1

I found this related question What does sudo -H do? that demonstrates the usage of -H with

sudo -H bash -c 'echo $HOME $USER'

But I don't understand is why is bash necessary, because the echo command can stand on its own, but running

sudo -H echo $HOME $USER

will display instead current user variables (and not root's).

So why is (in this case) bash needed for the commands ran as sudo arguments to take in the -H flag?

This is also true if one specifies another user, like sudo -H -u anotheruser echo $HOME $USER.

user2066480
  • 1,229
  • 2
  • 12
  • 24
  • Put an `echo` in front of `sudo -H echo $HOME $USER ` and you'll understand. It's not `bash` that is required there, it's a way to evaluate `$HOME` by the command launched by `sudo`, not by the current shell. – axiac Apr 09 '18 at 12:40
  • So what kind of commands do this evaluation? Obviously echo does't do it, does it have to be commands that are able to create an interactive shell? – user2066480 Apr 09 '18 at 13:02

2 Answers2

1

$HOME and $USER are expanded by the shell before sudo even runs. You need bash -c to add a layer of indirection, so that the shell run by sudo does the expansion.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

When you run the command:

sudo -H echo $HOME $USER 

the variables $HOME and $USER are evaluated by the current shell. They are replaced with their values and the command line adjusted this way is passed to sudo.

F.e. if your username is foo and your home is /home/foo, the command above is the same thing as:

sudo -H echo /home/foo foo

It's not necessarily bash that is required to get what you want. It's required a way to evaluate the environment variables by the command that is executed by sudo, not by the current shell.

When you run:

 sudo -H bash -c 'echo $HOME $USER'

the $HOME and $USER environment variables are not evaluated by the current shell, because they are enclosed in single quotes.

sudo receives the command line as it is written here (it's fourth argument is the string echo $HOME $USER as a single word). It then launches bash with two arguments: -c and the string mentioned above.

bash interprets -c as "execute a command" that is provided as the next argument. It then tries to run echo $HOME $USER (notice that the variables are not enclosed in quotes here) and, before running echo it replaces $HOME and $USER with their values (that belong to the new user now).

Running bash (or any other shell) is needed to do the variables expansion in the execution environment of the new user.

axiac
  • 68,258
  • 9
  • 99
  • 134