私はbashシェルスクリプトの例を読んでいます:
#!/bin/bash
# This script makes a backup of my home directory.
cd /home
# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1
# First remove the old bzip2 file. Redirect errors because this generates some if the archive
# does not exist. Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar
# Copy the file to another Host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1
# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log
ここで「/ dev/null 2>&1」の使い方を理解しようとしています。最初は、このスクリプトは/ dev/nullを使用して、スクリプトをクラッシュさせずにエラーを適切に無視することを考えていました(プログラミング言語で例外処理をキャッチするようなものです)。 tarを使用してディレクトリをtarファイルに圧縮する方法がわからないため、あらゆる種類のエラーが発生する可能性があります。
いいえ、これはスクリプトのクラッシュを防ぐことはできません。 tar
プロセスでエラーが発生した場合(例:権限が拒否された、そのようなファイルやディレクトリがないなど)、スクリプトは引き続きクラッシュします。
これは、> /dev/null 2>&1
を使用すると、すべてのコマンド出力(stdout
とstderr
の両方)が/dev/null
にリダイレクトされ、出力が端末に出力されないためです。
デフォルトでは:
stdin ==> fd 0
stdout ==> fd 1
stderr ==> fd 2
スクリプトでは、> /dev/null
を使用すると、次の原因になります。
stdin ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2
そして2>&1
が原因:
stdin ==> fd 0
stdout ==> /dev/null
stderr ==> stdout
ここで ">/dev/null 2>&1"の使用を理解しようとしています。
(質問の/dev/null
の前にリダイレクトを追加したことに注意してください。)
上記はSTDOUT
およびSTDERR
を/dev/null
にリダイレクトします。 STDERR
をSTDOUT
にマージすることで機能します。 (基本的に、コマンドからのすべてのoutputは null device にリダイレクトされます。)
...スクリプトをクラッシュさせることなく(プログラミング言語で例外処理をキャッチしようとするようなものです)。
try/catch
などとはまったく異なります。コマンドからのあらゆる種類の出力(エラーを含む)を単にsilencesします。
Tarを使用してディレクトリをtarファイルに圧縮する方法がわからないため、あらゆる種類のエラーが発生する可能性があります。
次のようないくつかの理由でエラーが発生する可能性があります。
CMD>/dev/null 2>&1を実行すると
STDOUTは/ dev/nullにリダイレクトし、次にSTDERRは/ dev/nullに設定されているSTDOUTのTHE ADDRESSにリダイレクトします。その結果、STDOUTとSTDERRの両方が/ dev/nullを指します。
反対に、CMD 2>&1>/dev/nullを実行すると
STDERRはSTDOUTのTHE ADDRESS(その瞬間のファイル記述子1、または/ proc/self/fd/1)にリダイレクトし、次にSTDOUTは/ dev/nullにリダイレクトしますが、STDERRはfd1にリダイレクトし続けます!!その結果、STDOUTからの通常の出力は破棄されますが、STDERRからのエラーはまだコンソールに書き込まれています。
簡単に理解できるように、明示的に記述してください。以下は、存在しないファイルを削除しようとするコマンドの例です。
rm nonexisting.txt 1>/dev/null 2>/dev/null
以下は、いくつかの拡張機能です(デフォルトとポインターを使用して、すべてのユーザーを混乱させます)。
拡張1: "1>"を ">"に置き換えることができます( "1"がデフォルトのstdoutであるため)
rm nonexisting.txt >/dev/null 2>/dev/null
機能拡張2:2番目の「/ dev/null」を&1に置き換えることができます(2番目の/ dev/nullは&1と呼ばれます。これは、/ dev/nullが「stdout 1によってすでにポイントされているため」)
rm nonexisting.txt 1> /dev/null 2> &1