私は Linux の基本的なスキルしか持っていませんが、現在いくつかのシェル スクリプトを解析しようとしています。スクリプトの 1 つに次の行があります。
if [ -n "$(which voltdb 2> /dev/null)" ];
/dev/null はビット バケットであり、コマンド ラインで voltdb を実行した場合に実行されるパスを出力するものであることはわかっています。また、行全体が明らかに if ステートメントです。しかし、ここでは他の多くの点について混乱しています。
- なぜ 2 が /dev/null と比較されるのでしょうか? これらは互換性のないタイプのようです。
- スイッチ-nは何をしますか?rm -r filenameのようなスイッチを使うのに慣れていますが、-nはどのコマンドとも組み合わせられないようです。
- 括弧は何をするのでしょうか?この表現とは別の意味があるようですこのテスト式[]の意味は何ですか?
基本的に、この行は何をするものなのでしょうか? 私には、これには不明な点が多すぎます。つまり、外国語の文章を聞いていて、多くの単語を聞き逃して基本的な構造を理解できないのと少し似ています。
答え1
このコード断片では多くのことが行われています。内側から外側に向かって作業を進めます。
which voltdb 2> /dev/null
- ここで実行されるコマンドは ですwhich
。which
呼び出されると、PATH
は環境変数のすべてのエントリを検索して、「voltdb」という名前のコマンドを見つけます。 で指定されたディレクトリの 1 つに「voltdb」という名前の実行可能ファイルが見つかった場合PATH
、実行可能ファイルの完全修飾名が出力されますvoltdb
。
質問 1 にお答えすると、「2>」はリダイレクトの例です。すべての Unix/Linux/*BSD プロセスには 3 つの標準入力と出力があり、0 は stdin、1 は stdout、2 は stderr です。コマンド ラインで実行されるプログラムは、通常、エラー メッセージを stderr に出力します。したがって、「2> /dev/null」は 2 と「/dev/null」を数値的に比較しているのではなく、which
エラー出力を に送信しています。これは/dev/null
、入力をすべて受け入れて 0 バイトの出力を返す特別なファイルです。
それ以外の場合、この$(...)
構文は「囲まれたコマンドを実行し、'$(' と ')' の間の出力をここで字句的に置換する」ことを意味します。これが出力置換であり、シェル プログラムが行うものです。
出力置換の外側では、フラグメントは を実行します。if [ -n "something" ];
ここで、「something」はwhich
印刷されるはずのものです。「if」はシェルのフロー制御構造であり、「if」の後のコマンドのパイプラインが「成功」ステータスで終了すると、コード ブロックが実行されます。
は[
実際には実行可能ファイルであり、 までのコマンドライン引数を調べます]
。「-n」フラグは通常、「次の引数がゼロ以外の文字列長の場合に true」を意味します。これが、質問 #2 と #3 に対する答えです。この[ ... ]
構造は、いくつかの論理条件 (この場合は「ゼロ以外の文字列長」) に対して true (成功コードで終了) または false (失敗コードで終了) の回答を返します。
最終的に、そのフラグメントは、シェルの PATH に実行可能ファイルを含むディレクトリがある場合に、if-then-fi または if-then-else-fi 制御フローの「true」句を実行しますvoltdb
。
答え2
そのコードは次のことを行っています:
if [ -n "...." ];
二重引用符内で実行されたコードの結果が空の場合、if ステートメントは true になります。
二重引用符内のコード:
$(which voltdb 2> /dev/null)
コマンドを実行しwhich voltdb
、このコマンドから STDERR (標準エラー) に出力されるすべての出力を にリダイレクトします/dev/null
。基本的に、これには興味がないので無視します。
の結果は、which voltdb
文字列 voltdb に一致する PATH 上の実行可能ファイルへのパスを返します。
例
$ which time
/usr/bin/time
$ which time 2> /dev/null
/usr/bin/time
についてはどうですか2>
?
2>
は、出力をリダイレクトするための省略表記です。ストリームプログラムの実行時に自動的に設定されます。ストリームは次のとおりです。
- 0 - 標準入力(別名 STDIN)
- 1 - 標準出力(別名 STDOUT)
- 2 - 標準エラー(別名 STDERR)
したがって、STDERR の出力を取得して削除したい場合は、次のようにします。
$ which time 2> /dev/null
STDOUT からの出力を取得して STDERR にリダイレクトする場合: