0

Input:

sudo bash -c '>> /media/$USER/rootfs/etc/profile'

Output:

bash: /media/root/rootfs/etc/profile: No such file or directory

Input:

TEST=$USER
sudo bash -c '>> /media/$TEST/rootfs/etc/profile'

Output:

bash: /media//rootfs/etc/profile: No such file or directory

Instead of:

/media/riccardo/rootfs/etc/profile

How can I solve the problem?

2 Answers2

4

Shell variables aren't exported to commands launched from the shell, by default.

You need to explicitly do it with export, e.g.:

$ export test=foo
$ bash -c 'echo test=$test'
test=foo

Except that sudo may still clean up the environment before passing it to bash, so you may need to use the command line arguments instead:

$ test=foobar 
$ sudo bash -c 'echo "$1"' sudo_bash "$test"
foobar

No need to export here, and sudo_bash is just a string that's used as the "name" of that inner shell, you'd see it if the -c string had e.g. a syntax error.

See also:

ilkkachu
  • 138,973
  • Thank you ilkkachu, also if i have found an more elegant solution: – Riccardo La Marca Mar 14 '20 at 13:13
  • sudo bash -c ">> /media/$USER/rootfs/etc/profile" – Riccardo La Marca Mar 14 '20 at 13:13
  • double quotes instead of single quotes solve my problem. – Riccardo La Marca Mar 14 '20 at 13:14
  • 1
    @RiccardoLaMarca, ah, I should have mentioned that in the first place. In general, don't use double quotes like that. If you do, the contents of the variable get expanded as part of the inner shell's command line, just like any other code there. Shell metacharacters and expansions get processed, so they can break the structure of the command and even cause security issues. Try e.g. test='foo;bar'; bash -c "echo $test" – ilkkachu Mar 14 '20 at 13:26
  • Wow, it's true, this issue was not known to me. Thank you. – Riccardo La Marca Mar 16 '20 at 09:32
1

Quoting problems

sudo bash -c '>> /media/'"$USER"'/rootfs/etc/profile'
test=$USER
sudo bash -c '>> /media/'"$test"'/rootfs/etc/profile'

'' quotes are literal, "" quotes allow expansion of variables. I have use both, concatenating them together. It would also work if I only used "".

  • This has exactly the issue with unsafe expansion of $USER or $test in the command line interpreted by the shell started from sudo. – ilkkachu Mar 16 '20 at 11:28
  • What is the danger? These variables are expanded by the calling shell, so you have to be responsible for ensuring they are correct, and won't cause a problem. Can you explain what the danger is? – ctrl-alt-delor Mar 16 '20 at 13:02
  • The usual, shell metacharacters and whitespace being interpreted as part of the command, and not just as pure data. Compare test='foo;bar'; sudo bash -c 'echo /media/'"$test"'/rootfs/etc/profile' and test='foo;bar'; sudo bash -c 'echo /media/"$1"/rootfs/etc/profile' sh "$test". Sure, $USER probably contains just letters and digits, but it's not hard to use command line args or the environment to pass the value safely. – ilkkachu Mar 16 '20 at 13:09
  • @ilkkachu oh yes. Would I need to add more quotes (for sudo). You can edit if you like. – ctrl-alt-delor Mar 16 '20 at 13:12