where did my environment variable go? - bash

I am trying to use an environment variable in a bash script that needs to run as sudo with source.
I have the following file (my_file.sh)
echo "this is DOMAIN = $DOMAIN"
I have the DOMAIN environment variable in my session..
and now I need to run
sudo -E bash -c "source ./my_file.sh"
but the output does not display the value for $DOMAIN. instead it is empty.
if I change the command to be
sudo -E bash -c "echo $DOMAIN"
I see the correct value..
what am I doing wrong?

With the command line:
sudo -E bash -c "source ./my_file.sh"
you are running a script that may refer to environment variables that would need to be exported from a parent shell to be visible.
On the other hand:
sudo -E bash -c "echo $DOMAIN"
expands the value of $DOMAIN in the parent shell, not inside your sudo line.
To demonstrate this, try your "working" solution with single quotes:
sudo -E bash -c 'echo $DOMAIN'
And to make things go, try exporting the variable:
export DOMAIN
sudo -E bash -c "source ./my_file.sh"
Or alternately, pass $DOMAIN on the command line:
sudo -E bash -c "source ./my_file.sh $DOMAIN"
And have your script refer to $1.

Related

Why sudo -H needs an extra command?

I found this related question What does sudo -H do?
that demonstrates the usage of -H with
sudo -H bash -c 'echo $HOME $USER'
But I don't understand is why is bash necessary, because the echo command can stand on its own, but running
sudo -H echo $HOME $USER
will display instead current user variables (and not root's).
So why is (in this case) bash needed for the commands ran as sudo arguments to take in the -H flag?
This is also true if one specifies another user, like sudo -H -u anotheruser echo $HOME $USER.
When you run the command:
sudo -H echo $HOME $USER
the variables $HOME and $USER are evaluated by the current shell. They are replaced with their values and the command line adjusted this way is passed to sudo.
F.e. if your username is foo and your home is /home/foo, the command above is the same thing as:
sudo -H echo /home/foo foo
It's not necessarily bash that is required to get what you want. It's required a way to evaluate the environment variables by the command that is executed by sudo, not by the current shell.
When you run:
sudo -H bash -c 'echo $HOME $USER'
the $HOME and $USER environment variables are not evaluated by the current shell, because they are enclosed in single quotes.
sudo receives the command line as it is written here (it's fourth argument is the string echo $HOME $USER as a single word). It then launches bash with two arguments: -c and the string mentioned above.
bash interprets -c as "execute a command" that is provided as the next argument. It then tries to run echo $HOME $USER (notice that the variables are not enclosed in quotes here) and, before running echo it replaces $HOME and $USER with their values (that belong to the new user now).
Running bash (or any other shell) is needed to do the variables expansion in the execution environment of the new user.
$HOME and $USER are expanded by the shell before sudo even runs. You need bash -c to add a layer of indirection, so that the shell run by sudo does the expansion.

Echo variable using sudo bash -c 'echo $myVariable' - bash script

I want to echo a string into the /etc/hosts file. The string is stored in a variable called $myString.
When I run the following code the echo is empty:
finalString="Hello\nWorld"
sudo bash -c 'echo -e "$finalString"'
What am I doing wrong?
You're not exporting the variable into the environment so that it can be picked up by subprocesses.
You haven't told sudo to preserve the environment.
\
finalString="Hello\nWorld"
export finalString
sudo -E bash -c 'echo -e "$finalString"'
Alternatively, you can have the current shell substitute instead:
finalString="Hello\nWorld"
sudo bash -c 'echo -e "'"$finalString"'"'
You can do this:
bash -c "echo -e '$finalString'"
i.e using double quote to pass argument to the subshell, thus the variable ($finalString) is expanded (by the current shell) as expected.
Though I would recommend not using the -e flag with echo. Instead you can just do:
finalString="Hello
World"

Not able use lftp commands running from shellscript

I'm using set of commands from a shellscript. First command is running fine but it is moving to lftp command prompt and expecting manual input instead of running commands from shelscript. Following are the commands i'm using
lftp -e "$HOST"
lftp -u "$USER,$PWD"
lftp -e "cd /inbox"
put $file
bye
Please suggest me some solution
Using lower-case variable names to avoid conflicts with local environment variables or shell-builtins ($USER and $PWD are both builtins, so you shouldn't be setting them yourself):
lftp \
-e "cd /inbox; put $file" \
-u "$user,$pwd" \
"$host"
The point, here, is invoking lftp only once, and passing all the necessary commands to that single invocation.

Cannot set environment variable before command

I am trying to set a variable before calling a command in bash (on Mac):
BRANCH=test echo "$BRANCH"
But I get an empty echo.
printenv also has no other variable with the same name:
$ printenv | grep BRANCH
$
What am I doing wrong?
This is correct way:
BRANCH='test' bash -c 'echo "$BRANCH"'
test
To execute echo command you'll need bash -c to execute it after assignment.

How to set $TERM to a value when running /bin/bash via command line?

When I run the /bin/bash process with 2 parameters -c and SomeUserInput,
where SomeUserInput is echo $TERM
The output is
xterm-256color
Is there a way I can set the value of $TERM via a command line parameter to /bin/bash so the above invokation of echo $TERM would print something else that I specify?
(Yes, I've done a lot of digging in man bash and searching elsewhere, but couldn't find the answer; although I think it's likely there.)
First of all, since you used double quotes, that prints the value of TERM in your current shell, not the bash you invoke. To do that, use /bin/bash -c 'echo $TERM'.
To set the value of TERM, you can export TERM=linux before running that command, set it only for that shell with either TERM=linux /bin/bash -c 'echo $TERM' (shell expression), or /usr/bin/env TERM=linux /bin/bash -c 'echo $TERM' (execve compatible (as for find -exec)).
Update:
As for your edit of only using command line parameters to /bin/bash, you can do that without modifying your input like this:
/bin/bash -c 'TERM=something; eval "$1"' -- 'SomeUserInput'
Well, you can either set the variable on your .bashrc file, or simply set with the bash invocation:
/bin/bash -c "TERM=something-else; echo $TERM"

Resources