Mengapa gema tidak disebut sebagai / bin / sh -c echo foo output apa pun?

15

Misalnya, saat ini berfungsi:

$ echo foo
foo

Ini tidak:

$ / bin / sh -c echo foo

Padahal ini tidak:

$ / bin / sh -c 'echo foo; bilah gema
foo
batang

Apakah ada penjelasan?

SilverlightFox
sumber

Jawaban:

21

Dari 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

Itu berarti perintah Anda harus seperti ini:

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

Demikian pula:

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

Itu adalah bagian pertama yang dipahami; kasus kedua sederhana dan tidak perlu penjelasan, saya kira.

Ijaz Ahmad Khan
sumber
2
Cara konforman yang lebih ketat dan standar adalahsh -c 'echo $1' echo foo
jlliagre
1
sh -c 'echo "$@"' fnord a b c d ...
zwol
3
IMHO penjelasannya cukup bagus, tetapi sh -c 'echo $0' foobukan pilihan terbaik, dengan mempertimbangkan bahwa penanya sudah tahu bahwa itu /bin/sh -c 'echo foo; echo bar'berfungsi, Anda cukup menjawab dengan mengutip perintah/bin/sh -c 'echo foo'
X3MBoy
1
@ X3MBoy Penanya sudah tahu bahwa / bin / sh -c 'echo foo' berfungsi dengan baik. Dia ingin menggemakan sesuatu di luar itu, yang saya jelaskan
Ijaz Ahmad Khan
18
$ echo foo
foo

Panggilan ini echodengan argumen foo dan foo dicetak.

$ /bin/sh -c echo foo

Ini memanggil shell dengan argumen echodan memberikan foo sebagai argumen $0. The echooutput baris baru dan Anda membuang foo . Jika Anda ingin menampilkan foo , kutip argumennya:

sh -c 'echo foo'

atau gunakan argumen yang disediakan:

sh -c 'echo $0' foo

Dalam contoh ini

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

Shell dipanggil dengan argumen echo foo; echo baryang menghasilkan

foo
bar
Marco
sumber
8

Dalam perintah ini:

echo foo

echoadalah biner (atau perintah bawaan) dan foomerupakan argumen pertama.

Sini:

/bin/sh -c echo foo

/bin/shadalah biner, yang argumen pertamanya adalah -c, yang dengan sendirinya menerima "string perintah" sebagai parameter. Ini echodalam contoh di atas. Lalu ada argumen ketiga: fooyang merupakan argumen untuk /bin/sh, bukan untuk echo. Itu sebabnya dalam contoh ketiga Anda:

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

... keduanya dicetak. Anda mengutip argumennya. Jadi: argumen pertama adalah -c, dan parameter untuk argumen ini adalah 'echo foo; echo bar'yang ditafsirkan secara keseluruhan sebagai satu argumen; sebagai "string perintah".

kekacauan
sumber
3

Struktur sh -c wordhanya mengeksekusi kata (dalam shell).
Kata-kata yang ditambahkan berarti hal-hal lain, seperti argumen nol, satu, dua, dll .:

sh -c word zero one two three

untuk menjaga perintah yang memiliki spasi sebagai satu kata, mengutip diperlukan:

sh -c 'echo fnord' zero one two three

jadi, ini mencetak semua argumen:

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

Contohnya

Dalam contoh yang Anda sajikan: /bin/sh -c echo fooKata pertama (setelah opsi) adalah echo, itulah yang dieksekusi. Dan gema tanpa teks hanya akan mencetak baris baru, tidak ada yang lain:

$ / bin / sh -c echo foo

Itu sebabnya Anda mendapatkan garis kosong.

Jika Anda mengutip spasi, Anda akan mengeksekusi "satu kata" (tanpa spasi), karena ini:

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

Kesimpulan

Simpan perintah yang dieksekusi sebagai satu "kata" menggunakan mengutip.


sumber