Running script with ssh - shell

I work with machine A and I want to run a script that exists in machine B.
I did the ordinary command:
ssh user#machine_B_adress '. script.sh'
the problem is that I used in the script some commands that cannot be interpret with machine A. So I get command not found: (for example)
ksh: sqlplus: not found
I tried to open a shh by:
ssh user#machine_B_adress
and then run the script, it works!!!

Assuming that the shell for user#machine_B is bash, the first example 'ssh user#machine_B_adress '. script.sh', bash sets up the shell env differently for interactive/non-interactive sessions.
See man bash about interactive shells
Looks like you can emulate the interactive environment by adding a bash -l -c
$ ssh user#machine_B_address "bash -l -c '. script.sh'
My quick test, I added debug echo to .bash_profile of the remote user
$ ssh foouser#jdsrpi1 "bash --login -c '. foo.sh'"
This is file .bash_profile
foouser
SHELL = /bin/bash
PATH = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
Similar scenario for ksh
$ ssh kshuser#jdsdrop1.jimsander.io "date"
Tue Apr 18 11:52:43 EDT 2017
$ ssh kshuser#jdsdrop1 "ksh -l -c date"
This is SHELL(/usr/bin/ksh) file .profile
Tue Apr 18 11:53:24 EDT 2017

Related

Run shell script in pod remotely openshift or kubernetes

I have one shell script I want to run that remotely in POD, how I can do that?
oc exec build-core-1-p4fr4 -- df -kh / <--- I want to use my script
any way to do this remotely, like we do
oc exec build-core-1-p4fr4 -- cat >> text << shell.sh <---- something like this
I checked oc rsh but didn't find anything specific there.
You can try the following command using -i option that allows to pass stdin to the container.
$ oc exec -i your_pod_name -- /bin/bash -s <<EOF
#!/bin/bash
date > /tmp/time
EOF
$ oc exec your_pod_name -- cat /tmp/time
Fri Nov 13 10:00:19 UTC 2020
$
Use oc exec -i to take script from stdin.
oc exec -i your_pod_name -- bash -s < your_script.sh

How to sudo su; then run command

Can anyone help me to to solve following issue
i need to ssh to another server by e.g. ubuntu user which has permission to run sudo su fore sure then execute pm2 restart command
full command look like this
#!/bin/sh
CMD="sudo su; pm2 restart 0; pm2 restart 1; exit;"
ssh -i somepemfile.pem ubuntu#1.1.1.1 $CMD
for example i can run normally any command with sudo
CMD="sudo /etc/init.d/apache2 restart"
but with sudo su case it somehow hang and do not response
Unless you have an unusual setup, you can't normally string su with other preceding commands like that. I would imagine it is running sudo su, then hanging in the root environment/session, because it's waiting for you to exit before preceding to the pm2 commands. Instead, I would consider something along the lines of this using the -c option:
CMD="sudo su -c 'pm2 restart 0; pm2 restart 1'"
ssh -i somepemfile.pem ubuntu#1.1.1.1 "$CMD"
As suggested in another answer, it would also probably be useful to encapsulate the $CMD variable in quotes in the ssh call.
su normally puts you in a sub shell which you can see by echoing the current PID (process id)
$ echo $$
94260
$ sudo echo $$
94260
$ sudo su
$ echo $$
94271
But to get around this you can pipe the commands you want to run to su like this
$ echo "whoami" | sudo su
root
And we run multiple commands
$ echo "uptime;whoami" | sudo su
11:29 up 8 days, 19:20, 4 users, load averages: 4.55 2.96 2.65
root
Now to make this work with ssh
$ ssh wderezin#localhost 'echo "uptime;whoami" | sudo su'
sudo: no tty present and no askpass program specified
Darn it, we need allocate a tty for the su command. Add the -t option which allocates a TTY during the remote execution.
$ ssh -t wderezin#localhost 'echo "uptime;whoami" | sudo su'
11:36 up 8 days, 19:26, 5 users, load averages: 2.97 2.97 2.76
root
Your command would look this
ssh -i somepemfile.pem ubuntu#1.1.1.1 'echo "pm2 restart 0; pm2 restart1" | sudo su'
Use -c option of su to specify the command
From man su
In particular, an argument of -c will cause the next argument to be treated as a command by most command interpreters. The command will be executed by the shell specified in
/etc/passwd for the target user.
CMD="sudo su -c \"pm2 restart 0; pm2 restart 1;\""
You need to quote the expansion so that the entire string is parsed on the remote end.
ssh -i somepemfile.pem ubuntu#1.1.1.1 "$CMD"
Otherwise, the expansion is subject to word splitting, and the remote shell gets a string which consists of the command sudo and the arguments su;, restart, 0;, pm2, restart;, 1;, and exit;. That is, ssh will escape the semicolons when it builds a single string from the separate arguments you pass.
However, that doesn't solve the problem of running pm2 in the shell started by sudo. That is addressed by ramki.

