Pourquoi l'écho appelé en tant que / bin / sh -c écho foo ne produit-il rien?


15

Par exemple, alors que cela fonctionne:

$ echo foo
foo

Cela ne veut pas:

$ / bin / sh -c echo foo

Alors que cela:

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

Y a-t-il une explication?

Réponses:


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

Cela signifie que votre commande doit être comme ceci:

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

De même:

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

C'était la première partie à comprendre; le deuxième cas est simple et n'a pas besoin d'explication, je suppose.


2
Une manière conforme plus stricte et standard seraitsh -c 'echo $1' echo foo
jlliagre

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

3
À mon humble avis, l'explication était assez bonne, mais ce sh -c 'echo $0' foon'est pas la meilleure option, étant donné que l'interrogateur sait déjà que cela /bin/sh -c 'echo foo; echo bar'fonctionne, vous pouvez simplement répondre en citant la commande/bin/sh -c 'echo foo'
X3MBoy

1
@ X3MBoy Le questionneur sait déjà que / bin / sh -c 'echo foo' fonctionne très bien. Il voulait faire écho à quelque chose en dehors de cela, ce que j'ai expliqué
Ijaz Ahmad Khan

18
$ echo foo
foo

Ceci appelle echoavec l'argument foo et foo est imprimé.

$ /bin/sh -c echo foo

Cela invoque le shell avec l'argument echoet fournit foo comme argument $0. Les echosorties une nouvelle ligne et vous jetez le foo . Si vous voulez sortir foo , citez l'argument:

sh -c 'echo foo'

ou utilisez l'argument fourni:

sh -c 'echo $0' foo

Dans cet exemple

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

Le shell est invoqué avec l'argument echo foo; echo barqui génère

foo
bar

8

Dans cette commande:

echo foo

echoest le binaire (ou la commande intégrée) et fooest le premier argument.

Ici:

/bin/sh -c echo foo

/bin/shest le binaire, dont le premier argument est -c, qui accepte lui-même une "chaîne de commande" comme paramètre. C'est echodans l'exemple ci-dessus. Ensuite, il y a un troisième argument: fooqui est un argument pour /bin/sh, pas pour echo. C'est pourquoi dans votre troisième exemple:

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

... les deux sont imprimés. Vous avez cité l'argument. Ainsi: le premier argument est -c, et le paramètre de cet argument est 'echo foo; echo bar'qui est interprété entier comme un seul argument; comme "chaîne de commande".


3

La structure sh -c wordexécute uniquement le mot (dans un shell).
Les mots ajoutés signifient d'autres choses, comme l'argument zéro, un, deux, etc.:

sh -c word zero one two three

pour garder une commande qui a des espaces comme un seul mot, la citation est nécessaire:

sh -c 'echo fnord' zero one two three

ainsi, cela affiche tous les arguments:

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

Exemples

Dans l'exemple que vous présentez: /bin/sh -c echo fooLe premier mot (après les options) est echo, c'est ce qui est exécuté. Et un écho sans texte imprimera une nouvelle ligne uniquement, rien d'autre:

$ / bin / sh -c echo foo

C'est pourquoi vous obtenez une ligne vide.

Si vous citez l'espace, vous exécuterez "un mot" (pas d'espaces), comme ceci:

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

Conclusion

Conservez la commande exécutée comme un "mot" en utilisant des guillemets.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.