有时我需要运行这样的命令:
cat file.txt | awk ' NR%4 == 2 { print $1 }' | sort | uniq -c | sort -gr >>output.txt &
大文件(2-32 GB大小)。我在晚上启动命令,当我早上来时,output.txt有时是空的,进程不再运行。
请问,我该如何追踪正在发生的事情?为什么以及何时我的命令失败?我知道管道正在运行,因为有时它只是成功完成。
非常感谢!
更新: 我现在认为我的进程被杀死了,因为我运行此计算时的服务器建议仅用于交互式使用。如果这是真的,那么我只能从日志文件中看到它是不成功的 - 还没有完成。
有没有办法发现我的进程实际上被杀了?感谢。
答案 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)
使用screen
,pv
和tee
来捕获所有错误,拥有进度条,并允许从上一个成功命令重新启动,而不是在出错时从头开始。< / em>的
您可以使用screen
(multiplexer)而非背景您的流程。这样,您始终可以查看其状态,不会错过错误消息。只需输入screen
,在没有&
的情况下运行您的命令,然后点击CTRL-a,d
。然后您可以注销。要稍后查看输出,请登录(甚至远程)并键入screen -r
。
此外,如果您将初始cat
替换为pv
(Pipe 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)
您需要将stderr
和stdout
重定向到输出文件。
按照以下命令执行命令:
( awk 'NR%4 == 2{print $1}' file.txt| sort | uniq -c | sort -gr ) >> output.txt 2>&1 &
请注意2>&1
将stderr
重定向到stdout
所在的位置。