Выполнить команду на нескольких хостах, но вывести команду на печать только в случае ее успешного выполнения?

Выполнить команду на нескольких хостах, но вывести команду на печать только в случае ее успешного выполнения?

Вот что я хочу сделать.

Я хочу проверить более 100 хостов и посмотреть, существует ли файл на этом хосте. Если файл существует, то я хочу вывести имя хоста и вывод команды.

В этом примере предположим, что у меня есть три хоста: host1.example.org host2.example.org host3.example.org . Файл /etc/foobarсуществует на host2.example.org, но не на host1.example.org или host3.example.org .

  1. Я хочу запустить ls -l /etc/foobarна каждом хосте из списка.
  2. Если этот файл существует на этом хосте, выведите имя хоста и вывод команды.
  3. Если файл не существует на этом хосте, то ничего не печатайте. Мне не нужен лишний шум.
HOSTLIST="host1.example.org host2.example.org host3.example.org"
for HOST in $HOSTLIST
do
    echo "### $HOST"
    ssh $HOST "ls -ld /etc/foobar"
done

Идеальный результат был бы таким:

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

Но фактический результат таков:

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

Я не хочу, чтобы печатались строки host1.example.org или host3.example.org.

Я экспериментирую со скобками, чтобы сдержать вывод, выдаваемый echoи ssh, но не могу понять магический синтаксис, чтобы сделать то, что я хочу. Я уверен, что я делал это в прошлом без управляющих символов,

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

решение1

в этом выпуске я рекомендую использоватьпсш. Спасибо pssh, ты можешь очень легко запускать команды на многих удаленных серверах одновременно.

поместите хост в (т.е. hosts_file) - каждый сервер в 1 строке, например:
host1.tld
host2.tld

Использование:

pssh -h hosts_file "COMMAND"

в вашем примере это будет

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

решение2

Мне это помогло:

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

решение3

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

решение4

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

Связанный контент