I've been playing around with parameter expansion. The following is my code.

sh -c 'echo $a'

sh -c "echo $b"

c="three" sh -c 'echo $c'
echo $c

And this is the output when i execute this script:

$sh test.sh



For $a, If single quoting suppresses substitution. Shouldn't it just print echo $a ? It's printing a new line, does that mean that the value of $a is null? For $c, the 'echo $c' doesn't work, doesn't print a new line, but the echo $c in the next line works as intended. I'm a little confused how this works.

2 Answers 2


sh -c 'echo $a' is like opening a new shell and typing echo $a in it. Since there's no variable a in the child shell (you didn't export the one you set in the parent shell), it'll print an empty line.


sh -c "echo $b"

, the "echo $b" string is expanded by the current shell and the expanded value is passed as an argument string to the child shell. It's as if you opened a new shell and typed in echo two.

var=val command temporarily sets and exports var=val, just for the invocation of command.

c="three" sh -c 'echo $c'

is almost (the subshell isn't really there) like

( export c="three"; sh -c 'echo $c' )

The c variable in the parent shell is not affected.


If you want to see variables in subprocesses, you have to export them. Like this:

   $ export a=7
   $ sh -c 'echo $a'

In your case, subprocesses (for a and b) don't see variables from parent shell.

When you make string with single quotes, all substitutions don't work. You cannot substitute variable or something like \n. It will be exactly $a or \n. So, string in first case is exactly 'echo $a'. sh -c 'echo $a' will create new process, and this process won't have parent's $a, it will have it's own uninitialized $a, i. e. empty string. It will just execution of 'echo $a'

In second case, you are using double quotes. Substitution works, and string becomes "echo two" before execution subprocess. So, it's just execution sh -c 'echo two'.

In third case, $c becomes exported variable. It is special syntax that means «export variable only for this command». Thus, you execute exactly sh -c 'echo $c', but new shell will contain $c as an environment variable. Like $PATH or $HOME when you start your shell.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .