Bash | ssh return value [duplicate] - linux

This question already has answers here:
How to create a bash script to check the SSH connection?
(14 answers)
Closed 1 year ago.
I am writing a bash script that goes through a number of hosts defined in hosts.list and returns if they are online.
I would like to do the same but with ssh. How to I return a value from ssh like boolean if the connection and login was successful.
#!/bin/bash
File="hosts.list"
Hosts=$(cat $File)
declare -i deadhosts
$deadhosts = 0
declare -i counter
$counter = 0
for Host in $Hosts
do
if ! ping -c 1 -s 1 -W 1 "$Host" 1>/dev/null 2>&1; then
deadhosts=$((deadhosts+1))
else
echo $Host
fi
counter=$((counter+1))
done
echo "Mission success"
echo "Scanned Hosts: $counter Dead Hosts: $deadhosts"

There is a question that was ask for the same thing:
How to create a bash script to check the SSH connection?
And you can also find information there:
https://www.golinuxcloud.com/test-ssh-connection/

Related

My script is working fine butit is not taking next server from the server list [duplicate]

This question already has answers here:
While loop stops reading after the first line in Bash
(5 answers)
Closed yesterday.
My script is working fine butit is not taking next server from the server list
#!/bin/bash
# Read in server names from afile
while read -r server; do
# Check if server is reachable
if ping -c 1 "$server" &> /dev/nul l; then
echo "Server $server is reachable."
# Check if mount point exists
if ssh "$server" "[ -d /path/to/mount/point ]"; then
echo "Mount point exists on server $server."
else
echo "Mount point does not exist on server $server."
fi
else
echo "Server $server is not reachable."
fi
done < servers.txt
For an example 192.168.0.1 and 192.168.0.2 is there in server list file .but it is showing output for 192.168.0.1 . It is not showing output for 192.168.0.2
As pointed out in the comments section, ssh command is consuming your script stdin.
Add -n option to ssh should prevent this (see this).
So change this line:
if ssh "$server" "[ -d /path/to/mount/point ]"; then
To:
if ssh -n "$server" "[ -d /path/to/mount/point ]"; then

SSH Remote command exit code

