web-dev-qa-db-ja.com

sshしてコマンドを実行するスクリプトが機能しない

以下はスクリプトです。

複数のサーバーにログインして、カーネルのバージョンを確認したいと思っていました。

#!/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

等々..

Server.txtの約80台のサーバーでこのスクリプトを実行しました

そして、私が得た出力は...

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バナーなしの出力が必要です。ここで何が問題になっていますか?

10
Being Gokul

hostnameコマンドとunameコマンドから予期した出力が得られない理由はわかりませんが、無関係なテキストについてはお手伝いできます。

コマンドラインに実行するコマンドが指定されていない場合、デフォルトでTTYを割り当てようとするため、「疑似ターミナル」行はsshによって出力されます。 sshコマンドに「-T」を追加することで、このメッセージを回避できます。

sshpass -p password ssh -T root@$line

"Warning:no access to tty"行がリモートシステムのシェルから送られています。 cshおよびtcshは、特定の状況下でそのメッセージを出力します。リモートシステムの.cshrcまたは同様のファイルの何かが原因で、TTYを必要とする機能にアクセスしようとしている可能性があります。

11
Kenster

次のコードを使用して、

#!/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
4
msnfreaky

Stdinにはリモートコマンドからアクセスできません。あなたができることは、bdinの "-s"フラグを使って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

参照: https://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-Shell-script-on-a-remote-machine

1
nimai

これは私にとってはうまくいきます:

 # 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
Valiant Jiang

ホストがserver.txtに次のように保存されている場合

Host1.tld
Host2.tld
....

あなたはできる

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

しばらくの間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
0
Leon Wang