Warum gibt das als / bin / sh -c echo foo bezeichnete Echo nichts aus?

15

Zum Beispiel, während dies funktioniert:

$ echo foo
foo

Das tut nicht:

$ / bin / sh -c echo foo

Während dies tut:

$ / bin / sh -c 'echo foo; Echo-Leiste
foo
Bar

Gibt es eine Erklärung?

SilverlightFox
quelle

Antworten:

21

Von 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

Dies bedeutet, dass Ihr Befehl folgendermaßen lauten sollte:

 $ sh -c 'echo "$0"' foo 
 foo

Ähnlich:

$ sh -c 'echo "$0 $1"' foo bar
foo bar

Das war der erste Teil, der verstanden hat; Der zweite Fall ist einfach und bedarf wohl keiner Erklärung.

Ijaz Ahmad Khan
quelle
2
Eine strengere, standardkonforme Methode wäresh -c 'echo $1' echo foo
jlliagre
1
sh -c 'echo "$@"' fnord a b c d ...
zwol
3
IMHO die Erklärung war ziemlich gut, aber sh -c 'echo $0' fooist nicht die beste Option, unter Berücksichtigung, dass der Fragesteller bereits weiß, dass /bin/sh -c 'echo foo; echo bar'funktioniert, können Sie einfach mit dem Befehl antworten/bin/sh -c 'echo foo'
X3MBoy
1
@ X3MBoy Der Fragesteller weiß bereits, dass / bin / sh -c 'echo foo' gut funktioniert. Er wollte etwas außerhalb dessen wiedergeben, was ich erklärte
Ijaz Ahmad Khan
18
$ echo foo
foo

Dieser ruft echomit dem Argument foo auf und foo wird gedruckt.

$ /bin/sh -c echo foo

Dies ruft die Shell mit dem Argument auf echound liefert foo als Argument $0. Das echogibt eine neue Zeile aus und Sie verwerfen das foo . Wenn Sie foo ausgeben möchten, geben Sie das Argument an:

sh -c 'echo foo'

oder verwenden Sie das angegebene Argument:

sh -c 'echo $0' foo

In diesem Beispiel

$ /bin/sh -c 'echo foo; echo bar'
foo
bar

Die Schale ist mit dem Argument aufgerufen , echo foo; echo barwelche Ausgänge

foo
bar
Marco
quelle
8

In diesem Befehl:

echo foo

echoist die Binärdatei (oder der eingebaute Befehl) und foodas erste Argument.

Hier:

/bin/sh -c echo foo

/bin/shist die Binärdatei, deren erstes Argument ist -c, die selbst einen "Befehlsstring" als Parameter akzeptiert. Dies ist echoim obigen Beispiel. Dann gibt es ein drittes Argument: Das fooist ein Argument für /bin/sh, nicht für echo. Deshalb in Ihrem dritten Beispiel:

/bin/sh -c 'echo foo; echo bar'

... beide sind gedruckt. Sie haben das Argument zitiert. Also: Das erste Argument ist -c, und der Parameter zu diesem Argument ist, 'echo foo; echo bar'der als ein einziges Argument interpretiert wird; als "Befehlszeichenfolge".

Chaos
quelle
3

Die Struktur sh -c wordführt nur ein Wort (in einer Shell) aus.
Hinzugefügte Wörter bedeuten andere Dinge, wie Argument Null, Eins, Zwei usw .:

sh -c word zero one two three

Um einen Befehl beizubehalten, der Leerzeichen als ein Wort enthält, muss Folgendes angegeben werden:

sh -c 'echo fnord' zero one two three

Das gibt also alle Argumente aus:

$ sh -c 'echo "args=" "$0" "$@"' zero one two three
args = zero one two three

Beispiele

In dem Beispiel, das Sie präsentieren: /bin/sh -c echo fooDas erste Wort (nach Optionen) ist das echo, was ausgeführt wird. Und ein Echo ohne Text gibt nur eine neue Zeile aus, sonst nichts:

$ / bin / sh -c echo foo

Aus diesem Grund erhalten Sie eine leere Zeile.

Wenn Sie das Leerzeichen zitieren, führen Sie "ein Wort" (keine Leerzeichen) aus:

$ / bin / sh -c echo \ foo
foo
$ / bin / sh -c "echo foo"
foo
$ / bin / sh -c 'echo foo'
foo

Fazit

Behalten Sie den ausgeführten Befehl in Anführungszeichen als ein "Wort".


quelle