I basically need to do this:
DUMMY=dummy
sudo su - ec2-user -c 'echo $DUMMY'
This doesn't work. How can I pass the env variable $DUMMY to su? -p doesn't work with -l.
I basically need to do this:
DUMMY=dummy
sudo su - ec2-user -c 'echo $DUMMY'
This doesn't work. How can I pass the env variable $DUMMY to su? -p doesn't work with -l.
Pro tip: There is never really a good reason to run sudo su
. To run a command as a different user, use sudo -u username command
. If you want a root shell, run sudo -i
or sudo -l
. If you have activated the root account, you can also run su
alone, but sudo su
is just not useful. And yes, I know you see it everywhere.
That said, sudo
has the -E
switch which will preserve the environment of the user's session:
-E, --preserve-env
Indicates to the security policy that the user wishes to preserve
their existing environment variables. The security policy may
return an error if the user does not have permission to
preserve the environment.
So, you will first need to export your variable, and then run sudo -E
:
$ export DUMMY=dummy
$ sudo -Eu bob bash -c 'echo $DUMMY'
dummy
The bash -c
is not needed. However, if I run sudo -Eu bob echo "$DUMMY"
, the variable is expanded before the root shell is launched so it doesn't demonstrate that the command actually works:
$ sudo -u bob echo $DUMMY ## looks like it works but doesn't
dummy
$ sudo -u bob bash -c 'echo D:$DUMMY' ## now we see it failed
D:
$ sudo -Eu bob bash -c 'echo D:$DUMMY' ## works as expected
D:dummy
env_keep
in sudoers
. Perhaps like this: Defaults env_keep += "DUMMY"
.
– lcd047
May 09 '15 at 09:58
sudo
. It is also more cumbersome for a single variable. That is only useful for something that should always be exported.
– terdon
May 09 '15 at 11:37
LD_PRELOAD
and carrying over LESSCHARDEF
. I don't think convenience should be the winning argument here...
– lcd047
May 09 '15 at 13:54
You can do it without calling login shell:
sudo DUMMY=dummy su ec2-user -c 'echo "$DUMMY"'
or:
sudo DUMMY=dummy su -p - ec2-user -c 'echo "$DUMMY"'
The -p
option of su
command preserve environment variables.
-m
preserves the variable, other says -c
whats the difference? And one of the comment in this answer days -E
https://stackoverflow.com/questions/10488758/how-do-you-give-su-the-current-user-environment-variables
– Vishrant
Jan 08 '19 at 17:12
-m
and -p
are the same, -c
does not. -E
is for sudo
, not su
.
– cuonglm
Jan 09 '19 at 10:42
-E
when you only want to preserve one environment variable.
– SpinUp __ A Davis
Sep 10 '19 at 17:01
-p
is ignored when --login
is used. So for the second case one should put env variables to a user shell profile.
– Fox Amadeus
Oct 15 '23 at 14:28
-E does the job for me.
From man sudo
-
-E
,--preserve-env
Indicates to the security policy that the user wishes to pre‐ serve their existing environment variables. The security policy may return an error if the user does not have permis‐ sion to preserve the environment.
Also su
has a --whitelist-environment
option. It can be used like so:
# export DUMMY=dummy
# export FOO=foo
# su -l somebody --whitelist-environment="DUMMY,FOO"
$ env
...
PWD=/home/somebody
LOGNAME=somebody
HOME=/home/somebody
...
DUMMY=dummy
FOO=foo
...
Don't forget to export
the whitelisted variables.
I also faced this issue and I fixed by exporting env variable into profile. below is my sample code:
echo export runner_token=$(echo $resp_json | jq -r '.token') >> /etc/profile
su -p - ubuntu -c '$HOME/actions-runner/config.sh --url https://github.com/${gh_repo_user}/${gh_repo_name} --token "$runner_token" --name MAC-AWS-RUNNER --labels ${gh_runner_labels}'
What follows is a solution that does not need one to change the security policy.
I will ignore the su
part, as we can use the --user
option of sudo
.
We want to pass environment variables to a command
run via sudo
. However sudo
will not allow environment variables to be passed to a command (there are valid security reason for this, some variables can be dangerous). A shell can be used to set environment variables, and sudo
can run a shell with a script passed to it. Therefore tell sudo
to run a script that sets the environment variables.
var_a=someThing
var_b=someOtherThing
sudo bash -c "
export var_a=\"${var_a}\"
export var_b=\"${var_b}\"
the_command some_args
"
sudo -iu ec2-user echo $DUMMY
? – muru May 09 '15 at 08:44