Exporting environment variable to user after login via su
I am struggling to work out what exactly the following alias does. I guess it is making the environment variable COUNTER
available to the user nobody
but the COUNTER=${COUNTER}
preceding the ssh and the SendEnv COUNTER
stump me. I have looked up the man pages but I am none the wiser.
COUNTER=280
...
alias run='COUNTER=${COUNTER} ssh nobody@localhost -o "SendEnv COUNTER"'
I’d like to rewrite this alias without ssh (because it has been disabled). Here is my attempt, but I am not sure if I have done the right thing if I don’t understand what the original alias does exactly.
alias run='su - nobody -c "export COUNTER=${COUNTER}"'
-
Assigning a value to a variable on the same line / in the same statement before a program is run temporarily exports that variable to the environment for the program being run. It’s a way of exporting a variable for just one program – as soon as that program has been run, it’s no longer in the environment and will not affect or be available to any subsequent programs.
COUNTER=${COUNTER} ssh ...
sets $COUNTER to itself, temporarily exports it to the environment, then runsssh
.It was probably written by someone who doesn’t understand what curly braces or quoting are for because
COUNTER=$COUNTER
is 100% equivalent, andCOUNTER="$COUNTER"
would be even better, just because it’s good practice to double-quote variables unless you are absolutely certain that you do not want to and know exactly why you do not want to in that particular case. See $VAR vs ${VAR} and to quote or not to quote -
-o "SendEnv COUNTER"
is anssh
option that tellsssh
what local environment variables should be sent to the remote server. By default, onlyTERM
is sent (and even then, only when a a pty is requested, e.g. an interactive ssh connection where you can type into the remote shell/program and see its output). Fromman ssh_config
:SendEnv
Specifies what variables from the local
environ(7)
should be sent to the
server. The server must also support it, and the server must be configured
to accept these environment variables. Note that theTERM
environment
variable is always sent whenever a pseudo-terminal is requested as it is
required by the protocol. Refer toAcceptEnv
insshd_config(5)
for how
to configure the server. Variables are specified by name, which may contain
wildcard characters. Multiple environment variables may be separated by
whitespace or spread across multipleSendEnv
directives.See PATTERNS for more information on patterns.
It is possible to clear previously set SendEnv variable names by prefixing
patterns with-
. The default is not to send any environment variables.Note that the remote server can and will ignore any sent variables unless it is configured to accept them. By default, it only accepts
TERM
. Fromman sshd_config
:AcceptEnv
Specifies what environment variables sent by the client will be copied into
the session’senviron(7)
. SeeSendEnv
andSetEnv
inssh_config(5)
for how to configure the client. TheTERM
environment variable is always
accepted whenever the client requests a pseudo-terminal as it is required by
the protocol.Variables are specified by name, which may contain the wildcard characters
*
and?
. Multiple environment variables may be separated by
white‐space or spread across multiple AcceptEnv directives. Be warned
that some environment variables could be used to bypass restricted user
environments. For this reason, care should be taken in the use of this
directive. The default is not to accept any environment variables.What this means is that, unless
/etc/ssh/sshd_config
on the remote server (actuallylocalhost
in your example, but that still qualifies as "remote"-ish enough for this purpose) is configured to accept the COUNTER variable, yourCOUNTER=${COUNTER} ssh nobody@localhost -o "SendEnv COUNTER"
command wont do anything that justssh nobody@localhost
wouldn’t do. -
su - nobody -c "export COUNTER=${COUNTER}
will runexport COUNTER=${COUNTER}
as user nobody, then exit (because the-c
option tellssu
to run that command instead of just giving you a shell, it doesn’t run it before giving you a shell). TryCOUNTER="$COUNTER" su - nobody
instead. Or justexport COUNTER
so that it is in the environment for all programs you run.