Por que o eco não é chamado como / bin / sh -c echo foo em alguma saída?

15

Por exemplo, enquanto isso funciona:

$ echo foo
foo

Isso não acontece:

$ /bin/sh -c echo foo

Considerando que isso acontece:

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

Existe uma explicação?

    
por SilverlightFox 05.01.2016 / 17:22

4 respostas

21

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

Da mesma forma:

$ 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.

    
por 05.01.2016 / 17:30
18
$ echo foo
foo

Isso chama echo com o argumento foo e foo é impresso.

$ /bin/sh -c echo foo

Isso invoca o shell com o argumento echo e fornece foo como argumento %código%. O $0 gera uma nova linha e você descarta o foo . Se você quiser output 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 , que gera

foo
bar
    
por 05.01.2016 / 17:34
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 "string de comando" como parâmetro. Isso é echo no exemplo acima. Em seguida, há um terceiro argumento: foo , que é 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 este argumento é 'echo foo; echo bar' , que é interpretado como um argumento; como a "string de comando".

    
por 05.01.2016 / 17:31
3

A estrutura sh -c word executa apenas a palavra (em um shell).
As palavras adicionadas significam outras coisas, como o 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 foo A primeira palavra (após as opções) é echo , é o que é executado. E um eco sem texto imprimirá apenas uma nova linha, nada mais:

$ /bin/sh -c echo foo

É por isso que você recebe uma linha vazia.

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

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

Conclusão

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

    
por 05.01.2016 / 22:26