Скрипт для SSH и запуска команды не работает


10

Ниже приведен сценарий.

Я хотел войти на несколько серверов и проверить версию ядра.

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done

Я ожидаю, что выходной, который идет как ..

server1_hostname
kernel_version
server2_hostname
kernel_version

и так далее..

Я запустил этот скрипт с около 80 серверов в server.txt

И результат, который я получил, был как .....

Pseudo-terminal will not be allocated because stdin is not a terminal. 
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

========================================================================
================================ WARNING ===============================
========================================================================
This system is solely for the use of authorized personnel. Individuals
using this system are subject to having some or all of their activities
monitored and recorded. Anyone using this system expressly consents to
such monitoring and is advised that any unauthorized or improper use of
this system may result in disciplinary action up to and including
termination of employment. Violators may also be subject to civil and/or
criminal penalties.
========================================================================

Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell.
xxxxdev01
2.6.32-431.23.3.el6.x86_64
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

Здесь я получил вывод только для 1 хоста, который xxxxdev01также поставляется с баннером ssh и другим предупреждением.

Мне нужен вывод всех других хостов и без ssh-баннера .. Что здесь не так?


Что произойдет, если вы используете один из серверов вручную и запустите sshpass -p password root@server histname?
Тердон

1
Используйте ssh -t -t root@..., чтобы вызвать псевдо-терминал.
garethTheRed

Ответы:


11

Я не могу сказать вам , почему вы не получаете ожидаемый результат от hostnameи unameкоманд, но я могу помочь постороннему тексту.

Строки «псевдотерминала» печатаются, sshпотому что он пытается выделить TTY по умолчанию, когда в командной строке не было предоставлено ни одной команды для выполнения. Вы можете избежать этого сообщения, добавив «-T» к команде ssh:

sshpass -p password ssh -T root@$line

Строка «Предупреждение: нет доступа к tty» поступает из оболочки удаленной системы. cshи tcshнапечатает это сообщение при определенных обстоятельствах. Возможно, это вызвано чем-то в этом .cshrcили аналогичном файле на удаленной системе, пытаясь получить доступ к некоторой функции, которая требует TTY.


4

Используйте следующий код,

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
  sshpass -p password ssh root@$line 'hostname;uname -r'
done

Это то, что я попробовал первым. Но это не дает мне ожидаемый результат.
Быть Гокулом

1

Если ваши хосты хранятся в следующем порядке server.txt

host1.tld
host2.tld
....

Вы можете

mapfile -t myhosts < server.txt; for host in "${myhosts[@]}"; do ssh username@"$host" 'hostname;uname -r'; done

1

Stdin не доступен для ваших удаленных команд. Что вы можете сделать, это использовать флаг "-s" bash для чтения команд из stdin:

Из руководства по bash:

-s        If the -s option is present, or if no arguments remain after
          option processing, then commands are read from the standard 
          input.  This option allows the positional parameters to be set
          when  invoking  an  interactive shell.

Так что это должно делать то, что вы хотите:

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
    sshpass -p password ssh root@$line bash -s << EOF
hostname
uname -r
EOF
done

Смотрите также: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine


1

Это прекрасно работает для меня:

 # cat hostsname.txt 
operation01  172.20.68.37 5fDviDEwew
ngx-gw01     172.20.68.36 FiPp2UpRyu
gateway01    172.20.68.35 KeMbe57zzb
vehicle01    172.20.68.34 FElJ3ArM0m

# cat hostsname.txt | while read hostname ipaddr passwd; do sshpass -p $passwd /usr/bin/ssh-copy-id $ipaddr;done

обратите внимание, что используйте -t -tвместо того, -Tчтобы избежать ошибки

Псевдо-терминал не будет выделен, потому что stdin не является терминалом


1
Вы должны прочитать о форматировании. Ваш ответ может быть отличным, но сейчас он почти не читается.
Ройма

0

Я полагаю, что SSH в то же время съесть все остальное в stdin. Вы можете обратиться к Bash FAQ 89 за подробностями. С FileDescriptor следующие коды должны работать как вы ожидаете.

while read line <& 7
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done 7< server.txt

альтернативный способ - использовать / dev / null для ssh. FileDescriptor можно игнорировать. `пока читаю строку; do sshpass -p пароль ssh root @ $ line </ dev / null << EOF .... done <server.txt`
Леон Ванг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.