Linuxの/dev/null 2>&1 とリダイレクトの意味|標準出力・標準エラーを捨てる仕組みを徹底解説

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, シェルスクリプト > Linuxの/dev/null 2>&1 とリダイレクトの意味|標準出力・標準エラーを捨てる仕組みを徹底解説
「cronで実行したコマンドが何も出力されない」「シェルスクリプトのエラーが画面に出てほしくない」
こんな場面でよく登場するのが /dev/null 2>&1 という記述です。
コピペで使えてはいるけれど、「なぜこう書くのか」「順番を変えたら何が起きるか」を説明できる人は意外と少ない。

この記事では、/dev/null 2>&1 の仕組み を、ファイルディスクリプタ(FD番号)と評価順序から丁寧に解説します。
cron やシェルスクリプトでの実用例、混同しやすい &>2>/dev/null との違いも合わせてカバーします。

なお、リダイレクト全般( > >> < 2> など)の基本については Linux 基本コマンドの解説 も参照してください。

この記事のポイント

・/dev/null は入力を全て捨てる「ブラックホール」デバイスファイル
・2>&1 は「標準エラー(FD2)を標準出力(FD1)の向き先へ合流させる」という意味
・> /dev/null 2>&1 と 2>&1 > /dev/null は評価順が違い結果が異なる
・cron では出力を全捨てするか、エラーだけ残すかを明示的に書くのがベスト


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

/dev/null とは何か

/dev/null は Linux が標準で用意している特殊なデバイスファイルです。
書き込んだデータを全て破棄し、読み込もうとしても即座に EOF を返します。
Windowsに例えると「ごみ箱に直接投げ込んで即削除する」イメージですが、ファイルを一切作らず、ディスクも消費しません。

# /dev/null の正体を確認する $ ls -la /dev/null crw-rw-rw- 1 root root 1, 3 Jun 14 00:00 /dev/null # c = キャラクタデバイス, 1,3 = major:minor番号

c はキャラクタデバイスを意味します。
試しに大量のデータを書き込んでも、ディスク使用量は変わりません。

$ echo "消えろ" > /dev/null $ cat /dev/null # 何も返ってこない(即 EOF) $

実際の現場では「不要な出力を画面やログに出したくないが、コマンド自体は実行したい」という場面で使います。

標準出力・標準エラー・ファイルディスクリプタ番号

Linux のプロセスは起動時に 3 つの標準ストリームを持ちます。
名前 FD番号 役割
標準入力(stdin) 0 コマンドへの入力元(デフォルト: キーボード)
標準出力(stdout) 1 正常な出力先(デフォルト: 端末画面)
標準エラー出力(stderr) 2 エラーメッセージの出力先(デフォルト: 端末画面)
FD番号は ls -l /proc/$$/fd/ で確認できます。

# 現在のシェルのファイルディスクリプタを確認 $ ls -l /proc/$$/fd/ lrwx------ 1 ec2-user ec2-user 64 Jun 14 10:00 0 -> /dev/pts/0 lrwx------ 1 ec2-user ec2-user 64 Jun 14 10:00 1 -> /dev/pts/0 lrwx------ 1 ec2-user ec2-user 64 Jun 14 10:00 2 -> /dev/pts/0 # 0,1,2 が全て端末(/dev/pts/0)を指している

リダイレクトとは、この FD が指す先を変更する操作です。

「>」と「>>」の違い

1. 上書きリダイレクト「>」

> は、FD1(標準出力)の指す先を指定のファイルに変えます。
ファイルが存在する場合は上書き(既存内容を削除してから書き込み)します。

# uptime の出力をファイルに保存(上書き) $ uptime > /tmp/uptime.log $ cat /tmp/uptime.log 10:05:32 up 3 days, 1:22, 1 user, load average: 0.01, 0.04, 0.05

2. 追記リダイレクト「>>」

>> はファイルが存在する場合に末尾へ追記します。
ログを蓄積したい場合はこちらを使います。

# 実行のたびに追記 $ uptime >> /tmp/uptime.log $ uptime >> /tmp/uptime.log $ cat /tmp/uptime.log 10:05:32 up 3 days, 1:22, 1 user, load average: 0.01, 0.04, 0.05 10:06:01 up 3 days, 1:22, 1 user, load average: 0.00, 0.04, 0.05 10:06:30 up 3 days, 1:22, 1 user, load average: 0.00, 0.04, 0.05

3. エラー出力のリダイレクト「2>」

