Can someone please help me understand the difference between

bash -c 'echo $SHELL $HOME $USER'


env -i bash -c 'echo $SHELL $HOME $USER'

I tried going over it many times but I still don't get it. I'm studying about env and bash -c appears in the example. What does bash -c do exactly?

  • 1
    bash -c 'commands' runs the commands, that's all. – muru Feb 25 '16 at 2:25

env -i executes the specified command with an empty environment.

bash -c … executes the argument of the -c option (the ) as a bash code snippet.

bash -c 'echo $SHELL $HOME $USER' is equivalent to echo $SHELL $HOME $USER, because running bash doesn't modify these variables (at least as long as they're initially set).

env -i bash -c 'echo $SHELL $HOME $USER' runs bash with the arguments -c and echo $SHELL $HOME $USER, and with an empty environment. When bash starts, it sets some shell variables, including SHELL (which is only set as a shell variable, not exported in the environment of any child program that bash might start). Thus, when bash parses and expands the command echo $SHELL $HOME $USER, the variables HOME and USER are unset but SHELL is set to /bin/sh (I don't know why bash does this), and this command displays /bin/sh followed by two spaces.

The single quotes around the argument of bash -c ensure that the text within the quotes is not expanded by the shell from which you run env -i bash -c '…', so that text is passed as-is to the bash subprocess.

  • "SHELL is set to /bin/sh (I don't know why bash does this)" This is because, on some unix systems at least, /bin/sh is a symbolic link to /bin/bash. This is very much dependant on which system you're running though, Debian and Ubuntu for instance /bin/sh links to /bin/dash – Robo Jan 23 '18 at 22:17
  • @Robo No, that doesn't explain it. How do you go from “bash is sometimes installed as /bin/sh” to “bash sets SHELL to the user's login shell but does not set HOME to the user's home directory or USER to the user's name”? – Gilles Jan 23 '18 at 22:32
  • Ah sorry, answering the wrong question when you run bash, by default it won't act as though it was invoked from a login shell. You can emulate this by passing the -l flag [root@5f992ef6d2b6 /]# env -i bash -lc 'echo $SHELL $HOME $USER' /bin/bash root But $HOME is still not being set, because this is set by the login process before bash is launched. Bash relies on the $HOME variable for a bunch of things, but never actually sets it If (SHELL) it is not set when the shell starts, bash assigns to it the full pathname of the current user's login shell. – Robo Jan 23 '18 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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