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