たとえば、これは機能しますが、
$ echo foo foo
これはしません:
$/bin/sh -c echo foo
これは次のとおりです。
$/bin/sh -c 'echo foo;エコーバー ' foo バー
説明はありますか?
man sh
から
-c string If the -c option is present, then commands are read from string.
If there are arguments after the string, they are assigned to the
positional parameters, starting with $0
つまり、コマンドは次のようになります。
$ sh -c 'echo "$0"' foo
foo
同様に:
$ sh -c 'echo "$0 $1"' foo bar
foo bar
それが最初に理解した部分でした。 2番目のケースは単純で、説明は不要だと思います。
$ echo foo
foo
これは、引数fooでecho
を呼び出し、fooが出力されます。
$ /bin/sh -c echo foo
これは、引数echo
を使用してシェルを呼び出し、引数$0
としてfooを提供します。 echo
は新しい行を出力し、fooを破棄します。 fooを出力する場合は、引数を引用符で囲みます。
sh -c 'echo foo'
または、提供された引数を使用します。
sh -c 'echo $0' foo
この例では
$ /bin/sh -c 'echo foo; echo bar'
foo
bar
シェルは、出力echo foo; echo bar
を引数として呼び出されます。
foo
bar
このコマンドでは:
echo foo
echo
はバイナリ(または組み込みコマンド)で、foo
は最初の引数です。
ここに:
/bin/sh -c echo foo
/bin/sh
はバイナリで、最初の引数は-c
で、それ自体が「コマンド文字列」をパラメーターとして受け入れます。これは上記の例ではecho
です。次に、3番目の引数があります。foo
ではなく/bin/sh
の引数であるecho
です。これが、3番目の例での理由です。
/bin/sh -c 'echo foo; echo bar'
...両方とも印刷されます。あなたは議論を引用した。したがって、最初の引数は-c
であり、この引数のパラメーターは'echo foo; echo bar'
であり、全体が1つの引数として解釈されます。 「コマンド文字列」として。
構造 sh -c Word
は、Wordのみを実行します(シェル内)。
追加された単語は、引数0、1、2などの他のことを意味します。
sh -c Word zero one two three
1つの単語としてスペースを持つコマンドを保持するには、引用符が必要です。
sh -c 'echo fnord' zero one two three
したがって、これはすべての引数を出力します。
$ sh -c 'echo "args=" "$0" "$@"' zero one two three
args = zero one two three
あなたが提示する例では:/bin/sh -c echo foo
最初のWord(オプションの後)はecho
です。つまり、これが実行されます。そして、テキストのないエコーは改行だけを印刷し、他には何も印刷しません:
$/bin/sh -c echo foo
そのため、空の行が表示されます。
スペースを引用すると、次のように「1つの単語」(スペースなし)が実行されます。
$/bin/sh -c echo\foo foo $/bin/sh -c "echo foo" foo $/bin/sh -c 'echo foo' foo
実行されたコマンドは、引用を使用して1つの「Word」として保持します。