Bashのmanページには、-c
オプションに関して次のように書かれています。
-c string
-c
オプションが存在する場合、コマンドはstring
から読み取られます。文字列の後に引数がある場合、それらは$0
で始まる位置パラメータに割り当てられます。
したがって、その説明があれば、このようなものが機能するはずだと思います。
bash -c "echo arg 0: $0, arg 1: $1" arg1
ただし、出力には次のように表示されるため、-c
文字列の後の引数が位置パラメータに割り当てられていないように見えます。
arg 0: -bash, arg 1:
私はかなり古いBashを実行しています(Fedora 4で):
[root @ dd42 trunk] #bash --version GNU bash、バージョン3.00.16(1)-リリース(i386-redhat-linux-gnu)Copyright(C)2004 Free Software Foundation、株式会社.
私は実際に、引数を使用してシェルスクリプトを少し実行しようとしています。 -c
は非常に有望に見えると思ったので、上記の問題が発生しました。 evalを使用することを考えましたが、evalに続くものに引数を渡すことはできないと思います。私は他の提案も受け入れています。
呼び出し元のシェルで補間が発生しないようにするには、一重引用符を使用する必要があります。
$ bash -c 'echo arg 0: $0, arg 1: $1' arg1 arg2
arg 0: arg1, arg 1: arg2
または、二重引用符で囲まれた文字列内の変数をエスケープします。どちらを使用するかは、コードスニペットに何を入れたいかによって異なります。
文字列内の「$0
」と「$1
」は、それぞれ変数#0と#1に置き換えられるためです。
試してみてください:
bash -c "echo arg 0: \$0, arg 1: \$1" arg0 arg1
このコードでは、両方の$
がエスケープされているため、ベースはそれを文字列$
と見なし、置き換えられません。
このコマンドの結果は次のとおりです。
arg 0: arg0, arg 1: arg1
お役に立てれば。
$0
(つまり、\$0
)に円記号を追加します。そうしないと、現在のシェルは、サブシェルに到達する前に、シェルの名前に$0
をエスケープします。
martinは補間について正しいです:一重引用符を使用する必要があります。ただし、実行中のコマンドに引数を渡そうとしている場合は、文字列within文字列で、明示的に転送する必要があることに注意してください。たとえば、スクリプトがある場合foo.sh次のようになります:
#!/bin/bash
echo 0:$0
echo 1:$1
echo 2:$2
次に、次のように呼び出す必要があります:
$ bash -c './foo.sh ${1+"$@"}' foo "bar baz"
0:./foo.sh
1:bar baz
2:
またはより一般的にはbash -c '${0} ${1+"$@"}' <command> [argument]...
$ bash -c ./foo.sh foo "bar baz"
0:./foo.sh
1:
2:
$ bash -c './foo.sh $@' foo "bar baz"
0:./foo.sh
1:bar
2:baz
つまり、サブプロセスをコマンド文字列に埋め込んだり、エスケープしたりすることなく、引数をサブプロセスに渡すことができます。