How to ssh/sudo su - oracle/run some commands - shell

I have already looked at the following links but didn't managed to make it work:
SSH to server, Sudo su - then run commands in bash
Can I ssh somewhere, run some commands, and then leave myself a prompt?
Run ssh and immediately execute command
I'm trying to automate the following sequence to log in to the database
$ ssh <myserver>
me#myserver$ sudo su - oracle
<enter password>
oracle#myserver$ bash
oracle#myserver$ export ORAENV_ASK=NO
oracle#myserver$ export ORACLE_SID=ORACLEDB
oracle#myserver$ . oraenv
oracle#myserver$ echo $ORACLE_HOME
I tried the command (based on the links above) but that does not work :
ssh -t myserver "echo password | sudo -S su - oracle ; bash ; export ORAENV_ASK=NO"
How can I combine thoses commands in a shell script (or even perl one), execute it and then leave myself at a prompt so I can run sqlplus after? Is that even possible?
Note:
ssh does not need password because we use authorized_keys, BUT Password-less sudo is not an option nor using su directly (I'm not root and cannot change that), the command needs to be "sudo su - oracle" exactly.
Thanks

You can't do that in shell, but you can do it with expect (apt-get install expect if on Debian variants).
This is a very simple expect file. You need to do some research to make it work in your environment but this gives the general idea.
spawn ssh foo#x.x.x.x
expect "~$"
send "sudo bash\r"
expect {
password {send "foobar\r";exp_continue}
"#"
}
send "id\r"
expect "root"
You would run this as expect /path/to/your/expectfile.
This will log in, do sudo with password "foobar", execute id and exit. Would this be of any help?
Hannu

Related

Using sshpass to run a command on another server

I'm trying to run a single command on server X, to have that SSH into server Y and run another command
I'm doing this like the below:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su c command_must_be_run_root --arguments"
So to break it down:
I'm using "sshpass" to pass a password into my ssh command
I'm SSH'ing into the new server as the "test-admin" user
once in the server, I am running the command "sudo su command_must_be_run_root --arguments
This "command_must_be_run_root" is a command that has to be run as root only
It also has arguments I have to pass in. However I'm seeing that when I pass in the arguments, it is passing these arguments into the "su" command, and not passing them into the new command I want to run
Any ideas on how to fix this?
For what ever reason when you have a command with arguments you need to actually tell sudo su to login as root. Without logging in first it will run the first part of the command, even with all of it in single quotes, but not the args. (I guess it thinks that is the end of the command or it's only 1 command per sudo su -c, and that is why the persistent login works?). After adding sudo su -l root then you can continue with -c and everything that follows needs single quotes.
Should look like this:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su -l root -c 'command_ran_as_root --arguments'"
I don't think that su command is valid in any case. The syntax of su is su <someuser> [arguments...], so what you've written is going to try running command_must_be_run_root as user c.
I suspect that c is supposed to be -c, in which case you need to quote the arguments to -c, which would solve the problem you're asking about:
sshpass -p 'my_password' ssh -t test-admin#my_ip "sudo su -c 'command_must_be_run_root --arguments'"
But the next question is, if you already have sudo access, why are you bothering with su? You could just write instead:
sshpass -p 'my_password' ssh -t test-admin#my_ip sudo command_must_be_run_root --arguments

How to get the output of ssh when the command has a command to change user

When I use ssh to run command on a remote machine, I will get the output from shell. However, if I add
sudo su - user2
I will get no output. Now, I cannot do
ssh user2#host
Because of some permission issue.
Is there any way to get the output for the following command?
ssh user1#host 'sudo su - user2; wc -l tmp.txt'
Thanks to #laenkeio. Using sudo -u user2 can run some simple programs.
However, when I need to call a python script which needs some enviroment variable for user2, the script was not able to find those default path by using sudo -u user2.
If you have the appropriate sudo rights on host you should be able to do it with:
ssh -t user1#host 'sudo -u user2 wc -l tmp.txt'
Using sudo -u means "execute as user2", thus avoiding the extra su -. And -t forces ssh to allocate a tty so that sudo can ask for your password.
If you cannot do ssh user2#host for some permission issue, you'll not be able to run ssh user1#host 'sudo su - user2; ... for the same reason...
And, even with no permission issue, when doing su - user you'll be requested for a password...

BASH instead of CSH while running Commands on a Remote Linux Server over SSH

I would like to run a command on a remote server using ssh, under bash, while my default session is csh.
minimal example (true command is more complex and is generated by my IDE remote debugger):
ssh hostname 'ls | head'
I don't have admin privileges. Trying chsh -s /bin/bash results with an error chsh: cannot lock /etc/passwd; try again later.
I tried adding to .cshrc the following
setenv SHELL /bin/bash
exec /bin/bash --login
but it freezes the console when sending the command through ssh (while regular ssh works)
Any idea how to solve that?
NOTE: I must have a solution that would configure the host, because I don't have access to the ssh command which is generated automatically by the debugger of my IDE. On the IDE I can only set the host name and port number. (EDIT) Therefore solutions like ssh hostname '/bin/bash -c "ls | head"' wont apply
EDIT2:
Actual command shown by IDE (again, I can't edit it):
ssh://username#localhost:2213/home/lab/username/anaconda2/envs/tf_011b/bin/python -u /specific/a/home/cc/cs/username/.pycharm_helpers/pydev/pydevd.py --multiproc --qt-support --client '0.0.0.0' --port 41823 --file /home/lab/username/remote_py/nlteach/show_attend_and_tell/train_saat_classifier.py --train_dir=/home/lab/username/nlteach/output/train/d=cub/imSD=11%imSP=rnd%tcSP=cvpr16/CSat/res50%lr0_02LrDTexpLrDc0_938OrmspWDc0/emb=512%ldTrn=0%nU=512%noHid=1%lr=0_02%lrDT=fix%lrDc=1%o=rmsp/
I am not sure why, but on a bash enabled server it works, while it fails on the csh host.
Thanks!
Invoke bash on the remote side, telling it what commands to run:
ssh hostname '/bin/bash -c "ls | head"'
If the command is too complicated (eg because of quotation mark escaping), then write your commands to a script, copy the script, then run the script:
scp script.bash hostname:/tmp/
ssh hostname '/bin/bash /tmp/script.bash'

How to first login using sudo and then run rest of Unix Shell script

I am working on Automating deployment script for which I have to run all steps as sudo user, when I try to sudo first in my script like below it prompt me for password and then rest of script doesn't execute, when i exit sudo then only it executes.
"sudo -u username bash"
Please help me how to achieve this or I have to first login using sudo and then only run my script ?
You can instead just run the script as sudo.
sudo sh ./script.sh
This way the entire script would run as a sudo user, and it would prompt only for once.
If you want to still use sudo -u you can use it like this, instead of:
sudo -u username bash
You can do:
sudo -u username sh ./script.sh

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.

Resources