'bash -c'に引数を追加します


22

次のように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

動作していないように見えます(無視されているようです)。私は何か間違ったことをしているのですか、それともmanページを間違って解釈していますか?

男性からの関連する引用:

-cオプションが存在する場合、コマンドはstringから読み取られます。文字列の後に引数がある場合、$ 0から始まる位置パラメータに割り当てられます。

そして

A-オプションの終了を通知し、さらにオプション処理を無効にします。-の後の引数は、ファイル名と引数として扱われます。

回答:


33

あなたはマニュアルページを間違って解釈しています。まず、--オプションの終了を知らせる部分は、あなたがやろうとしていることとは無関係です。これ-cにより、コマンドラインの残りの部分が上書きされ、bashのオプション処理がまったく行われなくなります。つまり、--bashでオプションマーカーとして処理されるのではなく、コマンドに渡されます。

2番目の間違いは、コマンドに引数として渡されるのではなく、起動されたシェルプロセスの位置パラメーターとして追加の引数が割り当てられることです。だから、あなたがやろうとしていることは、次のいずれかとして行うことができます:

/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar

最初の場合、パラメータを渡す$0$1明示的にエコーし、2番目の場合、"$@"「$ 0を除くすべての位置パラメータ」のように通常どおりに展開するために使用します。その場合、使用するものも渡す必要があることに注意してください$0。私は「bash」を選択しました$0が、それは通常はそうだからですが、他のものは何でも動作します。

その理由のためとして、だけでなく、あなたがリストコマンドに直接与える任意の引数を渡すのでは、この方法を行うの:ドキュメントは、「コマンドと言う。なお、sは複数の文字列から読み込まれます」。つまり、このスキームを使用すると、次のことができます。

/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file

ただし、元の目標を達成するためのより良い方法envは、以下を使用することですbash

/usr/bin/env -- "ls" "-l"

シェルが提供する機能を必要としない場合、それを使用する理由はありません。envこの場合の使用は、より速く、より簡単に、より少ないタイピングになります。また、シェルメタ文字または空白を含むファイル名を安全に処理できることを確認するのは難しいと考える必要はありません。


3

あなたの目的が何なのかはわかりませんが、単にRube Goldbergマシンを構築しようとしているのであれば、複雑なファッション」–してみてください

sh -c 'ls $0' -l

または

sh -c 'ls $1' supercalifragilisticexpialidocious -l

あるいは

sh -c 'ls -$0' l

これらがgodlygeekの答えからどのように機能するかを理解できるはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.