1

语境

我有一个迭代列表的脚本。在每次迭代中,它应该调用一个构造一个“diff”命令的函数,用于通过“eval”比较两个远程文件。

“diff”命令通过两个进程替换获取其输入,其中每个进程替换通过执行无密码身份验证(通过公钥/私钥)的“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

这不是 eval 也不是进程替换。是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 回答