Dlaczego echo nie jest wywoływane jako / bin / sh -c echo foo cokolwiek wypisuje?


15

Na przykład, podczas gdy to działa:

$ echo foo
bla

To nie:

$ / bin / sh -c echo foo

Podczas gdy to:

$ / bin / sh -c 'echo foo; pasek echa ”
bla
bar

Czy jest jakieś wytłumaczenie?

Odpowiedzi:


21

Od 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

Oznacza to, że twoje polecenie powinno wyglądać tak:

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

Podobnie:

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

To była pierwsza część do zrozumienia; drugi przypadek jest prosty i chyba nie wymaga wyjaśnienia.


2
Bardziej rygorystycznym, standardowym sposobem zgodnym byłobysh -c 'echo $1' echo foo
jlliagre

1
sh -c 'echo "$@"' fnord a b c d ...
zwolnienie

3
IMHO wyjaśnienie było całkiem dobre, ale sh -c 'echo $0' foonie jest najlepszą opcją, biorąc pod uwagę, że pytający już wie, że /bin/sh -c 'echo foo; echo bar'działa, możesz po prostu odpowiedzieć, cytując polecenie/bin/sh -c 'echo foo'
X3MBoy

1
@ X3MBoy Pytający już wie, że / bin / sh -c 'echo foo' działa dobrze. Chciał powtórzyć coś poza tym, co wyjaśniłem
Ijaz Ahmad Khan

18
$ echo foo
foo

Wywoływane jest to echoz argumentem foo i foo .

$ /bin/sh -c echo foo

To wywołuje powłokę z argumentem echoi dostarcza foo jako argument $0. echoWyprowadza nową linię i wyrzucić foo . Jeśli chcesz wypisać foo , zacytuj argument:

sh -c 'echo foo'

lub użyj podanego argumentu:

sh -c 'echo $0' foo

W tym przykładzie

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

Powłoka jest wywoływana z argumentem echo foo; echo barwyjściowym

foo
bar

8

W tym poleceniu:

echo foo

echo jest plikiem binarnym (lub wbudowanym) i foo jest pierwszym argumentem.

Tutaj:

/bin/sh -c echo foo

/bin/shto plik binarny, którego pierwszym argumentem jest -c, który sam przyjmuje „ciąg polecenia” jako parametr. To jest echow powyższym przykładzie. Jest jeszcze trzeci argument: fooktóry jest argumentem za /bin/sh, a nie za echo. Dlatego w trzecim przykładzie:

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

... oba są drukowane. Zacytowałeś argument. Zatem: pierwszym argumentem jest -c, a parametrem tego argumentu 'echo foo; echo bar'jest interpretowany jako jeden argument; jako „ciąg poleceń”.


3

Struktura sh -c wordwykonuje tylko słowo (w powłoce).
Dodane słowa oznaczają inne rzeczy, takie jak argument zero, jeden, dwa itd .:

sh -c word zero one two three

aby zachować polecenie zawierające spacje jako jedno słowo, konieczne jest cytowanie:

sh -c 'echo fnord' zero one two three

więc wypisuje wszystkie argumenty:

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

Przykłady

W prezentowanym przykładzie: /bin/sh -c echo fooPierwsze słowo (po opcjach) to to echo, co jest wykonywane. I echo bez tekstu wypisze tylko nowy wiersz, nic więcej:

$ / bin / sh -c echo foo

Dlatego dostajesz pustą linię.

Cytując spację, wykonasz „jedno słowo” (bez spacji), ponieważ:

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

Wniosek

Zachowaj wykonane polecenie jako jedno „słowo”, używając cudzysłowu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.