Execute a command on multiple hosts, but only print command if it is successful?
Solution 1
in this issue i recommend use pssh. Thx pssh you could very easy run command on many remote servers at once.
put host into (i.e hosts_file)- each server in 1 line like:
host1.tld
host2.tld
Usage:
pssh -h hosts_file "COMMAND"
in you example it will be
pssh -h hosts_file "ls -l /etc/foobar"
Solution 2
This worked for me:
for HOST in $HOSTLIST; do
ssh $HOST '[ -f /etc/passwd ] && echo $(hostname) has file'
done
Solution 3
Check out clusterssh
to easily execute a command on may systems. Be extremely careful with executing commands on so many systems at once, it you make a unfortunate typo all servers will be affected.
The command you want to execute would go something like (refer to bash manual page for details):
[ -e some_existing_file ] && { hostname; ls -l; }
Solution 4
set -- host1.example.org host2.example.org
for host; do
ssh "$host" sh -c '[ -e /etc/foobar ] && { printf %s\\n "$1"; ls -ld /etc/foobar; }' _ "$host"
done
Related videos on Youtube
Mark Norgren
Updated on September 18, 2022Comments
-
Mark Norgren almost 2 years
Here's what I want to do.
I want to check over 100 hosts and see if a file exists on that host. If the file does exist, then I want to print the hostname and the output of the command.
In this example example, assume that I have three hosts: host1.example.org host2.example.org host3.example.org . The file
/etc/foobar
exists on host2.example.org, but not on host1.example.org or host3.example.org .- I want to run
ls -l /etc/foobar
on each host in the list. - If this file exists on that host, then print the hostname and the output of the command.
- If the file does not exist on that host, then don't print anything. I don't want the extra noise.
HOSTLIST="host1.example.org host2.example.org host3.example.org" for HOST in $HOSTLIST do echo "### $HOST" ssh $HOST "ls -ld /etc/foobar" done
Ideal output would be:
### host2.example.org drwx------ 3 root root 4096 Apr 10 16:57 /etc/foobar
But the actual output is:
### host1.example.org ### host2.example.org drwx------ 3 root root 4096 Apr 10 16:57 /etc/foobar ### host3.example.org
I don't want the lines for host1.example.org or host3.example.org to print.
I am experimenting braces to contain the output spit out by
echo
andssh
, but I can't figure out the magic syntax to do what I want. I am sure that I have done this in the past without control characters,HOSTLIST="host1.example.org host2.example.org host3.example.org" for HOST in $HOSTLIST do # If 'ls' shows nothing, don't print $HOST or output of command # This doesn't work { echo "### $HOST" && ssh $HOST "ls -ld /etc/foobar" ; } 2>/dev/null done
-
jw013 about 12 yearsAvoid using all UPPERCASE variable names. Such names like
PAGER
,HOSTNAME
,PATH
, etc. are often reserved or may be reserved in the future by the shell for special purposes and clobbering them may have unintended side effects. -
Mark Norgren about 12 years@jw013 : Interesting. I thought that was just a convention. Do you have an authoritative source which recommends that I avoid all uppercase names, since it's not mentioned in the BASH manual
-
jw013 about 12 yearsNot really, just the folk wisdom of
#bash
and the fact that all the variables that are special to the shell have uppercase names. -
jw013 about 12 yearsHere's a source from the Wooledge Wiki.
-
rogerdpack over 6 years
- I want to run