これが私がやりたいことです。
100を超えるホストをチェックして、そのホストにファイルが存在するかどうかを確認したいと思います。ファイルが存在する場合は、ホスト名とコマンドの出力を出力します。
この例の例では、Host1.example.org Host2.example.orgHost3.example.orgという3つのホストがあると想定しています。ファイル /etc/foobar
はHost2.example.orgに存在しますが、Host1.example.orgまたはHost3.example.orgには存在しません。
ls -l /etc/foobar
リスト内の各ホスト。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
これは私のために働いた:
for Host in $HOSTLIST; do
ssh $Host '[ -f /etc/passwd ] && echo $(hostname) has file'
done
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
clusterssh
をチェックして、mayシステムでコマンドを簡単に実行してください。非常に多くのシステムで一度にコマンドを実行する場合は特に注意してください。残念ながら、すべてのサーバーが影響を受けるというタイプミスが発生します。
実行するコマンドは次のようになります(詳細については、bashのマニュアルページを参照してください)。
[ -e some_existing_file ] && { hostname; ls -l; }
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