Using sshpass to run a command on another server - bash

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

Related

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...

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

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

"sudo su && somecommand" doesn't run somecommand

I have created a Jenkins job today, what it does is the Jenkins user should log into another server and run two commands seperated by &&:
ssh -i /creds/jenkins jenkins#servername.com "sh -c 'sudo su && df'"
The loging part works fine, then it runs the sudo su command and becomes root but it never runs the second command (i.e. df).
I even did this manually and from the Jenkins machine logged into the other server (servername). Then ran sh -c "sudo su && df" with no luck.
Can you please help?
Thanks in advance
If you are trying to run the df command as root, you should instead do sudo df.
This is because with sudo su && df, you are basically executing sudo su first and then df.
Also make sure, your jenkins user can be sudo without password.
The sudo su launches a second shell, and the command containing the && df is waiting to be executed in the non-root shell, just after the sudo su shell exits successfully.
This could be what you're looking for:
sh -c 'sudo su - root -c "df"'
Edit: please note that I don't normally use or advocate the use of sudo su - root -c type of constructions. However, I have seen rare cases in which a program doesn't work properly when called via sudo/gksudo, but does work properly when called via su/gksu -- in such cases, a given user should try to use sudo -i first, and if that does not work, one might have to resort to sudo su - root -c or similar, as a workaround of sorts to deal with a "misbehaving" program. Since the OP used some similar syntax on his post, I assumed that his case could be such a workaround case, so I maintained the sudo su - root -c type of structure on my answer.
when you did sudo su && df , sudo su will start a child process immediately without waiting for the && df part of the command to execute , when you hit Ctrl + D it exits the child process and enters the parent shell , that's when your && df will execute. You should do this using here strings, it might not be the best option but it works and it does not start a new child process
sh -c "sudo su" <<<df
note: don't surround <<< df with any quotes

Escaping from sudo within a script

I have a script that calls another script as sudo. From within the second script, I want to be able to run another process without sudo permissions (the process in question is brew, which doesn't play nicely with sudo).
Here's the code in question:
scriptA.sh:
#!/bin/sh
sudo ./scriptB.sh
scriptB.sh:
#!/bin/sh
# This runs as sudo, but I need it to run as a regular user e.g. `username`
brew update
I tried su -c "brew update" -s /bin/sh username, but OS X's su doesn't allow the c flag.
Just use sudo again:
sudo -u username brew update
Superuser can use the su command to become any other user. So
su otheruser -c "command to execute"
OS X su does allow the -c option. You just have to put it after the username. From the man page:
If the optional args are provided on the command line, they are passed to the login shell of the target login. Note that all command line arguments before the target login name are processed by su itself, everything after the target login name gets passed to
the login shell.
In this case -c is not an option to the su command, it's an option to the login shell. And most shells take a -c option to specify a command to execute.

Need script to continue when switching over to new user

SO I have this script that will ssh you onto a new system, switch into a new user, and then I need it to execute three more commands while under that user. This is how I have it setup right now.
ssh -t $7 'cd /home/install/ ; su -c bash install ; tar -xvf [tarball] ; cd [directory] ; ./execute install ; bash'
What it will do is switch my user to the install user, but once there it doesn't execute any of the following commands. Only after I exit out of the install and back into the root user will those final commands run.
So for a tldr; I need a way to run those last three commands as the install user.
Thank you for your time! :)
You have two problems:
1. Your quotes are getting interpreted away
2. You're not using su correctly
If you want su to execute commands as that user, you have to provide them in STDIN, e.g. echo 'cd; ls' | su user. However, to do that, you're going to need to escape some stuff.
If the command you want to run as the user install is:
cmd1; cmd2; cmd3
Therefore, you provide it to su like so:
echo 'cmd1; cmd2; cmd3' | su install
However, you also want to execute it over ssh, which means you have to escape the quotes in the first sequence:
ssh user#host 'echo \'cmd1; cmd2; cmd3\' | su install'
Use sudo instead of su, that is what you need really.

Resources