2> は FD2(標準エラー)の指す先を変えます。

# 存在しないファイルを cat する(エラーが FD2 に出る) $ cat /no/such/file 2> /tmp/err.log $ cat /tmp/err.log cat: /no/such/file: No such file or directory

「2>&1」の意味と評価順序の罠

ここが最も重要なポイントです。

1. 「2>&1」が意味すること

2>&1 は「FD2(標準エラー)をFD1(標準出力)が現在指している先へ合流させよ」という指示です。
&1 は「FD1 が指しているファイルへの参照」を意味します。

# 正常出力もエラーも同じファイルに集める $ command > /tmp/output.log 2>&1 # 評価の順序(左から右): # 1. FD1 を /tmp/output.log へ向ける # 2. FD2 を「FD1 が今指している先(/tmp/output.log)」へ向ける # → FD1 も FD2 も /tmp/output.log を指す

2. 順番を逆にすると結果が変わる【重要】

# NG: 2>&1 を先に書いた場合 $ command 2>&1 > /tmp/output.log # 評価の順序(左から右): # 1. 2>&1 → FD2 を「FD1 が今指している先(端末)」へ向ける # 2. FD1 を /tmp/output.log へ向ける # → FD1 のみ /tmp/output.log へ # → FD2 は依然として端末を指したまま!エラーは画面に出る

実際に動作の違いを確認してみましょう。

# 正しい順番(エラーもファイルへ) $ ls /exist_dir /no_dir > /tmp/out.log 2>&1 $ cat /tmp/out.log ls: cannot access '/no_dir': No such file or directory /exist_dir: some_file.txt # 逆順(エラーは画面、正常出力だけファイルへ) $ ls /exist_dir /no_dir 2>&1 > /tmp/out.log ls: cannot access '/no_dir': No such file or directory ← 端末に出てしまう $ cat /tmp/out.log /exist_dir: some_file.txt

「左から右へ順番に評価される」というルールをしっかり覚えておきましょう。

3. /dev/null へ全て捨てる

正常出力もエラーも全て破棄したい場合、最もよく使うのがこの書き方です。

# 全ての出力を捨てる $ command > /dev/null 2>&1 # 評価の流れ: # 1. FD1 を /dev/null へ向ける # 2. FD2 を「FD1 が今指している先(/dev/null)」へ向ける # → FD1 も FD2 も /dev/null へ → 画面にも記録にも何も残らない

cron・シェルスクリプトでの実用例

1. cron の基本パターン

cron は実行結果をメールで送ろうとします(MAILTO が設定されていれば)。
出力を全て捨てることで、不要なメール通知を抑制できます。

# /etc/cron.d/myjob または crontab -e で記述 # 出力を全て捨てる(エラーも含む) 0 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1 # ログに正常出力のみ残す(エラーも同じファイルへ) 0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

注意: cron の環境変数は対話シェルと異なります。
スクリプト内でフルパスを使うか、crontab 冒頭で PATH を定義してください。

# PATH を明示する crontab の書き方 PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 0 2 * * * backup.sh >> /var/log/backup.log 2>&1

詳しいcronの書き方については、Linux ポート確認の全コマンド ではなく、cronログ確認の観点からは ntpd 時刻同期設定 のサンプルも参考になります。

2. シェルスクリプトでのエラー制御

#!/bin/bash # 実行日時をログに記録し、エラーは別ファイルへ LOG=/var/log/myjob.log ERR=/var/log/myjob_err.log echo "[$(date '+%Y-%m-%d %H:%M:%S')] 開始" >> $LOG # 正常出力はログへ、エラーは別ファイルへ分離 /usr/local/bin/process_data.sh >> $LOG 2>> $ERR if [ $? -ne 0 ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] エラーあり→ $ERR を確認" >> $LOG fi echo "[$(date '+%Y-%m-%d %H:%M:%S')] 終了" >> $LOG

3. find コマンドでよく使うパターン

find で権限のないディレクトリを検索するとエラーが大量に出ます。
エラーだけ捨てて、正常な検索結果だけ得たい場合に 2>/dev/null が役立ちます。

# エラーだけ捨てて、ファイル検索結果は画面へ $ find / -name "*.conf" 2>/dev/null # エラーを捨てて、結果はファイルへ $ find / -name "*.conf" > /tmp/conflist.txt 2>/dev/null

「&>」と「2>/dev/null」との違い

1. &>(bash 4以降の短縮記法)

