Linux 管道中的多个GREP在完成后未终止

Linux 管道中的多个GREP在完成后未终止,linux,bash,grep,Linux,Bash,Grep,我似乎对一个简单的grep语句在完成后没有完成/终止有问题 例如: grep -v -E 'syslogd [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}: restart' | grep -v 'printStats: total reads from cache:' /var/log/customlog.log >\ /tmp/filtered_log.tmp 上面的语句将删除内容并将其保存到临时文件中,但是在grep处理完整个文件后,shell脚本将挂起

我似乎对一个简单的
grep
语句在完成后没有完成/终止有问题

例如:

 grep -v -E 'syslogd [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}: restart' |
 grep -v 'printStats: total reads from cache:' /var/log/customlog.log >\
 /tmp/filtered_log.tmp
上面的语句将删除内容并将其保存到临时文件中,但是在
grep
处理完整个文件后,shell脚本将挂起,无法继续。在命令行中手动运行命令时也会触发此行为。实际上,组合多个grep语句会导致类似寻呼机的操作(
more
/
less

有人有什么建议来克服这个限制吗?理想情况下,如果
customlog.log
文件有时可能会变得很大,我不想执行以下操作

cat /var/log/customlog.log |
grep -v -E 'syslogd [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}: restart' |
grep -v 'printStats: total reads from cache:' > /tmp/filtered_log.tmp
谢谢


Tony

如上所述,您需要将文件名移到此处:

grep -v -E \
    'syslogd [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}: restart' /var/log/customlog.log
| grep -v 'printStats: total reads from cache:' > /tmp/filtered_log.tmp
但您也可以将这两个grep组合起来:

grep -v -E \
    -e 'syslogd [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}: restart' \
    -e  'printStats: total reads from cache:' /var/log/customlog.log > \
    /tmp/filtered_log.tmp
节省一点CPU,同时修复错误

顺便说一句,另一个可能的问题是:如果这个脚本的两个实例同时运行会怎么样?两者将使用相同的临时文件。在这种情况下,这可能不是一个问题,但您最好习惯于为这种情况开发脚本。我建议您使用
$
将进程ID放入临时文件中:

tempFileName="/tmp/filtered_log.$$.tmp"
grep -v -E -e [blah... blah.. blah] /var/log/customlog.log > $tempFileName
现在,如果两个不同的人正在运行此进程,您将无法让他们使用相同的临时文件


附加 正如所指出的,您实际上最好使用:


谢谢您的建议。

您需要将
/var/log/customlog.log
参数移动到行中的第一个grep命令。您的命令挂起,因为此grep正在等待来自控制台的输入。您希望第一个grep处理该文件,然后将其减少的输出传递给第二个grep实例。谢谢Scott,这完全回答了我的问题-Tony最好使用
mktemp
断言没有人猜到您的pid,并用相应的名称放置一个符号链接。好主意,尽管我从未使用过它。从manpage:许多shell脚本将带有pid的程序名作为后缀,并将其用作临时文件名。这种命名方案是可预测的,它创建的竞争条件很容易让攻击者获胜。要使用mktemp,必须执行以下操作:
myTempFile=$(mktemp foo.XXXXXX)
tempFileName=$(mktemp filtered_log.XXXXX)
grep -v -E -e [blah... blah.. blah] /var/log/customlog.log > $tempFileName