Executar um comando em vários hosts, mas apenas imprimir o comando se for bem-sucedido?

Executar um comando em vários hosts, mas apenas imprimir o comando se for bem-sucedido?

Aqui está o que eu quero fazer.

Quero verificar mais de 100 hosts e ver se existe um arquivo nesse host. Se o arquivo existir, quero imprimir o nome do host e a saída do comando.

Neste exemplo, suponha que eu tenha três hosts: host1.example.org host2.example.org host3.example.org . O arquivo /etc/foobarexiste em host2.example.org, mas não em host1.example.org ou host3.example.org .

  1. Quero executar ls -l /etc/foobarem cada host da lista.
  2. Se este arquivo existir nesse host, imprima o nome do host e a saída do comando.
  3. Se o arquivo não existir nesse host, não imprima nada. Não quero barulho extra.
HOSTLIST="host1.example.org host2.example.org host3.example.org"
for HOST in $HOSTLIST
do
    echo "### $HOST"
    ssh $HOST "ls -ld /etc/foobar"
done

A saída ideal seria:

### host2.example.org
drwx------ 3 root root 4096 Apr 10 16:57 /etc/foobar

Mas a saída real é:

### host1.example.org
### host2.example.org
drwx------ 3 root root 4096 Apr 10 16:57 /etc/foobar
### host3.example.org

Não quero que as linhas host1.example.org ou host3.example.org sejam impressas.

Estou experimentando colchetes para conter a saída cuspida por echoand ssh, mas não consigo descobrir a sintaxe mágica para fazer o que quero. Tenho certeza de que já fiz isso no passado sem personagens de controle,

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

Responder1

nesta edição eu recomendo usarpssh. Thx pssh, você pode executar facilmente o comando em muitos servidores remotos ao mesmo tempo.

coloque o host em (ou seja, hosts_file) - cada servidor em 1 linha como:
host1.tld
host2.tld

Uso:

pssh -h hosts_file "COMMAND"

no seu exemplo será

pssh -h hosts_file "ls -l /etc/foobar"

Responder2

Isso funcionou para mim:

for HOST in $HOSTLIST; do
  ssh $HOST '[ -f /etc/passwd ] && echo $(hostname) has file'
done

Responder3

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

Responder4

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:255.255.248.0 [host2] inet addr:xxx.xxx.138.14 Bcast:xxx.xxx.143.255 Mask:255.255.248.0 [host3] inet addr:xxx.xxx.82.146 Bcast:xxx.xxx.82.255 Mask:255.255.255.128

informação relacionada