Executar um comando em vários hosts, mas somente o comando de impressão se for bem sucedido?

4

Aqui está o que eu quero fazer.

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

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

  1. Desejo exibir ls -l /etc/foobar em cada host da lista.
  2. Se esse 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. Eu não quero o 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

Eu não quero que as linhas para host1.example.org ou host3.example.org sejam impressas.

Estou experimentando chaves para conter a saída cuspida por echo e ssh , mas não consigo descobrir a sintaxe mágica para fazer o que eu quero. Tenho certeza de que 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
    
por Stefan Lasiewski 11.04.2012 / 02:54

5 respostas

5

Nesta edição, eu recomendo usar pssh . Thx pssh você pode muito facilmente executar o comando em muitos servidores remotos de uma só vez.

colocar host em (ou seja, hosts_file) - cada servidor em uma linha como:
host1.tld
host2.tld

Uso:

pssh -h hosts_file "COMMAND"

no seu exemplo, será

pssh -h hosts_file "ls -l /etc/foobar"
    
por 07.04.2014 / 19:34
2

Isso funcionou para mim:

for HOST in $HOSTLIST; do
  ssh $HOST '[ -f /etc/passwd ] && echo $(hostname) has file'
done
    
por 11.04.2012 / 03:08
1
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
    
por 11.04.2012 / 03:08
1

Confira clusterssh para executar facilmente um comando em sistemas de maio. Seja extremamente cuidadoso ao executar comandos em tantos sistemas de uma só vez, você faz um erro de digitação infeliz que todos os servidores serão afetados.

O comando que você quer executar seria algo como (consulte a página de manual do bash para detalhes):

[ -e some_existing_file ] && { hostname; ls -l; }
    
por 11.04.2012 / 08:45
0
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

    
por 07.04.2014 / 14:53