No output from bash -c over ssh

How come when I run this on my local machine I get output
$ bash -c 'a=$(date) && echo $a'
Thu Feb 20 23:12:26 MST 2014
but if I try it over ssh (I have a public key on the other box, but no forced commands in authorized_keys)
$ ssh nathan#gnunix bash -c 'a=$(date) && echo $a'
Just a blank line is printed?
You don't need bash -c probably, just this would be able to print date:
ssh nathan#gnunix 'a=$(date) && echo $a'
If you must use bash -c then escape $ like this (otherwise $ is interpreted by current shell not remote one)
ssh nathan#gnunix "bash -c 'a=\$(date) && echo \$a'"
Fri Feb 21 01:22:42 EST 2014

shell script to run multiple scripts from different shells

I want to run 2 different scripts from a single master shell script.
The first one uses the following command "rosh -n -l abcd" (It will log me in to the server with the user abcd and on the same shell I need to run the other script#2 and script#3 ...etc.)
Script#2- From there I need to change user using su - xyz and provide a password (it is fine if I can hardcode this in the file) (Script name is logintoServer)
Script#3- Run some script in the same shell to verify start of stop of server...
I have done the following but failed
I have one script which has rosh -n <servername> -l abcd /bin/sh -c "su - xyz" (I have to run this command in the same shell)
The below are the errors:
I am getting error while executing "standard in must be a tty"
I have tried to create 2 different scripts and run, but the problem is once the first script is run it does not run the 2nd script till I exit the script. (I need to run the 2nd script from the sub-shell created by the 1st script....)
I don't have rosh and I don't have a man page for rosh but a similar problem exists with ssh:
ssh localhost /bin/bash -c 'echo x' # (prints nothing)
ssh localhost "/bin/bash -c 'echo x'" # x
ssh localhost "/bin/bash -c 'tty'" # not a tty
ssh -t localhost "/bin/bash -c 'tty'" # /dev/pts/12\nConnection to localhost closed.
ssh localhost "/bin/bash -c 'su - $USER'" # su: must be run from a terminal
ssh -t localhost "/bin/bash -c 'su - $USER'"
the last asked for a password and then gave me a shell, so that would be 2 of 3 steps.
so one idea is to see if rosh has the -t option, too and the other is to enclose /bin/bash... with quotes, too (will require some escaping for the 3rd level).
What does rosh say with equivalent commands?
UPDATE
latest state:
rosh -n $host -l abcd -t "/bin/sh -c 'su - $user'"
Next I would save one step by saying /bin/su - xyz instead /bin/sh -c 'su - xyz', then you can use single quotes later, e.g.
rosh -n $host -l abcd -t "/bin/su - $user -c 'echo $PATH'"
this should print $PATH as seen by the echo command. Apparently it doesn't contain java. try man su, which java, man which.
su ... -c cmd runs cmd with the shell specified in /etc/passwd, so say </etc/passwd grep $user on the remote machine to find out which shell is used. if it's bash you can change $PATH in .bashrc or so, for other shells I don't know exactly.
Or specify an absolute path when launching java.
regarding password: with ssh I managed to use private key / public key and ssh-agent. For rosh I don't know if that works, too.

running multiple commands through ssh and storing the outputs in different files

i've set up my public and private keys and have automated ssh login. I want to execute two commands say command1 and command2 in one login session and store them in files command1.txt and command2.txt on the local machine.
i'm using this code
ssh -i my_key user#ip 'command1 command2' and the two commands get executed in one login but i have no clue as to how to store them in 2 different files.
I want to do so because i dont want to repeatedly ssh into my remote host.
Unless you can parse the actual outputs of the two commands and distinguish which is which, you can't. You will need two separate ssh sessions:
ssh -i my_key user#ip command1 > command1.txt
ssh -i my_key user#ip command2 > command2.txt
You could also redirect the outputs to files on the remote machine and then copy them to your local machine:
ssh -i my_key user#ip 'command1 > command1.txt; command2 > command2.txt'
scp -i my_key user#ip:'command*.txt' .
NO, you will have to do it separately in separate command (multiple login) as already mentioned by #lanzz. To save the output in local, do like
ssh -i my_key user#ip "command1" > .\file_on_local_host.txt
In case, you want to run multiple command in a single login, then jot all your command in a script and then run that script through SSH, instead running multiple command.
It's possible, but probably more trouble than it's worth. If you can generate a unique string that is guaranteed not to be in the output of command1, you can do:
$ ssh remote 'cmd1; echo unique string; cmd2' |
awk '/^unique string$/ { output="cmd2"; next } { print > output }' output=cmd1
This simply starts printing to the file cmd1, and then changes output to the file cmd2 when it sees the unique string. You'll probably want to handle stderr as well. That's left as an exercise for the reader.
option 1. Tell your boss he's being silly. Unless, of course, he isn't and there is critical reason of needing it all in one session. For some reason such a case escapes my imagination.
option 2. why not tar?
ssh -i my_key user#ip 'command1 > out1; command2 > out2; tar cf - out*' | tar xf -
You can do this. Assuming you can set up authentication from the remote machine back to the local machine, you can use ssh to pipe the output of the commands back. The trick is getting the backslashes right.
ssh remotehost command1 \| ssh localhost cat \\\> command1.txt \; command2 \| ssh localhost cat \\\> command2.txt
Or if you aren't so into backslashes...
ssh remotehost 'command1 | ssh localhost cat \> command1.txt ; command2 | ssh localhost cat \> command2.txt'
join them using && so you can have it like this
ssh -i my_key user#ip "command1 > command1.txt && command2 > command2.txt && command3 > command3.txt"
Hope this helps
I was able to, here's exactly what I did:
ssh root#your_host "netstat -an;hostname;uname -a"
This performs the commands in order and cat'd them onto my screen perfectly.
Make sure you start and finish with the quotation marks, else it'll run the first command remotely then run the remainder of the commands against your local machine.
I have an rsa key pair to my server, so if you want to avoid credential check then obviously you have to make that pair.
I think this is what you need:
At first you need to install sshpass on your machine.
then you can write your own script:
while read pass port user ip; do
sshpass -p$pass ssh -p $port $user#$ip <<ENDSSH1
COMMAND 1 > file1
.
.
.
COMMAND n > file2
ENDSSH1
done <<____HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
____HERE
How to run multiple command on remote server using single ssh conection.
[root#nismaster ~]# ssh 192.168.122.169 "uname -a;hostname"
root#192.168.122.169's password:
Linux nisclient2 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:54 EDT 2009 i686 i686 i386 GNU/Linux
nisclient2
OR
[root#nismaster ~]# ssh 192.168.122.169 "uname -a && hostname"
root#192.168.122.169's password:
Linux nisclient2 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:54 EDT 2009 i686 i686 i386 GNU/Linux
nisclient2

Resources