终止进程并比较其结果

终止进程并比较其结果

我一直在尝试编写一个简单的 bash 脚本,但无法让它工作。

我想要:

  • 启动一个程序,从文本文件中为其提供输入 ( ./prog < input1.txt)
  • 等待一小段时间并杀死它,就好像它被键盘中断服务一样 ( & PID=$!; sleep 1; kill -INT $PID)来源
  • 找出程序输出和文本文件之间的差异 ( | diff -y output1.txt -)来源

这就是我现在所拥有的,将前面的步骤放在一起:

./program < input1.txt & PID=$!; sleep 1; kill -INT $PID | diff -y output1.txt -

此版本始终报告第一个命令没有输出,因为 PID 行正在隐藏它。如果我在程序名称后添加文件重定向,kill 命令就会停止工作,因为它现在指向重定向。

编辑:我使用的是 Ubuntu 16.04;的输出bash --versionGNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

答案1

事实上,在您的代码中diff接收的是 的输出kill而不是program.您可以通过将子 shell 中管道之前的命令与().

您的脚本的另一个潜在问题是,它kill不是设计用来等待program;的终止的。相反,它只是向它发送一个信号。因此,您可能会看到竞争条件在diff没有捕获 的整个输出的情况下起作用program。我建议以编程方式等待wait内置 bash 后台进程的终止。

下面是包含上述修复的代码示例:

#!/bin/bash
(
    ./program <input1.txt &
    PID=$!
    sleep 1
    kill -INT $PID
    wait
) | diff -y reference_output.txt -

答案2

您可以使用进程替换[1]:

diff -y output1.txt <(your_program & sleep 1; kill $!)

如果your_program能够在一秒钟内生成大量数据(就像使用 进行测试时一样yes(1)),那么diff处理时会遇到很多麻烦,除非您有一些仔细的限制,否则它可能会耗尽您的内存并挂起您的机器(在最好的情况下,它会产生命令“挂起”一段时间的错觉)。相反yes,请尝试使用slowyes类似 的脚本while echo y; do sleep .01; done

请注意,<(...)进程替换正在运行在平行下,因此diff不会等待它完成后再开始处理其数据。

your_program我想在生成多行之后停止而不是在一段时间之后停止会更好:

diff -y output1.txt <(your_program | head -n 1000)

在这种情况下,your_program应该被 杀死SIGPIPE,就像通常使用管道左侧一样。如果您的程序忽略了SIGPIPEwrite(2)错误,那么请就此提出另一个问题,或者如何修复它或如何解决它。

[1] 如果您的 shell 不支持进程替换(如/bin/shdebian 上的那样,则不支持bash),您还可以使用管道,如其他答案中所示

{ your_program & sleep 1; kill $!; } | diff -y output1.txt -

同样的注意事项也适用于本案。

相关内容