在作业脚本中使用stdout重定向到/ dev/null的grep是什么意思?

Tiu*_*uri 0 bash grep

我有一个bash脚本作为bash作业提交.它创建一些文件,执行一些计算,将输出文件移动到其他地方并清理.对于移动输出文件,它包含以下行:

set -e
mv $tmp/stdout.txt $current/tmp.stdout.txt
grep Report $current/tmp.stdout.txt >/dev/null 2>&1
mv $current/tmp.stdout.txt $current/stdout.txt
set +e
Run Code Online (Sandbox Code Playgroud)

如果计算成功,则输出文件stdout.txt包含多行开头Report; 但如果没有,则没有.进一步处理检查$current/stdout.txt文件是否存在(否则重新提交作业).

第一个mv将输出文件从临时目录移动到临时名称下的最终目录; 第二个mv将输出文件重命名为其最终名称.但是grep介于两者之间的目的是什么?如果输出文件包含行Report,则将它们重定向到\dev\null并且没有任何反应.如果输出文件不包含任何行Report,则它不会输出任何内容,既不会重定向stdout也不会重定向stderr.所以,我的印象是,这条线什么都不做,我应该取代mv+ grep+ mv由单一mv.我在这里忽略了哪些功能?

Cha*_*ffy 6

这里set -e很重要.

  • grep 将其退出状态设置为0,成功处理输入文件并找到任何结果,否则设置非零值.
  • set -e如果任何已检查的命令具有非零退出状态,则告诉shell退出.(它有一堆陷阱和警告,通常不应该使用;参见BashFAQ#105).

因此 - 除非此代码嵌入在触发其中一个set -e无效的情境之一的上下文中- mv如果grep没有匹配,您的脚本将在第二个之前终止.


编写脚本的这一部分的更好方法是:

mv "$tmp/stdout.txt" "$current/tmp.stdout.txt" || exit
grep -q Report "$current/tmp.stdout.txt" || exit
mv "$current/tmp.stdout.txt" "$current/stdout.txt" || exit
Run Code Online (Sandbox Code Playgroud)
  • grep -q效率更高grep >/dev/null,因为它可以在看到匹配时立即退出,而另外grep需要一直读到输入文件的末尾.(2>/dev/null通常是不好的做法,因为它隐藏了你需要知道的关于调试不当行为的错误;因此这里被删除了).
  • 引号使用空格或全局字符安全的变量,否则它们不会.
  • || exit根据BashFAQ#105中set -e给出的理由(如果匆忙,请跳过下面的练习的寓言,或者参见https://www.in-ulm),将您想要对错误致命的单个命.de/~mascheck/various/set-e /表示已知不同shell和/或shell版本的行为不同的情况列表.set -e