在具有 eval 和进程替换的函数之后循环停止
loop stops after a function with an eval and process substitution
上下文
我有一个遍历列表的脚本。在每次迭代中,预计会调用一个构造 'diff' 命令的函数,用于通过 'eval' 比较两个远程文件。
'diff' 命令通过两个进程替换获取其输入,其中每个进程替换通过 'ssh' 执行无密码身份验证(通过 public/private 密钥)获取远程文件。
'diff' 和 'ssh' 执行已经在脚本之外进行了测试,它们工作正常。
代码
这里我 post 我的脚本的一个非常短的版本但是产生了同样的问题:
#!/bin/bash
func(){
NUM=
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
问题
你知道循环停止的原因吗?以及如何解决?
这不是评估也不是进程替换。这是 ssh
.
ssh
默认情况下将 stdin
传递给它在远程服务器上运行的命令(并从远程命令返回 stdout
)。这使得在管道中使用成为可能。但是,在这种情况下,您不希望 ssh
触及 stdin
,因为您自己在循环中使用它。
您可以轻松地让 ssh
不使用 stdin
,方法是使用 -n
命令行选项,或者将 stdin
重定向到 /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')
上下文
我有一个遍历列表的脚本。在每次迭代中,预计会调用一个构造 'diff' 命令的函数,用于通过 'eval' 比较两个远程文件。
'diff' 命令通过两个进程替换获取其输入,其中每个进程替换通过 'ssh' 执行无密码身份验证(通过 public/private 密钥)获取远程文件。
'diff' 和 'ssh' 执行已经在脚本之外进行了测试,它们工作正常。
代码
这里我 post 我的脚本的一个非常短的版本但是产生了同样的问题:
#!/bin/bash
func(){
NUM=
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
问题
你知道循环停止的原因吗?以及如何解决?
这不是评估也不是进程替换。这是 ssh
.
ssh
默认情况下将 stdin
传递给它在远程服务器上运行的命令(并从远程命令返回 stdout
)。这使得在管道中使用成为可能。但是,在这种情况下,您不希望 ssh
触及 stdin
,因为您自己在循环中使用它。
您可以轻松地让 ssh
不使用 stdin
,方法是使用 -n
命令行选项,或者将 stdin
重定向到 /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')