1

環境

リストを反復処理するスクリプトがあります。各反復で、'eval' を介して 2 つのリモート ファイルを比較するための 'diff' コマンドを構築する関数を呼び出すことが期待されます。

「diff」コマンドは、2 つのプロセス置換を通じて入力を取得します。各プロセスは、パスワードなしの認証を実行する「ssh」を介してリモート ファイルをキャットします (公開/秘密キーを介して)。

「diff」および「ssh」の実行は、スクリプトからテストされており、正常に動作します。

コード

ここでは、非常に短いバージョンのスクリプトを投稿しますが、同じ問題が発生します。

#!/bin/bash
func(){
   NUM=$1
   echo "func $NUM"
   COMMAND="diff <(ssh user1@server1 'cat file1' ) <(ssh user2@server2 'cat file2' )"
   eval "${COMMAND}"  1>/dev/null
   RESULT=$?
}

LIST="1
2
3
4
5"

echo "$LIST" | while read NUM ; do
   echo "main $NUM"
   func $NUM
done

期待される結果

main 1
func 1
main 2
func 2
main 3
func 3
main 4
func 4
main 5
func 5

問題

スクリプトは最初の繰り返しの後に停止します。

main 1
func 1

質問

ループが停止する理由を知っていますか? そしてそれを解決する方法は?

4

1 に答える 1

1

それは評価でもプロセス置換でもありません。ですssh

sshデフォルトstdinでは、リモート サーバー上で実行されるコマンドにパススルーされます (そしてstdout、リモート コマンドから戻されます)。これにより、パイプラインでの使用が可能になります。ただし、この場合、ループに自分で使用しているため、ssh触れたくありません。stdin

コマンドラインオプションを使用するか、にリダイレクトすることにより、簡単にssh使用しないようにすることができます:stdin-nstdin/dev/null

ssh -n user1@server1 'cat file1'
ssh user1@server1 'cat file1' < /dev/null

後者は、呼び出し関数でも機能します。

echo "$LIST" | while read NUM ; do
   echo "main $NUM"
   func $NUM < /dev/null
done

eval の弊害についての講義は不要だと思いますがeval、この方法での使用はおそらく不要であることを言及しなければならないと思います。プロセス置換を使用するコマンドを構築するためにそれを行っていると思います。exec代わりに、次のような を使用して、プロセス置換を使用して環境を構築できます。

exec 10< <(ssh -n user1@server1 'cat file1')
于 2015-02-04T22:01:15.790 に答える