"/bin/["は正確にどのように機能しますか?

"/bin/["は正確にどのように機能しますか?

フォルダにプログラムが/binあるという事実に常に驚きます。[

if [ something ]これを行うときは、次のように呼びます。

[シェルでプログラムを明示的に呼び出すと、適切なプログラムを要求して閉じ]括弧を指定すると、括弧の間に何を挿入しても何もしません。

言うまでもなく、プログラムの助けを借りる一般的な方法は機能しません。つまり、仕事でもman [仕事でもありません[ --help

答え1

この[コマンドの目的は、テスト式を評価することです。 0終了状態で返されます(つまり、本物)式がtrueと他の値として解釈されるとき(これは間違った)そうでなければ。

何もしないわけではありませんが、終了状態で結果を見つけることができます。シェルでは、$?Bourne シェルや他のほとんどのシェル (fish/rc/es/csh/tcsh...) と同様に、最後のコマンド$statusの終了ステータスを見つけることができます。

$ [ a = a ]
$ echo "$?"
0
$ [ a = b ]
$ echo "$?"
1

たとえば、他の言語では、perl終了ステータスは次の戻り値として返されますsystem()

$ perl -le 'print system("[", "a", "=", "a", "]")'
0

すべての最新のBourne様シェル(およびfish)には組み込み[コマンドがあります。通常、ここに含まれるコマンドは、他のシェルを使用する場合、または上記のコマンドと同じ操作を実行した場合にのみ実行されます/binenv [ foo = bar ]find . -exec [ -f {} ] \; -printperl

順序[は名前としても知られていますtest。 asが呼び出されたら、引数をtest終了する必要はありません。]

あなたのシステムにマニュアルページがないかもしれませんが、[おそらくそうです。しかし、もう一度申し上げますが、文書化または実装されますtest。シェルに組み込まれている機能については、シェルのドキュメントをお読みください。/bin/[/bin/test[

このユーティリティの履歴と[[...]]kshテスト式との違いの詳細については、以下を参照してください。その他の質問と回答についてはこちらをご覧ください

答え2

フォルダにプログラムが/binあるという事実に常に驚きます。[

あなたが驚いたのは正しいです。これは:、コマンドファイル(移植可能なファイル名の文字セット)に許可されている文字規則に従わないヌルユーティリティ()を持つまれなPOSIXコマンドの1つです。

if [ something ]これを行うときは、次のように呼びます。

正確ですがなくても使用できますif

[シェルでプログラムを明示的に呼び出すと、適切なプログラムを要求して閉じ]括弧を指定すると、括弧の間に何を挿入しても何もしません。

if目に見えるものは何もしませんが、実際にはContentで使用するとtestコマンドと同じように動作します。唯一の違いは、エンディングを見つけることです]。バラよりman testもっと学ぶ。

言うまでもなく、プログラムの助けを借りる一般的な方法は機能しません。つまり、仕事でもman [仕事でもありません[ --help

これはオペレーティングシステムによって異なります。man [複数の主流のGnu / Linuxディストリビューションでは確実に機能しますが、Solarisでは機能しません。

[ --help実装に応じて動作する場合と動作しない場合があります。とにかく構文が壊れて終わりが欠けているからです]。また、test/[コマンドのPOSIX標準--終了オプションを含むすべてのオプションを明示的に除外するので、両方を返し、設計上沈黙する必要があり[ --help ]ます。括弧の中や後ろの内容やオプションのように見えるもの(例えば、など)はそうではありません。test --helptrue[-f file-n stringオプションしかし、オペランド

すべての最新のBourneスタイルのシェルインタプリタ(例えば、、、bashなどksh)は内部的に/ utilsを組み込みに実装しているので、それを使用するときに参照する正しいマニュアルページはおそらくシェルのマニュアルページではなくシェルのマニュアルページです。。dashzshtest[test

Unix System III(1981)以前は、Bourneシェルはこのtestユーティリティを組み込みプログラムとして実装していなかったため、外部バイナリコマンドでのみ実装できました。 Unix System IIIより前には[コマンド(内部または組み込み)がありませんでした。たとえば、Unixバージョン7では次のように入力する必要がありました。

if test something ; then

変える:

if [ something ] ; then

答え3

[実際、より一般的なのはtestコマンドです。このコマンドの一般的な用途は、単に式を評価し、その条件(真または偽)を返すことです。以下のように、ステートメントの外部でシェルまたは演算子を介して他のコマンドを条件付きで実行するif-then-else-fiためにステートメントの外部で使用することもできますが、ステートメント内でよく使用されます。if&&||

$ [ -e /etc/passwd  ] && echo "File exists"
File exists

$ test -e /etc/passwd && echo "File exists"
File exists

より具体的には、評価は終了ステータスを介して他のコマンドに渡されます。一部のプログラムは、プログラムが正常に完了したか、実行中に特定のタイプのエラーが発生したか、構文エラーなど、さまざまなタイプのイベントを示すために終了ステータスを出力することを選択できます。コマンドの場合はtrueまたはfalseを意味する場合testがあります。 Stephanが指摘したように、構文エラーが発生します。012

その場所はシステムによって異なり、マニュアルページを見たときに表示されない理由を説明しますman [。たとえば、FreeBSDではです/bin。 Linux(または特定の場合はUbuntu 16.04)ではです/usr/bin/。 Linuxシステムでこれを行うと、man [同じ文書が開いていることがわかります。man testまた、シェルに独自のtest

また、このコマンドでは質問, ここで Korn シェル (通常「条件式」二重括弧[[ "$USER" = "root" ]]()を持つ参照は解像度を探します。この機能は、bashなどの他のシェルでも使用されますzsh

答え4

[引数に含まれる式がtrueと見なされると、コマンドは終了ステータス0を返し、引数に含まれる式がfalseと見なされるとコマンドはゼロ以外の終了ステータスを返します。最後のパラメータがそうでない場合でも、エラーメッセージで失敗します](純粋に審美的な理由による)。

たとえば、

[ hello ]
echo "Exit-status of [ hello ] is:" $?
[ abc = abc ]
echo "Exit-status of [ abc = abc ] is:" $?
[ ]
echo "Exit-status of [ ] is:" $?
[ abc = def ]
echo "Exit-status of [ abc = def ] is:" $?

...出力されます:

[hello]の終了ステータスは0です。      - 空でない文字列は真と見なされるためです。
[ abc = abc ] の終了状態: 0  - 'abc'は実際には'abc'と同じです。
[]の終了状態は1です。            - 空の文字列は偽と見なされるためです。
[ abc = def ] の終了状態は 1 です。  - 「abc」は実際には「def」とは異なるためです。

しかし、強く打つこの場合、他の多くのシェルは通常/bin/[(または/usr/bin/[)を呼び出すのではなく、(純粋にパフォーマンス上の理由で)まったく同じ動作で組み込みコマンドを呼び出します。/bin/[シェル組み込みプロキシではなくプロキシを呼び出すには、パスを明示的に指定するか(例:dirnameの前に☺プレフィックスを付ける/bin/[ hello ]必要はありません])、組み込みプロキシを使用しないようにシェルを設定する必要があります(たとえば、enable -n [bashなど)。

PS:他の答えで言ったよう[test。とは異なり、test最後のパラメータとしては[必要ではなく、まったく必要ありません。パラメータ。同じファイルに解析することできます(たとえば、]]test/bin/test/bin/[シンボリックリンク;この場合、行動伝達は以下を介して行うことができます。現在呼び出されているコマンドを分析します。test/コード自体内[)または他のファイル。シェルの場合、パスが明示的に指定されているか()そうでないように設定されていない限り、()testシェルは通常組み込みプロキシも呼び出します。/bin/testenable -n test

PPS:testとは異なり、[現代はif実際には文書ではありませんでした。これはシェル構文の一部です(例:bash):(if commandA; then commandB; fiセミコロンの代わりに改行を使用できます)、ステータスが0の状態で終了したcommandB場合にのみ実行されます。commandAこれはtest、またはの動作と完全に一致し、[それらを組み合わせることができますif [ "$a" = foo ]; then …; fi (またはif test "$a" = foo; then …; fi読み取りが読みやすくなりません)。しかし、最新のスクリプトでは[[実際にはファイルではありませんが、常にシェル構文の一部であるorを代わりに使用することがよくあります。test[if

PPPS:つまり、manファイルmanシステムのすべてのコマンドを扱う記事を期待しないでください。一部の(実際には、「ファイルベース」)コマンドに関する情報が欠落している可能性があり、一部のシェル組み込みコマンドに関する情報は特定のシェル専用文書にのみ表示されない場合があります(ここでtest、、、、)。それにもかかわらず、多くのディストリビューションには明示的な記事があります。 (明白な理由で認識されません。同様の状況を静かに処理する必要があります。一部のディストリビューションでは(閉じずに)まだヘルプが表示されますが、一部のディストリビューションではそうではありません。)[if[[mantest[--helptesta=--help; test "$a"[ --help]

関連情報