web-dev-qa-db-ja.com

「/ bin / [」はどのように機能しますか?

/binフォルダーに[プログラムがあることにいつも驚いています。

これは、if [ something ]のような場合に何と呼ばれますか?

シェルで[プログラムを明示的に呼び出すことにより、対応する]を要求し、閉じ括弧を指定すると、括弧の間に何を挿入しても何もしないようです。

言うまでもなく、プログラムに関するヘルプを取得する通常の方法は機能しません。つまり、man [[ --helpも機能しません。

51
Bregalad

_[_コマンドの仕事は、テスト式を評価することです。式がtrueと他の何かに解決されると、終了ステータス0(trueを意味します)で戻ります(つまり、false)それ以外の場合。

それは何もしないということではなく、その結果がその終了ステータスで見つかることだけです。シェルでは、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)には、組み込みの_[_コマンドがあることに注意してください。 _/bin_の1つは、通常、別のシェルを使用する場合、または_env [ foo = bar ]_や_find . -exec [ -f {} ] \; -print_などのこと、または上記のPerlコマンドを実行する場合にのみ実行されます...

_[_コマンドはtest名でも知られています。 testとして呼び出された場合、_]_引数を閉じる必要はありません。

お使いのシステムには_[_のmanページがないかもしれませんが、おそらくtestのmanページがあります。ただし、ここでも_/bin/[_または_/bin/test_の実装について説明していることに注意してください。シェルに組み込まれている_[_について知るには、代わりにシェルのドキュメントを読む必要があります。

そのユーティリティの履歴と_[[...]]_ kshテスト式との違いの詳細については、この その他のQ&Aはこちら を参照してください。

64

/binフォルダーに[プログラムがあることにいつも驚いています。

あなたは驚かれることは正しいです。これは、nullユーティリティ(:)を備えた、まれなPOSIXコマンドの1つであり、コマンドファイルで許可されている文字規則(ポータブルファイル名の文字セット)を考慮していません。

if [ something ]のようなことをしているときに何が呼び出されるのですか?

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

シェルで[プログラムを明示的に呼び出すことにより、対応する]を要求し、閉じ括弧を指定すると、括弧の間に何を挿入しても何もしないようです。

何も表示されませんが、実際にはifを使用した場合と同じです。つまり、括弧内に何を置くかに応じて、終了ステータスを0(true)またはその他(false)に設定します。 (理由により)testコマンドと同じ動作です。唯一の違いは、末尾の]を探すことです。詳細は man test を参照してください。

言うまでもなく、プログラムに関するヘルプを取得する通常の方法は機能しません。つまり、man [[ --helpも機能しません。

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

[ --helpは、実装に依存して機能する場合と機能しない場合があります。いずれにせよ、構文が壊れており、末尾の]が欠落しているためです。さらに、 test/[コマンドのPOSIX標準 は、--オプションの終了を含むすべてのオプションを明示的に除外するため、[ --help ]test --helpの両方がtrueを返し、設計によりサイレント。大括弧の内側または[の後に置き、オプションのように見えるもの(例えば、-f file-n stringなど)はoptionsではなくオペランド

現代のすべてのボーンスタイルシェルインタープリター(bashkshdashzshなど)は、test/[を実装していますユーティリティを組み込みとして内部的に使用するため、それらを使用する場合、参照する正しいマニュアルページはtestではなく、シェルのページである可能性があります。

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

if test something ; then
…

の代わりに:

if [ something ] ; then
…
41
jlliagre

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

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

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

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

その場所はシステムによって異なり、man [を実行したときにmanページが表示されなかった理由も説明します。たとえば、FreeBSDでは/binの下にあります。 Linux(または私の特定のケースでは、Ubuntu 16.04)では/usr/bin/にあります。 Linuxシステムでman [またはman testを実行すると、同じドキュメントが表示されます。シェルがtestを独自に実装している場合があることに注意することも重要です。

また、このコマンドには issues があり、Korn Shellの実装(一般に "条件式" 二重角かっこを使用した参照、[[ "$USER" = "root" ]])が求めます。解決する。この機能は、bashzshなどの他のシェルでも使用されます。

10

_man [_も_[ --help_も機能しない

一部のディストリビューション(Ubuntuなど)では、_man [_はtest(1)へのシンボリックリンクをたどります。他(アーチなど)では、これは当てはまりません。 (ただし、testのマニュアルページには、_[_の使用法も記載されています)


_type -a [_は、組み込みのシェルと実行可能ファイルの両方があることを示しています。

_$ type -a [
[ is a Shell builtin
[ is /usr/bin/[
_

bash-builtin _[ --help_はエラーメッセージを出力します。 (ただし、組み込みなので、_help [_を使用するか、bashのマニュアルページ/ドキュメントを参照してください)。

_/usr/bin/[ --help_は、完全なヘルプ出力を出力します(GNU Coreutilsバージョンの場合)。

_$ /usr/bin/[ --help
Usage: test EXPRESSION
  or:  test
  or:  [ EXPRESSION ]
  or:  [ ]
  or:  [ OPTION
Exit with the status determined by EXPRESSION.

      --help     display this help and exit
      --version  output version information and exit
_

次に、EXPRESSIONで使用できる構文について説明します。

これは、_[_とtestが同等であることがわかるもう1つの方法です。


ところで、bashをプログラミングしている場合(または1ライナーを対話形式で記述している場合)、_[[_ではなく_[_をお勧めします。いくつかの点で優れています。Sergの回答のリンクを参照してください。

3
Peter Cordes

[コマンドは、引数に含まれる式が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—空でない文字列はtrueと見なされるため
終了ステータスof [abc = abc] is:0— 'abc'は実際には 'abc'
と同じであるため、[]の終了ステータスis:1—空の文字列はfalseと見なされるため
 [abc = def]の終了ステータスは:1—「abc」は「def」と実際には異なるため

ただし、 bash および他の多くのシェルは通常、これらの場合に/bin/[(または/usr/bin/[)を呼び出さず、代わりにまったく同じ動作で組み込みコマンドを呼び出します(純粋にパフォーマンス上の理由から)。 /bin/[(Shellビルトインサロゲートではない)を呼び出すには、パスを明示的に指定する必要があります(例:/bin/[ hello ];ただし、]の前にdirnameを付ける必要はありません。☺)、またはビルトインサロゲートを使用しないようにシェルを構成します(たとえば、bashのenable -n [)。

P. S .:他の回答でも述べたように、[testに関連しています。ただし、[とは異なり、testは、最後の引数として]を必要としません。 (それをまったく期待していません。]test引数に追加すると、エラーメッセージで失敗したり、間違った結果が返されたりする可能性があります)。 /bin/test/bin/[は同じファイルに解決できます(例: symlinked ;この場合、動作転換はおそらく 現在呼び出されているコマンドtest/[コード自体)または別のファイル内。 testの場合、パスが明示的に指定されていないか(/bin/test)、またはパスが明示的に指定されていない(enable -n test)場合を除き、Shellは通常、組み込みサロゲートも呼び出します。

P. P. S .: test[とは異なり、最新のifは実際のファイルにはなりません。これはシェル(bashなど)構文の一部です:if commandA; then commandB; fi(セミコロンの代わりに改行を使用できます)は、commandBが実行されますif_and-only-if commandA exited with zero status。これはtestまたは[の動作に完全に適合し、if [ "$a" = foo ]; then …; fiのように組み合わせることができます。 (またはif test "$a" = foo; then …; fi —読みにくい)。ただし、最近のスクリプトでは、testまたは[[の代わりに[を使用することがよくあります(ifとして)。これは実際のファイルではなく、常にシェル構文の一部です。

P. P. P. S .: manと同様— manがファイルシステム内のすべてのコマンドに関する記事を持つことを決して期待しないでください。一部の(「実際の」ファイルベースの)コマンドでも情報が欠落している可能性があります。一部のShellビルトインに関する情報は、特定のShell専用の記事内にあるだけではありません(これは、testに関する情報を最も確実に見つける場所です) [if[[)。それでも、多くのディストリビューションには、man[の明示的なtest- articlesがあります。 (--helpについては、明らかな理由によりtestでは認識されません。a=--help; test "$a"のような静かなケースを処理する必要があります。一部のディストリビューションでは[ --help]を閉じずに)でもヘルプが表示されます、そうでないものもあります。)

2
sasha