I know there are lots of discussions about it but i need you help with ssh remote command exit codes. I have that code:
(scan is a script which scans for viruses in the given file)
for i in $FILES
do
RET_CODE=$(ssh $SSH_OPT $HOST "scan $i; echo $?")
if [ $? -eq 0 ]; then
SOME_CODE
The scan works and it returns either 0 or (1 for errors) or 2 if a virus is found. But somehow my return code is always 0. Even, if i scan a virus.
Here is set -x output:
++ ssh -i /home/USER/.ssh/id host 'scan Downloads/eicar.com; echo 0'
+ RET_CODE='File Downloads/eicar.com: VIRUS: Virus found.
code of the Eicar-Test-Signature virus
0'
Here is the Output if i run those commands on the "remote" machine without ssh:
[user#ws ~]$ scan eicar.com; echo $?
File eicar.com: VIRUS: Virus found.
code of the Eicar-Test-Signature virus
2
I just want to have the return Code, i dont need all the other output of scan.
!UPDATE!
It seems like, echo is the problem.
The reason your ssh is always returning 0 is because the final echo command is always succeeding! If you want to get the return code from scan, either remove the echo or assign it to a variable and use exit. On my system:
$ ssh host 'false'
$ echo $?
1
$ ssh host 'false; echo $?'
1
$ echo $?
0
$ ssh host 'false; ret=$?; echo $ret; exit $ret'
1
$ echo $?
1
ssh returns the exit status of the entire pipeline that it runs - in this case, that's the exit status of echo $?.
What you want to do is simply use the ssh result directly (since you say that you don't want any of the output):
for i in $FILES
do
if ssh $SSH_OPT $HOST "scan $i >/dev/lull 2>&1"
then
SOME_CODE
If you really feel you must print the return code, that you can do that without affecting the overall result by using an EXIT trap:
for i in $FILES
do
if ssh $SSH_OPT $HOST "trap 'echo \$?' EXIT; scan $i >/dev/lull 2>&1"
then
SOME_CODE
Demo:
$ ssh $host "trap 'echo \$?' EXIT; true"; echo $?
0
0
$ ssh $host "trap 'echo \$?' EXIT; false"; echo $?
1
1
BTW, I recommend you avoid uppercase variable names in your scripts - those are normally used for environment variables that change the behaviour of programs.

How to send email from remote server for particular user via unix shell script [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I need to send mail to a particular user from host computer via shell script using command line argument.Mail should go to that particular user only.
Script execution will be like ./tesh.sh user emailid
cat test.sh
#!/bin/sh
export user=$1
export email=$2
list=`echo "$(cat ip.txt)"`
script=$(cat remote_cmds.sh)
for ip in ${list[#]} ; do
echo "***";
echo "IP: $ip"
ssh -o StrictHostKeyChecking=no -l ${user} ${ip} ${script}
done
# cat remote_cmds.sh
source pathto/test.sh
echo "";
echo "****Hostname****";
echo "`hostname`";
echo "";
echo "****Disk Allocated****";
echo "`df -h`";
echo "";
echo "****Ram Allocated****";
echo testmail | mailx -s "Testmail" $email
If I understand you correctly you have N computers with ip addresses saved in ip.txt. Each of these computers has a user named 'user' to which you can login via ssh. Each of these computers has a user named 'emailid' to which you want to send mail. You want to use ssh session to connect to these computers and run mail client on these computers. You want to print some information about hostname, disc space and some other infos from the remote computers on your computer and send simple mail with subject 'Testmail' and content 'testmail' to the local user 'emaillid' on these remote N computers.
These scripts are not good. Doing script=$(cat remote_cmds.sh) and then calling ssh ... ${scripts} is so dangerous... The line list=echo "$(cat ip.txt)" can be just shortened to list=$(cat ip.txt). list variable is not an array, so doing ${list[#]} is the same as $list. remote_cmds.sh has the line source pathto/test.sh, so that means that each of N computers has a test.sh file in the same path?
mailx is giving you arror, cause you are executing (literally) mailx -s Testmail $email and email address can't have $ characters (the email variable is not expanded).
Try smth like this:
test.sh
#!/bin/sh
# export is not needed anywhere here
user=$1
email=$2
# loop through the lines in ip.txt
cat ip.txt | while read ip; do
echo "***";
echo "IP: $ip"
# https://unix.stackexchange.com/questions/87405/how-can-i-execute-local-script-on-remote-machine-and-include-arguments
# login on computer with ip $ip on user $user and execute command on
# remote host 'bash -s', which will read commands from standard input,
# append our remote_cmds.sh script to stdin and pass "$email" as first
# argument to this script
ssh -o StrictHostKeyChecking=no -l "$user" "$ip" bash -c -- < remote_cmds.sh "$email"
done
# this loop is bad and inefficient, but it's safe and simple to write
# see https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
remote_cmds.sh
#!/bin/sh
# these lines will be executed on N computers
# email is passed as first argument to this script
email=$1
echo "";
echo "****Hostname****";
hostname
echo "";
echo "****Disk Allocated****";
df -h
echo "";
echo "****Ram Allocated****";
free -h # ;)
echo testmail | mailx -s "Testmail" "$email"

Bash exit status when using while loop [duplicate]

This question already has answers here:
How to get the exit status a loop in bash
(8 answers)
Closed 7 years ago.
I have a bash script that goes through a list of ip's and pings them one by one. If the exit status for each ping is 0, then echo that the node is up, else the node is down.I am able to get this to work perfectly, but when the bash script ends the exit status is always 0.
What I am trying to achieve is for example out of 5 ip's if the 3rd one fails, to continue through the list and check the rest but once the script ends throw an exit status other than 0 and output which ip has failed.
cat list.txt | while read -r output
do
ping -o -c 3 -t 3000 "$output" > /dev/null
if [ $? -eq 0 ]; then
echo "node $output is up"
else
echo "node $output is down"
fi
done
thanks in advance!
Your first problem is that by doing cat file | while read you've spawned the while in its own subshell. Any variables it sets will only exist during that loop, so persisting a value will be difficult. More info on that issue here.
If you use while read ... done < file it will work correctly. Make an exit status flag that defaults to zero, but set it to one if any errors occur. Use it as your script's exit value.
had_errors=0
while read -r output
do
ping -o -c 3 -t 3000 "$output" > /dev/null
if [ $? -eq 0 ]; then
echo "node $output is up"
else
echo "node $output is down"
had_errors=1
fi
done < list.txt
exit $had_errors

Check if i use sudo or su [duplicate]

This question already has answers here:
How to check if running as root in a bash script
(21 answers)
Closed 7 years ago.
I want a script shell make the user use su not sudo
I want a script check if i use sudo or su in my command, like :
if [ "$USER" != "root" -a "$0" = "sudo" ];then
echo "You have to run this script as a root \"Use : su \" "
fi
I know is wrong, can anybody help me ??
You can use the $EUID since the effective user id will always be 0 for sudo :)
Example:
#!/usr/bin/env bash
if [[ $EUID = 0 ]]; then
echo "sudo!"
else
echo "not sudo!"
fi
Edit:
above doesn't work, but if you just want to check this from a simple bash script you could do this hack:
#!/usr/bin/env bash
if [[ $EUID = 0 && "$(ps -o comm= | sed -n '1p')" = "su" ]]; then
echo "sudo!"
else
echo "not sudo!"
fi
Will obviously not recognize normal root shells, but actual su use is properly recognized. ( could break when called by another script :/ )
really dirty and not stable against nested su use (where sudo could still pass when ran from nested su) , it might suffice to do something like this:
#!/usr/bin/env bash
if [[ $EUID = 0 && "$(ps -o comm= | grep su | sed -n '1p')" = "su" ]]; then
echo "sudo!"
else
echo "not sudo!"
fi
... admittedly a solution from the (NOT OK!) category ...

Resources