
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
標準入力ストリームにデータがあることに気づき、対話的な操作を行うためのリモート システムに機能する端末がないことを警告するため、これを行います。 の標準入力ストリームをヒアドキュメントから再割り当てしているので、ここ-n
では は必要ありません。ssh
ssh
しかし、ループは単一のコマンドに置き換えることができます
xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list
...xargs
ユーティリティは次のように読み取ります行ファイルからlist
、コマンド{}
内の をファイルから読み取った行に置き換え、リモート システムにアクセスして特定のファイルを削除するアクションを実行します。削除するファイルがない場合にエラーが発生しないようにするために をssh
使用しています。rm -f
の実装によってxargs
は、たとえばユーティリティの並列実行が可能になります(一度に-P 4
最大 4 つのコマンドを同時に実行できます)。ssh
答え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 を単純にリダイレクトすることはできません。次のようなエラー メッセージが表示されるはずです。
stdin は端末ではないため、擬似端末は割り当てられません。
擬似ttyを強制的に割り当てるには、sshにオプション -tt を使用する必要があります。以下を試してください:
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS