循环在具有eval和进程替换的函数之后停止

时间:2015-02-04 21:29:25

标签: bash eval process-substitution

上下文

我有一个迭代列表的脚本。在每次迭代中,期望调用构造“差异”的函数。通过' eval'比较两个远程文件的命令。

'差异'命令通过两个进程替换获取其输入,其中每个进程替换通过&s; ssh'执行无密码身份验证(通过公钥/私钥)。

'差异'和' 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

问题

你知道循环停止的原因吗?以及如何解决它?

1 个答案:

答案 0 :(得分:1)

它不是eval,也不是流程替代。这是ssh

默认情况下,

sshstdin传递给它在远程服务器上运行的命令(并从远程命令传回stdout)。这使得可以在管道中使用。但是,在这种情况下,您不希望ssh触及stdin,因为您自己使用它来进行循环播放。

通过使用ssh命令行选项或将stdin重定向到-n,您可以轻松地stdin不使用/dev/null:< / p>

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')