Por que echo chamado como / bin / sh -c echo foo não produz nada?


15

Por exemplo, enquanto isso funciona:

$ echo foo
foo

Isto não:

$ / bin / sh -c eco eco

Considerando que isto faz:

$ / bin / sh -c 'echo foo; barra de eco '
foo
Barra

Existe uma explicação?

Respostas:


21

A partir de 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

Isso significa que seu comando deve ser assim:

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

Similarmente:

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

Essa foi a primeira parte a entender; o segundo caso é simples e não precisa de explicação, eu acho.


2
A mais rigorosa, maneira conformant padrão seriash -c 'echo $1' echo foo
jlliagre

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

3
IMHO a explicação foi muito bom, mas sh -c 'echo $0' foonão é a melhor opção, tendo em conta que o interlocutor já sabe que /bin/sh -c 'echo foo; echo bar'funciona, você pode simplesmente responder citando o comando/bin/sh -c 'echo foo'
X3MBoy

1
@ X3MBoy O interlocutor já sabe que / bin / sh -c 'eco foo' funciona bem. Ele queria eco fora algo que, que eu expliquei
Ijaz Ahmad Khan

18
$ echo foo
foo

Isso chama echocom o argumento foo e foo é impresso.

$ /bin/sh -c echo foo

Isso chama o shell com o argumento echoe fornece foo como argumento $0. A echosaída é uma nova linha e você descarta o foo . Se você deseja gerar foo , cite o argumento:

sh -c 'echo foo'

ou use o argumento fornecido:

sh -c 'echo $0' foo

Neste exemplo

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

O shell é invocado com o argumento echo foo; echo barque gera

foo
bar

8

Neste comando:

echo foo

echoé o binário (ou comando interno) e fooé o primeiro argumento.

Aqui:

/bin/sh -c echo foo

/bin/shé o binário, cujo primeiro argumento é -c, que aceita uma "sequência de comandos" como parâmetro. Isso está echono exemplo acima. Depois, há um terceiro argumento: fooque é um argumento para /bin/sh, não para echo. É por isso que no seu terceiro exemplo:

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

... ambos são impressos. Você citou o argumento. Assim: o primeiro argumento é -c, e o parâmetro para esse argumento é o 'echo foo; echo bar'que é interpretado inteiro como um argumento; como a "cadeia de comandos".


3

A estrutura sh -c wordexecuta apenas a palavra (em um shell).
As palavras adicionadas significam outras coisas, como argumento zero, um, dois, etc .:

sh -c word zero one two three

para manter um comando que tenha espaços como uma palavra, é necessário citar:

sh -c 'echo fnord' zero one two three

então, isso imprime todos os argumentos:

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

Exemplos

No exemplo que você apresenta: /bin/sh -c echo fooA primeira palavra (depois das opções) é echo, é isso que é executado. E um eco sem texto imprimirá apenas uma nova linha, nada mais:

$ / bin / sh -c eco eco

É por isso que você recebe uma linha vazia.

Se você citar o espaço, estará executando "uma palavra" (sem espaços), como este:

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

Conclusão

Mantenha o comando executado como uma "palavra" usando aspas.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.