bash script's question

nashrik

New Member
Joined
Mar 28, 2019
Messages
3
Reaction score
1
Credits
0
Hi everyone, I have problems with this script.
This script should check for a folder for each server in the list of the list.txt file.
The script only checks the first host, and then exits, why?

#!/bin/bash
file='/etc/list.txt'
while read line; do
echo $line
if ssh root@$line "stat /var > /dev/null 2>&1"; then
echo "File exists"
else
echo "File does not exist"
fi
done < $file

thank you very much for helping
n
 


G'day @nashrik and welcome to linux.org :)

I am moving this Thread to Command Line, where scripting questions are most often answered.

Good luck

Chris Turner
wizardfromoz
 
Hi everyone, I have problems with this script.
This script should check for a folder for each server in the list of the list.txt file.
The script only checks the first host, and then exits, why?

#!/bin/bash
file='/etc/list.txt'
while read line; do
echo $line
if ssh root@$line "stat /var > /dev/null 2>&1"; then
echo "File exists"
else
echo "File does not exist"
fi
done < $file

thank you very much for helping
n

I haven't used ssh for a long time, but if memory serves - I think you need to use the -n option.
Without it, ssh treats everything else in your script as input from stdin. Which is why in your script, the reason that only the first server is responding is because it's the only ssh session being fired off.
The rest of the script is being consumed as input to the initial ssh command..... I think!
Using the -n option should prevent ssh from hogging stdin and fix your problem.

Consider this slightly modified version of your script:
Code:
#!/usr/bin/env bash
file="/etc/list.txt"
while read host; do
    echo "$host"
    if ssh -n "root@$host" "stat /var > /dev/null 2>&1"; then
        echo "File exists"
    else
        echo "File does not exist"
    fi
done < "$file"

NOTES:
Above is your original script, but with some very pedantic, minor alterations.
- I renamed the variable $line to $host, to make it a bit clearer what each line in the file represented.
- I used double quotes every time we dereferenced a variable. I have a shellcheck plugin in vim which complains every time there are unquoted variables in a shell-script, so I automatically double quote them now. It's a habit!
- I changed the shebang line - because on some systems bash is in /bin/ and in others it's in /usr/bin/. This is just another habit I've picked up! There's nothing worse than trying to run one of your scripts on another machine and have it fail because the path to the interpreter was incorrect. So I always use "#!/usr/bin/env bash" in my scripts (Or "#!/usr/bin/env sh" for more generic, non-bash specific scripts). Let each system decide which bash (or shell) to run! Basically, I'm too lazy to have to edit the script each time I run it on a different machine! XD
- most importantly, I added the -n option to the ssh command.

Also, I haven't tested the script. I don't currently have ssh access to any servers, so I have no way to test it. So at the risk of ending up with egg on my face - I'll leave It to you to try!

And by all means, ignore most of my alterations. The the most important thing to try in your script is the ssh command's -n option. That should hopefully prevent the problem you were having!
 
Last edited:
I can't see any reason that loop wouldn't work unless it has to do with using root or prompting for the password or passphrase.

Why are you using root? If possible, you should use your normal unprivileged user.

If not using root, you might also want to consider the keychain package. It's in the repository for most distros. It'll prompt you for your SSH key passphrases once after boot and keep them in memory so you can use ssh without being prompted. That makes scripts like this work much smoother.

For example, this command works on my system, connecting to server 'asrol':
Code:
ssh asrol 'stat /var >/dev/null 2>&1' && echo yes
 
I can't see any reason that loop wouldn't work unless it has to do with using root or prompting for the password or passphrase.

Why are you using root? If possible, you should use your normal unprivileged user.

If not using root, you might also want to consider the keychain package. It's in the repository for most distros. It'll prompt you for your SSH key passphrases once after boot and keep them in memory so you can use ssh without being prompted. That makes scripts like this work much smoother.

For example, this command works on my system, connecting to server 'asrol':
Code:
ssh asrol 'stat /var >/dev/null 2>&1' && echo yes

That's a point - The OPs command that was being sent to each server was in double quotes wasn't it? Yours was in single quotes. Perhaps that's why the -n option was required? Do the single quotes around the command prevent ssh from hogging stdin, because the ssh's input is clearly delimited by the closing single quote? That may have been the problem all along!

Also, if the OP is being prompted for a password for each host (one would hope not!) - there is the -f option, which also enables the -n option - Again - if memory serves! I haven't actually used ssh since my previous job, 11 years ago! However, I was assuming that the OP was using stored credentials/cryptographic keys to connect to the servers!

There are also other solutions like pssh (parallel ssh) which allows multiple commands to be ran on multiple remote hosts.
I've never used it, but it was something I saw on tecmint a few years ago which looks simple enough to set up and use.
After searching my old bookmarks:
https://www.tecmint.com/execute-commands-on-multiple-linux-servers-using-pssh/
 
Yours was in single quotes.

For the example I posted, I don't think it makes any difference whether you use single of double quotes.

I also don't think you need -n because the stat command doesn't read any input, and it didn't look like the OP was putting the command in the background.

I use SSH routinely between my machines upstairs and downstairs. Ironically, I executed that command I posted in a shell via SSH to the upstairs machine, but it remotely accessed the machine I'm actually sitting in front of. Such fun.
 

Members online


Top