通常、$0
スクリプトでは、スクリプトの名前、またはスクリプトが呼び出されたもの(パスを含む)に設定されます。ただし、bash
を使用すると -c
を使用 オプション、$0
コマンド文字列の後に渡される最初の引数に設定されます:
bash -c 'echo $0' foo bar
# foo
実際には、位置パラメータがシフトされているように見えますが、$0
が含まれています 。ただし、shift
コマンド文字列内の$0
には影響しません (通常どおり):
bash -c 'echo $0; shift; echo $0' foo bar
# foo
# foo
コマンド文字列のこの明らかに奇妙な動作がなぜですか?
このような奇妙な動作を実装する背後にある理由、理論的根拠を探していることに注意してください。
このようなコマンド文字列には$0
は必要ないと推測できます。 通常定義されているパラメータなので、経済性のために通常の引数にも使用されます。ただし、その場合、shift
の動作 奇妙です。もう1つの可能性は、$0
プログラムの動作を定義するために使用されます(bash
sh
と呼ばれます またはvim
vi
と呼ばれます )、しかし、$0
なので、そうすることはできません。 ここでは、コマンド文字列にのみ表示され、コマンド文字列内で呼び出されるプログラムには表示されません。 $0
の他の用途は考えられません 、それで私はこれを説明するのに途方に暮れています。
承認された回答:
これにより、$0
を設定/選択する機会が得られます インラインスクリプトを使用する場合。それ以外の場合、$0
bash
になります 。
次に、たとえば次のことができます:
$ echo foo > foo
$ bash -c 'wc -c < "${1?}"' getlength foo
4
$ rm -f bar
$ bash -c 'wc -c < "${1?}"' getlength bar
getlength: bar: No such file or directory
$ bash -c 'wc -c < "${1?}"' getlength
getlength: 1: parameter not set
すべてのシェルがそれを行うために使用されるわけではありません。ボーンシェルはそうしました。 Korn(およびAlmquist)シェルは、最初のパラメーターを$1
に移動することを選択しました 代わりは。 POSIXは最終的にボーンの道を進んだので、ksh
およびash
派生物は後でそれに戻りました(詳細についてはhttp://www.in-ulm.de/~mascheck/various/find/#shellを参照してください)。つまり、sh
は長い間 (システムに応じて、Bourne、Almquist、またはKornシェルに基づいていました)、最初の引数が$0
に入ったかどうかはわかりませんでした。 または$1
、したがって、移植性のために、次のようなことをしなければなりませんでした:
sh -c 'echo foo in "$1"' foo foo
または:
sh -c 'shift "$2"; echo txt files are "[email protected]"' tentative-arg0 3 2 *.txt
ありがたいことに、POSIXは、最初の引数が$0
に入る新しい動作を指定しました。 、これで移植可能になりました:
sh -c 'echo txt files are "[email protected]"' meaningful-arg0-for-error *.txt