&>> /dev/null 2>&1 を一つにまとめた bash の拡張記法です。

# この2つは等価 $ command > /dev/null 2>&1 $ command &> /dev/null # 追記版 $ command >> /var/log/out.log 2>&1 $ command &>> /var/log/out.log

ただし &> は bash 固有の記法です。
/bin/sh や POSIX sh スクリプト(#!/bin/sh)では動作しない場合があります。
移植性を重視するスクリプトでは > /dev/null 2>&1 を使いましょう。

2. 2>/dev/null(エラーだけを捨てる)

2>/dev/null は標準エラー(FD2)のみを捨て、標準出力(FD1)は端末やパイプに流します。

# エラーを捨てて正常出力だけパイプへ渡す $ find / -name "*.log" 2>/dev/null | grep -v archive | wc -l # エラーを捨てて正常出力だけ画面へ $ ls /exist /noexist 2>/dev/null /exist: some_file.txt

書き方 FD1(正常出力) FD2(エラー)
command > /dev/null 2>&1 捨てる 捨てる
command 2>/dev/null 画面・パイプへ 捨てる
command 1>/dev/null 捨てる 画面へ
command &> /dev/null 捨てる(bash拡張) 捨てる(bash拡張)

ログだけ残す書き方(実務ベストプラクティス)

「正常出力はログに残し、エラーも同じログへ残す」のが最も運用しやすい構成です。
エラーを捨ててしまうと、障害調査の手がかりが全て消えてしまいます。

1. 正常出力とエラーを同じログへ(追記)

# cronジョブの推奨パターン 0 3 * * * /usr/local/bin/cleanup.sh >> /var/log/cleanup.log 2>&1

2. 正常とエラーを別々のファイルへ残す

障害切り分けをしやすくしたい場合は、出力を分離します。

$ command >> /var/log/cmd_out.log 2>> /var/log/cmd_err.log

3. 古いログをローテーションさせる

>> /var/log/backup.log で書き続けるとファイルが肥大化します。
logrotate を設定してログを定期的に圧縮・削除しましょう。
設定例は tar.bz2 の解凍方法 と合わせて参考にしてください。

4. ジョブの終了コードを確認する

#!/bin/bash /usr/local/bin/myjob.sh >> /var/log/myjob.log 2>&1 EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then echo "[ERROR] myjob.sh が終了コード $EXIT_CODE で終了" >> /var/log/myjob.log fi

トラブルシュート|よくあるミスと対処法

「2>&1」を先に書いてしまってエラーが捨てられない

先述のとおり、command 2>&1 > /dev/null と書くとエラーは端末に出ます。
必ず command > /dev/null 2>&1 の順番で書くことを徹底してください。

cron で出力が消えずにメールが届く

cron のメール通知は「出力があった場合に送信する」というルールです。
> /dev/null 2>&1 を付けても MAILTO="" を設定しないとメール設定次第では通知が来る場合があります。

# crontab の先頭に書くとメール通知を完全に抑制 MAILTO="" 0 2 * * * /usr/local/bin/backup.sh > /dev/null 2>&1

/dev/null を誤って削除してしまった場合

# root で再作成(削除してしまった場合) # mknod コマンドで再作成: c=キャラクタデバイス, 1=major, 3=minor # sudo mknod -m 666 /dev/null c 1 3 # または以下でも可(tmpfsマウント後に再生成される) # systemd 環境では reboot で自動復旧する

本記事のまとめ

やりたいこと コマンド
正常出力もエラーも全て捨てる command > /dev/null 2>&1
エラーだけ捨てて正常出力は画面へ command 2>/dev/null
正常出力だけ捨ててエラーは画面へ command 1>/dev/null
正常出力もエラーも同じログへ追記 command >> /var/log/out.log 2>&1
正常とエラーを別ファイルへ追記 command >> /var/log/out.log 2>> /var/log/err.log
全て捨てる(bash拡張・短縮形) command &> /dev/null
FD番号を確認する ls -l /proc/$$/fd/
/dev/null 2>&1 は「意味がわかって使う」と、ログ設計もデバッグもぐっと楽になります。
特に評価順序(左から右)だけは、一度手を動かして確認しておくと身に染みます。
cronジョブのログ管理については ntpd 時刻同期設定 で実際の crontab サンプルも確認できます。
また、SSHでのリモート操作を前提とした実践例については Linux ポート確認の全コマンド もあわせて参照してください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Linux無料マニュアルを受け取る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。