2

I need to modify an environment variable inside a sudo statement. The sudo statement includes some instructions.

In the example, I set the environment variable VAR1 with the value "ABC".

Then, in the sudo statement (and only here), I need to change that value to "DEF". But the value did not change after I set the value to "DEF". Echo commands return "ABC" as the value of VAR1.

How can I change/set the value of the variable inside the sudo statement?

Here an example of the code I run:

#!/bin/bash
export VAR1="ABC"

sudo -u <user> -i sh -c "
         export VAR1="DEF";
         echo $VAR1;
"

echo $VAR1;

Extra info: I tryed the option -E of sudo, to preserve the environment variable at the moment of sudo invocation (source: https://unix.stackexchange.com/questions/337819/how-to-export-variable-for-use-with-sudo/337820), but the result did not change:

#env VAR1="DEF" sudo -u <user> -E -i sh -c " [...]"
2
  • 3
    sudo env VAR1="DEF" sh -c '...' may be less trouble -- you don't need to worry about making your definitions eval-safe, which is certainly a concern if you're trying to pass data from untrusted sources to a script running with escalated privileges. Though of course that doesn't solve the problem of double quotes causing early expansion -- you do indeed need to use single quotes for your script (same as without sudo; sh -c "foo=bar; echo $foo" is always broken, sudo or no). Commented Jul 9, 2018 at 23:10
  • @jww Huh? There's an MCVE right in the question. Commented Jul 10, 2018 at 12:46

2 Answers 2

3

Use single quotes to prevent the outer shell from interpolating $VAR1. You need $VAR1 to be passed to the inner shell so it can expand it.

sudo -u <user> -i sh -c '
         export VAR1="DEF"
         echo "$VAR1"
'

It's also a good idea to quote variable expansions to prevent globbing and splitting mishaps: write "$VAR1" instead of $VAR1.

(The semicolons aren't necessary since you have newlines.)

Sign up to request clarification or add additional context in comments.

Comments

0

Try this

export VAR1="ABC"

sudo -u <user> -i sh -c '
         export VAR1="DEF"
         echo "${VAR1}"
'

echo $VAR1;

as John Kugelman pointed out, you should use ' instead of " to wrap your command to avoid shell vars interpolation. Also, when referencing to VAR inside the command, use "${}" instead of $, this is what did the trick for me

9 Comments

I can't think of any reason why it should matter whether you write $VAR1 or ${VAR1}. Why do you think it makes a difference?
it did with me, using just $ didn't work for me, I'm using bash so there shouldn't be any problem, and I honestly don't know why is not working
I just tried it. I didn't need the curly braces, but I did need to change sh to bash (combining export with the variable assignment is a bash extension) and add ; at the end of the export line (it wasn't treating the newline as a statement terminator).
Mmmm, this is exactly what I run: export V=1; sudo -i bash -c 'export V=2; echo "${V}"; echo "$V";'; echo $V;, only the ${V} and the last $V (outside sudo cmd) are being printed. Do you know why? I'm not an expert with bash and this is really interesting
It seems to be version-specific. I see what you see on OS X running bash 3.2.57, but not on Linux running 4.2.37.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.