web-dev-qa-db-ja.com

echoが/ bin / sh -c echo fooの出力として何も出力しないのはなぜですか?

たとえば、これは機能しますが、

 $ echo foo 
 foo 

これはしません:

 $/bin/sh -c echo foo 
 

これは次のとおりです。

 $/bin/sh -c 'echo foo;エコーバー '
 foo 
バー

説明はありますか?

15
SilverlightFox

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番目のケースは単純で、説明は不要だと思います。

21
Ijaz Ahmad Khan
$ echo foo
foo

これは、引数fooechoを呼び出し、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
18
Marco

このコマンドでは:

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つの引数として解釈されます。 「コマンド文字列」として。

8
chaos

構造 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」として保持します。

3
user79743