上下文
我有一个迭代列表的脚本。在每次迭代中,期望调用构造“差异”的函数。通过' 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
问题
你知道循环停止的原因吗?以及如何解决它?
答案 0 :(得分:1)
它不是eval,也不是流程替代。这是ssh
。
ssh
将stdin
传递给它在远程服务器上运行的命令(并从远程命令传回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')