ssh to server, run commands and save output of commands on local machine using shell - bash

#!/bin/sh
ssh [username]#[ip] "bash -s" <<EOF
if [condition]
then
echo "success"
else
echo "failure"
fi
EOF
After running these commands, I want to save the result (ie success/failure) in a file on local machine. How do I go about it?

Good to try is the IO redirection:
ssh [username]#[ip] "bash -s" > file.txt <<EOF
[...]

Exit status of ssh is the exit status of the remote command so this should work:
( ssh [username]#[ip] [command] && echo success || echo failure ) > result.txt

Related

SSH not exiting properly inside if statement in bash heredoc

So i am running this script to check if a java server is up remotely by sshing into remote. If it is down, i am trying to exit and run another script locally. However, after the exit command, it is still in the remote directory.
ssh -i ec2-user#$DNS << EOF
if ! lsof -i | grep -q java ; then
echo "java server stopped running"
# want to exit ssh
exit
# after here when i check it is still in ssh
# I want to run another script locally in the same directory as the current script
./other_script.sh
else
echo "java server up"
fi;
EOF
The exit is exiting the ssh session and so never gets to the execution of the other_script.sh line in the HEREDOC. It would be better to place this outside of the script and actioned from the exit status of the HEREDOC/ssh and so:
ssh -i ec2-user#$DNS << EOF
if ! lsof -i | grep -q java ; then
echo "java server stopped running"
exit 7 # Set the exit status to a number that isn't standard in case ssh fails
else
echo "java server up"
fi;
EOF
if [[ $? -eq 7 ]]
then
./other_script.sh
fi

Bash script catch exit code of another bash script over ssh

I'm writing a script execute.sh that ssh to other host and execute bash script from another file. The problem is I don't know how to catch exit code of the file I executed.
My execute.sh is like this:
ssh $REMOTE_USER#$REMOTE_HOST 'bash -s' < ./onvps.sh
and I want execute.sh catch exit code of onvps.sh.
Thank you all.
As the ssh client will exit with the exit code of the remote command, you can check the value of $?. if it return 0, it indicates that command is executed successfully.
in your case
ssh $REMOTE_USER#$REMOTE_HOST 'bash -s' < ./onvps.sh
return_code=$?
# then evaluate
if [ $return_code -eq 0 ]
then
echo "OK"
else
echo "ERROR"
fi
One example
$ more mytest.sh
exit 22
$ ssh myuser#myhost 'bash -s' < ./mytest.sh
$ echo $?
22
whatever you are including in the script will be executed in the remote, so $? will give you the exit code of it.

How to get return status of a command in subshell into the main shell?

I want to retrieve the return status of a command which is being executed in a subshell.
I am running the below script from Unix Box A which has a passwordless SSH access to Box B whose IP is mentioned in the script as ip_addr.
I want to get the return status of command which is ran in subshell in my current environment.
That is if the below command fails:
echo "cmd" | system_program> 2>> /dev/null
then echo $? should print non-zero value and I should be able to use that value to decide further action.
Snippet of my script is:
sample.sh :
ip_addr="xxx.xxx.xx.xx"
status=$(ssh -q -T $ip_addr << EOF
rm /tmp/program.log; echo "cmd" | system_program> 2>> /dev/null; echo $?
EOF
)
You don't need the here-doc, or the echo. Try:
ssh -q -T $ip_addr 'rm /tmp/program.log; echo "cmd" | system_program> 2>> /dev/null'
Or if you want to use here-doc set errexit:
status=$(ssh -q -T $ip_addr << EOF
set -o errexit
rm /tmp/program.log; echo "cmd" | system_program> 2>> /dev/null
EOF
)

ssh script doesn't return control to the parent script

I am trying to execute a local script on the remote server, by writing it to standard input of an ssh command. The script runs fine, but then ssh doesn't exit: it just hangs, and control doesn't return to the parent script.
Parent Shell :
for HOSTNAME in ${HOSTS} ; do
ssh -t -t $HOSTNAME "bash -s" < ~backup_conf.sh
done
Called Script:
#!/bin/sh
AGENT_BASE_PATH=/home/lokesh
if [ -d "$AGENT_BASE_PATH/CI/DE_deployment/conf" ]; then
if [ -d "$AGENT_BASE_PATH/CI/temp/conf_bkup" ]; then
rm -rf $AGENT_BASE_PATH/CI/temp/conf_bkup
fi
cp -R $AGENT_BASE_PATH/CI/DE_deployment/conf $AGENT_BASE_PATH/CI/temp/conf_bkup
fi
exit
I have written 'exit' but the control is not returning back to the parent script.
It hangs at the remote server.... :(
Culprit is bash -s line in your calling code, which is still expecting input to be ended using ctrl-C:
Try this instead:
for HOSTNAME in ${HOSTS} ; do
ssh -t -t $HOSTNAME "bash ~backup_conf.sh"
done
write your exit - status into a file on the remote host and pick it later from the remote host with ssh/scp/sftp.
Direct via ssh you will not get a exit - status from the other host.

Checking SSH failure in a script

Hi what is the best way to check to see if SSH fails for whatever reason?
Can I use a IF statement ( if it fails then do something)
I'm using the ssh command in a loop and passing my hosts names form a flat file.
so I do something like:
for i in `cat /tmp/hosts` ; do ssh $i 'hostname;sudo ethtool eth1'; done
I get sometime this error or I just cannot connect
ssh: host1 Temporary failure in name resolution
I want to skip the hosts that I cannot connect to is SSH fails. What is the best way to do this? Is there a runtime error I can trap to bypass the hosts that I cannot ssh into for whatever reason, perhaps ssh is not allowed or I do not have the right password ?
Thanking you in advance
Cheers
To check if there was a problem connecting and/or running the remote command:
if ! ssh host command
then
echo "SSH connection or remote command failed"
fi
To check if there was a problem connecting, regardless of success of the remote command (unless it happens to return status 255, which is rare):
if ssh host command; [ $? -eq 255 ]
then
echo "SSH connection failed"
fi
Applied to your example, this would be:
for i in `cat /tmp/hosts` ;
do
if ! ssh $i 'hostname;sudo ethtool eth1';
then
echo "Connection or remote command on $i failed";
fi
done
You can check the return value that ssh gives you as originally shown here:
How to create a bash script to check the SSH connection?
$ ssh -q user#downhost exit
$ echo $?
255
$ ssh -q user#uphost exit
$ echo $?
0
EDIT - I cheated and used nc
Something like this:
#!/bin/bash
ssh_port_is_open() { nc -z ${1:?hostname} 22 > /dev/null; }
for host in `cat /tmp/hosts` ; do
if ssh_port_is_open $host; then
ssh -o "BatchMode=yes" $i 'hostname; sudo ethtool eth1';
else
echo " $i Down"
fi
done

Resources