Bashで次のようにコマンドを実行したいとしましょう。
/bin/bash -c "ls -l"
Bashのマニュアルページによると、次のように実行することもできます。
# don't process arguments after this one
# | pass all unprocessed arguments to command
# | |
# V V
/bin/bash -c ls -- -l
しかし、うまくいかないようです(無視されるようです)。私が何か間違っているのか、それともマニュアルページを間違って解釈しているのでしょうか?
男性に関する関連引用:
-c オプションがある場合は、文字列からコマンドを読み込みます。文字列の後にパラメータがある場合は、$ 0から始まる位置パラメータに割り当てられます。
そして
A - オプションの終わりを示し、追加のオプション処理を無効にします。 - 以降のすべての引数はファイル名と引数として扱われます。
ベストアンサー1
マニュアルページの解釈が正しくありません。まず、オプションの終わりを示す部分は、やりたいこと--
には関係ありません。-c
その時点から、残りのコマンドラインは上書きされ、bashのオプション処理を経なくなりました。つまり、--
bashでオプションの終わりの表示として扱われるのではなく、コマンドに渡されるということです。
2番目のエラーは、追加の引数がコマンドに引数として渡されず、開始されたシェルプロセスに位置引数として割り当てられることです。したがって、実行したい操作は次のいずれかで行うことができます。
/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar
最初の場合は echo 引数が明示的に渡され$0
、$1
2 番目の場合は"$@"
「$0 を除くすべての位置引数」に一般拡張が使用されます。この場合、使用するものを渡す必要があることに注意してください$0
。私は「bash」を選びました。なぜならこれは$0
一般的ですが、他のものも可能だからです。
これを行う理由は、指定した引数をリストされたコマンドに直接渡すよりも次のようになります。文書に「コマンドS文字列から""(複数形)を読みます。つまり、このプログラムを使用すると、次のことができます。
/bin/bash -c 'mkdir -p -- "$1" && cd -P -- "$1" && touch -- "$2"' bash dir file
ただし、元の目標を達成するためのより良い方法は、次のものをenv
代わりに使用することですbash
。
/usr/bin/env -- "ls" "-l"
シェルが提供する機能が必要ない場合、使用する理由はありません。env
この場合、より速く、簡単で、入力が少なくなります。また、シェルメタ文字やスペースを含むファイル名を安全に処理できることを確認するために、あまりにも懸命に考える必要はありません。