xargs -Iが正しく機能するためにshに引数を渡す前に二重ダッシュが必要なのはなぜですか?

xargs -Iが正しく機能するためにshに引数を渡す前に二重ダッシュが必要なのはなぜですか?

問題の命令です

 find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename $1) ' -- file

したがって、二重ダッシュがないと転送されずfileshそのまま認識されます$1。なぜそんなことですか?これにより、--後続のパラメータがコマンドラインオプションとして認識されないことがわかります。しかし、file前にダッシュがないため、コマンドラインオプションとして認識する理由はないようです。

答え1

オプションではない最初のパラメータはにshなります$0shスクリプトから呼び出されると、これはスクリプトへのパスです。を実行すると、sh -c SOMECOMMANDシェルはパラメータを入れる以外にパラメータに対して何もしません$0。通常、-cwhere is the name or path of the script と同様に に渡されたスクリプトの名前ですsh /path/to/script$0

ほとんどのコマンドとは異なり、--特殊目的フラグではなく汎用パラメーターとして扱われます。したがって--、実際には$0次のパラメータの代わりに使用されます。

$ sh -c 'echo $1' hello            

$ sh -c 'echo $0' hello
hello
$ sh -c 'echo $0; echo $1' hello world
hello
world
$ sh -c 'echo $0; echo $1' -- hello
--
hello

xargsこれは、すべての引数をコマンドshに渡すこととは関係ありません。sh

答え2

上記の例では、と間のブレーカーとして--機能します。文字列を引数に強制します。sh -c 'echo $(basename $1) 'filefile$1sh

上記は以下のように単純化できます。

$ find . -name "*.txt" | xargs -Ifile sh -c 'echo $(basename file) '

関連情報