如何跟踪bash脚本 - 退出状态及其失败原因

时间:2013-10-19 17:54:30

标签: bash exitstatus

有时我需要运行这样的命令:

cat file.txt | awk ' NR%4 == 2 { print $1 }' | sort | uniq -c | sort -gr >>output.txt &

大文件(2-32 GB大小)。我在晚上启动命令,当我早上来时,output.txt有时是空的,进程不再运行。

请问,我该如何追踪正在发生的事情?为什么以及何时我的命令失败?我知道管道正在运行,因为有时它只是成功完成。

非常感谢!

更新: 我现在认为我的进程被杀死了,因为我运行此计算时的服务器建议仅用于交互式使用。如果这是真的,那么我只能从日志文件中看到它是不成功的 - 还没有完成。

有没有办法发现我的进程实际上被杀了?感谢。

3 个答案:

答案 0 :(得分:4)

第一步,将该脚本封装在一个文件中,而不是直接在终端上运行(并在我们使用时丢失UUOC奖励)。

#!/bin/bash

{
awk 'NR%4 == 2 { print $1 }' file.txt | sort | uniq -c | sort -gr >>output.txt
} 2>error.log

这会捕获文件error.log中的所有错误消息。然后,您可以添加诊断信息。

#!/bin/bash

{
date >&2
set -x
awk 'NR%4 == 2 { print $1 }' file.txt | sort | uniq -c | sort -gr >>output.txt
date >&2
} 2>error.log

现在你已经获得了时间信息 - 它何时开始以及何时完成。由于您在bash,因此您可以安排捕获管道中每个进程的退出状态,这样您就可以确切地知道哪些命令退出了哪个状态。您可能会或可能不会获得有关哪个进程被终止的消息(如果进程被外部信号杀死),但如果进程自行死亡,它应该在标准错误上打印一条消息(这就是它的用途,以及为什么将错误打印到标准错误而非标准输出至关重要。

使用此脚本,标准输出将转至output.txt,标准错误将转至error.log;该脚本不使用标准输入(数据来自file.txt)。因此,您可以使用nohup或仅使用&在后​​台运行此操作,而不会有任何疑虑。

您可能更喜欢将名称file.txt设置为命令行参数;您可能希望使输出和日志文件可配置。您可能更喜欢日期输出的不同格式。所有这些都是可以调整的。但关键是将它放入shell脚本中,以便您可以直接和系统地处理这些事情。

答案 1 :(得分:2)

使用screenpvtee来捕获所有错误,拥有进度条,并允许从上一个成功命令重新启动,而不是在出错时从头开始。< / em>的

您可以使用screenmultiplexer)而非背景您的流程。这样,您始终可以查看其状态,不会错过错误消息。只需输入screen,在没有&的情况下运行您的命令,然后点击CTRL-a,d。然后您可以注销。要稍后查看输出,请登录(甚至远程)并键入screen -r

此外,如果您将初始cat替换为pvPipe Viewer),您将有一个进度条告诉您已经处理了多少:

pv -cN file.txt

你会看到像

这样的东西
611MB 0:00:11 [58.3MB/s] [=>      ] 15% ETA 0:00:59

每当您重新连接screen进程时。

或者/互补地,您可以在命令之后插入tee,以便在将其输出传播到下一个文件之前将其输出复制到文件中。

uniq -c | tee afteruniq.tmpfile | sort -gr

文件afteruniq.tmpfile将包含uniq -c的结果。所以你知道什么有效,什么失败。您还可以在tee'd文件的最后一个成功步骤后恢复链。

答案 2 :(得分:0)

您需要将stderrstdout重定向到输出文件。

按照以下命令执行命令:

( awk 'NR%4 == 2{print $1}' file.txt| sort | uniq -c | sort -gr ) >> output.txt 2>&1 &

请注意2>&1stderr重定向到stdout所在的位置。