bashスクリプトを使用してリモートで複数のコマンドを実行する

bashスクリプトを使用してリモートで複数のコマンドを実行する

SSHを介してリモートサーバーにログインし、tmpフォルダに移動してrmコマンドを実行する必要があります。ところで、以下のスクリプトを実行するとリモートサーバーには行きますが、tempフォルダには行かず、rmコマンドも実行されません。

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

答え1

コードの唯一の実際の問題は、ループが欠落して構文エラーが発生doし、doneそれをループ変数として使用するが設定されていないiいくつかの変数を連結しようとしていることです。server

catそれに加えて、引用符なしでコマンド置換を使用しています。一般的に言えば空白とファイル名ワイルドカードなしで文字列を読み取ることができるかどうかわからない場合は、これは悪い考えです(たいていのホスト名はこの点でうまく機能しますが)。

ほとんどの場合、次のように入力内容を1行ずつ読み取ることをお勧めします。

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

ssh -nここでは、ssh標準入力ストリーム(ファイルに接続されている)の読み取りを停止するために使用していますlist。そうでなければ、-n残りのssh部分を読み、listループは1回の反復の間だけ実行されます。

または、ここのドキュメントからコマンドを読むには、次の手順を実行します。

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

ここではssh -T、ユーザー対話が必要な操作を実行しないため、不要な疑似端末割り当てを明示的に無効にする方法を使用します。sshこれは標準入力ストリームにデータがあることに気づき、リモートシステムに対話できる端末がないことを警告するためです。 hereドキュメントから標準入力ストリームを再割り当てする-nため、ここではこれは必要ありません。sshssh

ただし、ループは単一のコマンドで置き換えることができます。

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

...xargsユーティリティが読む場所ワイヤーファイルからlistコマンドを、ファイルを読み取り、特定のファイルを削除するためにリモートシステムに接続するアクションを実行する行{}に置き換えます。削除するファイルがないと、通常エラーは発生しません。sshrm -f

たとえば、一部の実装ではxargsユーティリティの並列実行が可能です-P 4(最大ssh4つの同時コマンドが同時に実行されます)。

答え2

#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

ファイルを1つだけ削除する必要がある場合は、1行に簡単に指定できます。また-f、に関する追加事項もありますrm

答え3

したがって、SSHセッションの標準入力を単にリダイレクトすることはできません。次のようなエラーメッセージが表示されます。

stdin が端末ではないため、疑似端末は割り当てられません。

擬似デバイスの割り当てを強制するには、sshオプション-ttを使用する必要があります。この試み:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS

関連情報