0

I'm trying to run a script which switches users (following this answer). I'm unable to set a variable within this. I've tried many things but the most basic is:

sudo -u other_user bash << EOF
V=test
echo "${V}"
EOF

More realistically I am doing something similar to the following:

sudo -u other_user bash << EOF
cd
V=$(ls)
echo "${V}"
EOF

Every time I try to use the variable V it is unset. How can I set a variable?

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • 2
    Can't test on my current environment, but I'm pretty sure `"${V}"` is expanded in your outer shell rather than in the other user's. Try escaping the `$` – Aaron Apr 20 '18 at 19:40
  • @Aaron that's it! Convert to an answer and I'll accept – Ryan Haining Apr 20 '18 at 19:42
  • Protip: Just like you can print variable values to try to debug a script, you can print the contents of here docs to make sure you're passing the right data. Simply replace `sudo -u other_user bash` with `cat` and you'll see what your shell is getting and why it behaves like that – that other guy Apr 20 '18 at 19:47
  • @RyanHaining Charles Duffy's answer is probably better, might as well accept this one :) – Aaron Apr 20 '18 at 19:47

1 Answers1

4

To suppress all expansions within the heredoc, quote the sigil -- that is, <<'EOF', not <<EOF:

sudo -u other_user bash -s <<'EOF'
cd
v=$(ls)      # aside: don't ever actually use ls programmatically
             #        see http://mywiki.wooledge.org/ParsingLs
echo "$v"    # aside: user-defined variables should have lowercase names; see
             #        http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
             #        fourth paragraph ("the name space of environment variable names
             #        containing lowercase letters is reserved for applications.")
EOF

If you want to pass variables through, pass them after the -s, and refer to them positionally from in the heredoc script (as $1, $2, etc).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441