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

等々..

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.

ここではxxxxdev01、1つのホストのみの出力を取得しました。これは、sshバナーやその他の警告にも含まれています。

他のすべてのホストの出力とsshバナーなしの出力が必要です。ここで何が問題になっていますか?


サーバーの1つを手動で使用して実行するとsshpass -p password root@server histnameどうなりますか?
terdon

1
ssh -t -t root@...を使用して、疑似端末を強制します。
garethTheRed 2014

回答:


11

hostnameand unameコマンドから期待どおりの出力が得られない理由を説明することはできませんが、無関係なテキストについてはお手伝いできます。

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

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

これは私が最初に試したものです。しかし、期待される出力は得られません。
Gokulである2014

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はリモートコマンドにアクセスできません。あなたができることは、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

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

 # 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
あなたはフォーマットについて読むべきです。あなたの答えは素晴らしいかもしれませんが、今はほとんど判読できません。
roaima

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

別の方法は、sshに/ dev / nullを使用することです。FileDescriptorは無視できます。`行を読みながら; do sshpass -p password ssh root @ $ line </ dev / null << EOF .... done <server.txt`
Leon Wang
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.