¿Ejecutar un comando en varios hosts, pero solo imprimir el comando si tiene éxito?

¿Ejecutar un comando en varios hosts, pero solo imprimir el comando si tiene éxito?

Esto es lo que quiero hacer.

Quiero comprobar más de 100 hosts y ver si existe un archivo en ese host. Si el archivo existe, entonces quiero imprimir el nombre del host y el resultado del comando.

En este ejemplo, supongamos que tengo tres hosts: host1.example.org host2.example.org host3.example.org. El archivo /etc/foobarexiste en host2.example.org, pero no en host1.example.org o host3.example.org.

  1. Quiero ejecutar ls -l /etc/foobaren cada host de la lista.
  2. Si este archivo existe en ese host, imprima el nombre del host y el resultado del comando.
  3. Si el archivo no existe en ese host, no imprima nada. No quiero el ruido 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

El resultado ideal sería:

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

Pero el resultado real es:

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

No quiero que se impriman las líneas de host1.example.org o host3.example.org.

Estoy experimentando con llaves para contener la salida escupida por echoy ssh, pero no puedo encontrar la sintaxis mágica para hacer lo que quiero. Estoy seguro de que he hecho esto en el pasado sin personajes de control,

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

Respuesta1

en este número recomiendo usarpssh. Gracias pssh, podría ejecutar fácilmente el comando en muchos servidores remotos a la vez.

coloque el host en (es decir, hosts_file): cada servidor en 1 línea como:
host1.tld
host2.tld

Uso:

pssh -h hosts_file "COMMAND"

en tu ejemplo será

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

Respuesta2

Esto funcionó para mí:

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

Respuesta3

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

Respuesta4

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

información relacionada