我有一个for循环,我通过ssh传递给一个服务器,这个服务器的格式是这样的。。。

i=0
for cmd in cmd_list;
do ${cmd} | sed "s/^/OUTPUT_${i}_: /" &
(( i++ ));
done;
wait

其思想是for循环将运行一个我给它的命令列表,并将每个命令通过管道发送到sed,sed在每个输出行前面加上一个命令号(0、1、2、3等)。然后它的背景,以便允许并行执行。这允许我跟踪与输出相关联的命令,因为数据可以同时返回,并且所有数据都是混合的。这真的很管用。根据命令打印信息的时间和完成信息的时间,输出可能如下所示。。。
OUTPUT_0_: some_data_string_from_a_command
OUTPUT_2_: some_data_string_from_a_command
OUTPUT_0_: some_data_string_from_a_command
OUTPUT_3_: some_data_string_from_a_command
OUTPUT_1_: some_data_string_from_a_command
OUTPUT_1_: some_data_string_from_a_command

然而,我真正想做的是。。。
do ${cmd} 2>&1 | sed "s/^/OUTPUT_${i}_${PIPESTATUS[0]}: /" &

所以我可以拿回这个。。。
OUTPUT_0_0: some_data_string_from_a_command
OUTPUT_2_1: some_error_message_from_a_command
OUTPUT_0_0: some_data_string_from_a_command
OUTPUT_3_1: some_error_message_from_a_command
OUTPUT_1_0: some_data_string_from_a_command
OUTPUT_1_0: some_data_string_from_a_command

如果第一个命令出错,这个命令就可以正常工作。我通常会从${PIPESTATION[0 ] }获得非零退出代码。然而,当我故意在我知道会失败的列表中植入命令时(即CAT/TMP/NothNo.ItAuthEntIX文件),PIPESTATE没有给我管链中命令的正确退出代码。我有时会得到0而不是真正的退出代码。
知道为什么吗?

最佳答案

管道中的命令并行执行。这意味着,在评估PIPESTATE时,它们可能没有退出,尤其是因为在实际运行SED命令之前,PIPESTATE由shell扩展。
我真的不明白你想做什么,因为你似乎想违反因果关系。你仔细考虑过吗?你似乎想要一个命令的输出值和它的输出,但是如果它正在输出数据,它显然没有退出。你依赖的是一个小的定时窗口总是打开的。它可能适用于一些短期运行时命令,但这甚至是有问题的,因为在没有同步操作的情况下协调并行执行容易出现“随机”故障。
如果要捕获数据以及命令的输出状态,则需要将输出保存在某处(例如在文件中),并且当进程退出时,然后用退出状态输出数据。

10-06 06:48