AWS EC2 User Data: Commands not recognized when using sudo - bash

I'm trying to create an EC2 User-data script to run other scripts on boot up. However, the scripts that I run fail to recognize some commands and variables that I'd already declared. I'm running the commands as the "ubuntu" user but it still isn't working.
My user-data script looks something like this:
export user="ubuntu"
sudo su $user -c ". ./run_script"
Within the script, I have these lines:
THIS_PATH="/some/path"
echo "export SOME_PATH=$THIS_PATH" >> ~/.bashrc
source ~/.bashrc
However, the script can't run SOME_PATH/application, and echo $SOME_PATH this returns a blank line. I'm confused because $SOME_PATH/application works when I log into the EC2 using SSH and my debug logs using whoami returns "ubuntu."
Am I missing something here?

Your data script is executed as root and su command leaves $HOME and other ENV variables intact (note that sudo is redundant). "su -" does not help either
So, do not use ~ or $HOME but full path /home/ubuntu/.bashrc

I found out the problem. It seems that source ~/.bashrc isn't enough to restart the shell -- the environment variables worked after I referenced them in another bash script.

Related

execute aws command in script with sudo

I am running a bash script with sudo and have tried the below but am getting the error below using aws cp. I think the problem is that the script is looking for the config in /root which does not exist. However doesn't the -E preserve the original location? Is there an option that can be used with aws cp to pass the location of the config. Thank you :).
sudo -E bash /path/to/.sh
- inside of this script is `aws cp`
Error
The config profile (name) could not be found
I have also tried `export` the name profile and `source` the path to the `config`
You can use the original user like :
sudo -u $SUDO_USER aws cp ...
You could also run the script using source instead of bash -- using source will cause the script to run in the same shell as your open terminal window, which will keep the same env together (such as user) - though honestly, #Philippe answer is the better, more correct one.

run inline shell script as root

I have a user, who's a passwordless sudoer. I need to execute shell script file with him, and make him execute one block as sudo. E.g:
su root <<"AS_ROOT"
# do something with my linux
AS_ROOT
But nothing works. I tried:
su - root <<...
sudo -s -- <<...
It barks back at me. I'm on ubuntu 16.04 lts.
Thank you.
As Cyrus points out, su is a different utility to which sudo's configuration doesn't apply.
It sounds like you're looking for something like this:
sudo -s <<'AS_ROOT'
echo "Hi from $USER."
AS_ROOT
This should output Hi from root.
Note that -s is needed to tell sudo to create a shell in order to interpret the commands passed via stdin (the here-doc). That shell is the current user's default shell, as reflected in environment variable $SHELL.

Alternative to export variable in non interactive shell

I have a requirement wherein a script needs to be executed which requires a few environment variables to be set. Typically the following is required:
1) I login to target node, say T1 using 'user1' and set my environment variable, say TEMPDIR=~/tmp; Do a source ~/.bashrc and logoff.
2) Now I'm required to do a non interactive shell script execution. This is
Login to a admin server and run the command:
ssh user1#T1 "sudo -u user2 /path/filescript"
The file script that I execute requires the TEMPDIR to be set.
The above setup doesn't work, as the bash shell is not sourced during non interactive shell (if my understanding is correct). To overcome this, I have tried the below suggestions available in this site and other, but without any luck:
ssh user1#T1 "source ~/.bashrc; sudo -u user2 /path/filescript"
ssh user1#T1 "sudo -u user2 env -i /path/filescript"
Please help. Thanks.
Note: I'm trying to get this done without any intervention from root (I mean using root to set / unset any variables.
I'm not sure step 1 is necessary in any way:
ssh user1#T1 sudo -u user2 env -i TEMPDIR=/home/user2/tmp /path/filescript"

Changing to root user inside shell script

I have a shell script which needs non-root user account to run certain commands and then change the user to root to run the rest of the script. I am using SUSE11.
I have used expect to automate the password prompt. But when I use
spawn su -
and the command gets executed, the prompt comes back with root and the rest of the script does not execute.
Eg.
< non-root commands>
spawn su -
<root commands>
But after su - the prompt returns back with user as root.
How to execute the remaining of the script.
The sudo -S option does not help as it does not run sudo -S ifconfig command which I need to find the IP address of the machine.
I have already gone through these links but could not find a solution:
Change script directory to user's homedir in a shell script
Changing unix user in a shell script
sudo will work here but you need to change your script a little bit:
$ cat 1.sh
id
sudo -s <<EOF
echo Now i am root
id
echo "yes!"
EOF
$ bash 1.sh
uid=1000(igor) gid=1000(igor) groups=1000(igor),29(audio),44(video),124(fuse)
Now i am root
uid=0(root) gid=0(root) groups=0(root)
yes!
You need to run your command in <<EOF block and give the block to sudo.
If you want, you can use su, of course. But you need to run it using expect/pexpect that will enter password for you.
But even in case you could manage to enter the password automatically (or switch it off) this construction would not work:
user-command
su
root-command
In this case root-command will be executed with user, not with root privileges, because it will be executed after su will be finished (su opens a new shell, not changes uid of the current shell). You can use the same trick here of course:
su -c 'sh -s' <<EOF
# list of root commands
EOF
But now you have the same as with sudo.
There is an easy way to do it without a second script. Just put this at the start of your file:
if [ "$(whoami)" != "root" ]
then
sudo su -s "$0"
exit
fi
Then it will automatically run itself as root. Of course, this assumes that you can sudo su without having to provide a password - but that's out of scope of this answer; see one of the other questions about using sudo in shell scripts for how to do that.
Short version: create a block to enclose all commands to be run as root.
For example, I created a script to run a command from a root subdirectory, the segment goes like this:
sudo su - <<EOF
cd rootSubFolder/subfolder
./commandtoRun
EOF
Also, note that if you are changing to "root" user inside a shell script like below one, few Linux utilities like awk for data extraction or defining even a simple shell variable etc will behave weirdly.
To resolve this simply quote the whole document by using <<'EOF' in place of EOF.
sudo -i <<'EOF'
ls
echo "I am root now"
EOF
The easiest way to do that would be to create a least two scripts.
The first one should call the second one with root privileges. So every command you execute in the second script would be executed as root.
For example:
runasroot.sh
sudo su-c'./scriptname.sh'
scriptname.sh
apt-get install mysql-server-5.5
or whatever you need.

sbt (Scala) via SSH results in command not found, but works if I do it myself

So I'm trying to do something that involves running sbt over an SSH command, and this is what I'm trying:
ssh my_username#<server ip> "cd <project folder>; sbt 'run-main Foo' "
When I do that however, I get an error message: bash: sbt: command not found
Then I go SSH into the server myself, cd to the project folder, and run sbt 'run-main Foo' and everything works nicely. I have checked to make sure sbt is on the $PATH variable on the remote server via ssh my_username#<server ip> "echo $PATH" and it shows the correct value.
I feel like this is a simple fix, but cannot figure it out... help?
Thanks!
-kstruct
When you log in, bash is run as an interactive shell. When you run commands directly through ssh, bash is run as a non-interactive shell, and therefore different initialization files are sourced (see the bash manual pages for which exactly). There are a number of ways to fix this, e.g.:
Use the full path to sbt when calling it directly through ssh
Edit .bashrc and add the missing directories to the PATH environment variable
Note that your test ssh my_username#<server ip> "echo $PATH" actually prints PATH on your client, not your server, because of the double quotes. Use ssh my_username#<server ip> 'echo $PATH' or ssh my_username#<server ip> env to print PATH from the server's environment. When checking using env, you will see that PS1 is only set in interactive shells.

Resources