【发布时间】:2019-06-25 10:18:19
【问题描述】:
我写了一个 bash 脚本rm_remote_file.sh,它通过 ssh 连接到一组远程机器并删除一个文件。我在每个函数调用结束时使用& 并行运行这些命令,脚本如下所示:
#!/bin/bash
rm_remote_file() {
echo "Removing file on node $1:"
ssh $1 'rm ~/test_file'
}
for node in node1.com node2.com node3.com; do
rm_remote_file $node &
done
当每个节点上都存在 test_file 时 - rm 命令成功 - 此脚本的输出为:
Removing file on node node1.com:
Removing file on node node2.com:
Removing file on node node3.com:
我更喜欢打印出每个主机名。但是,如果每个节点上不存在 test_file - rm 命令失败 - 此脚本的输出为:
rm: cannot remove ‘~/test_file’: No such file or directory
rm: cannot remove ‘~/test_file’: No such file or directory
rm: cannot remove ‘~/test_file’: No such file or directory
因此,此错误消息会抑制节点主机名的打印。我认为这种行为与 I/O 重定向有关,使用诸如 2>&1 之类的东西可以解决这个问题。但我想知道为什么 ssh 命令错误消息会抑制 echo 命令。
请注意,这只发生在 ssh 命令中,以下脚本仅删除一些本地文件,会同时输出“正在删除文件”和“没有此类文件或目录”。
#!/bin/bash
rm_file() {
echo "Removing file..."
rm ./$1
}
for file in test1 test2 test3 test4 test5; do
rm_file $file &
done
【问题讨论】:
-
这不是保证只发生在 ssh 上,在设置过程中会有更多的延迟,所以更有可能。在本地版本中,
rm_file函数仍被分叉并在后台运行,但echo的发生与rm的发生非常接近。对于远程版本,echo和rm之间存在很大延迟,而ssh传输是协商的。 -
@CharlesDuffy 为什么
echo和ssh之间的大延迟会阻止echo消息?我尝试在 remove-local-files 脚本中的echo和rm ./$1之间添加sleep 5,但我仍然可以看到echo消息和rm错误消息。 -
它不会阻止消息,但这意味着您有更大的机会破坏订单,因此您之前打印了所有三个
Removing file on node $i消息任何rm错误。还要记住,在ssh的情况下,确切的延迟量会有所不同,因此echos 的顺序和rm错误的顺序特别有可能被解耦。 -
(很清楚,我不相信消息曾经被阻止的问题中的说法,并且在看到@987654321之前不会相信@; 更有可能它们只是发生在您日志中的其他地方,在您不看的地方,因为它们下方的失败消息将它们推离了屏幕)。
-
当我们根本不使用
2>&1时,我们在运行remove-remote-files 脚本时看不到echo消息,但在运行remove-local- 时我们确实看到echo消息文件脚本。
标签: bash ssh io-redirection