Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For example, while this works:

$ echo foo
foo

This doesn't:

$ /bin/sh -c echo foo

Whereas this does:

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

Is there an explanation?

share|improve this question
up vote 19 down vote accepted

From 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

It means your command should be like this:

 $ sh -c 'echo $0' foo 
 foo

Similarly:

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

That was the first part to understand , the second case is simple and don't need explanation , i guess.

share|improve this answer
2  
A stricter, standard conformant way would be sh -c 'echo $1' echo foo – jlliagre Jan 5 at 16:33
1  
sh -c 'echo "$@"' fnord a b c d ... – zwol Jan 5 at 17:43
3  
IMHO the explanation was quite good, but sh -c 'echo $0' foo is not the best option, taking into account that the questioner already know that /bin/sh -c 'echo foo; echo bar' works, you can simply answer quoting the command /bin/sh -c 'echo foo' – X3MBoy Jan 5 at 18:01
1  
@ X3MBoy The questioner already know that /bin/sh -c 'echo foo' works fine. He wanted to echo something outside that , which i explained – Ijaz Khan Jan 5 at 18:18
$ echo foo
foo

This calls echo with the argument foo and foo is printed.

$ /bin/sh -c echo foo

This invokes the shell with the argument echo and provides foo as argument $0. The echo outputs a new line and you discard the foo. If you want to output foo, quote the argument:

sh -c 'echo foo'

or use the provided argument:

sh -c 'echo $0' foo

In this example

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

The shell is invoked with the argument echo foo; echo bar which outputs

foo
bar
share|improve this answer

In this command:

echo foo

echo is the binary (or built-in command) and foo is the first argument.

Here:

/bin/sh -c echo foo

/bin/sh is the binary, whose first argument is -c, which itself accepts a "command string" as parameter. This is echo in the above example. Then there is a third argument: foo which is an argument for /bin/sh, not for echo. That's why in your third example:

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

... both are printed. You quoted the argument. Thus: the first argument is -c, and the parameter to this argument is 'echo foo; echo bar' which is interpreted whole as one argument; as the "command string".

share|improve this answer

The structure sh -c word executes only word (in a shell).
Added words mean other things, like argument zero, one, two, etc.:

sh -c word zero one two three

to keep a command which has spaces as one word, quoting is needed:

sh -c 'echo fnord' zero one two three

so, this prints all the arguments:

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

Examples

In the example you present: /bin/sh -c echo foo The first word (after options) is echo, that is what is executed. And an echo with no text will print a new-line only, nothing else:

$ /bin/sh -c echo foo

That is why you do get an empty line.

If you quote the space, you will be executing "one word" (no spaces), as this:

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

Conclusion

Keep the executed command as one "word" using quoting.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.