Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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 .

  1. I want to run ls -l /etc/foobar on each host in the list.
  2. If this file exists on that host, then print the hostname and the output of the command.
  3. 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"
    echo "### $HOST"
    ssh $HOST "ls -ld /etc/foobar"

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 and ssh, 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"
    # 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
share|improve this question
Avoid 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. – jw013 Apr 11 '12 at 1:15
@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 – Stefan Lasiewski Apr 11 '12 at 17:38
Not really, just the folk wisdom of #bash and the fact that all the variables that are special to the shell have uppercase names. – jw013 Apr 11 '12 at 17:42
Here's a source from the Wooledge Wiki. – jw013 Apr 11 '12 at 18:45

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:


pssh -h hosts_file "COMMAND"

in you example it will be

pssh -h hosts_file "ls -l /etc/foobar"
share|improve this answer
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"
share|improve this answer

This worked for me:

for HOST in $HOSTLIST; do
  ssh $HOST '[ -f /etc/passwd ] && echo $(hostname) has file'
share|improve this answer

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; }
share|improve this answer
for host in host1 host2 host3 ;do ssh $host 'echo -n "[$(hostname -s)]"; /sbin/ifconfig |grep Bcast' ;done

[host1] inet addr:xxx.xxx.138.30 Bcast:xxx.xxx.143.255 Mask: [host2] inet addr:xxx.xxx.138.14 Bcast:xxx.xxx.143.255 Mask: [host3] inet addr:xxx.xxx.82.146 Bcast:xxx.xxx.82.255 Mask:

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.