awk
tail -f
分析vs的输出时表现不同inotifywait -m
。具体来说,我正在搜索匹配的字符串,并希望awk
在它出现后退出。这对于 来说效果很好tail -f
,但是在 的情况下inofitywait
,awk
需要触发两次。为什么这样?
可重复的例子:
假设我们在任何一种情况下都搜索特定的字符串(“OPEN”),并使用特殊的退出代码作为标记。让我们在短暂等待(inotofywait
需要一点时间)后触发它并返回退出代码。伪代码:
command | awk-analysis || get-non-0-exit-code & trigger
一切都好于tail -f
以下 a) 打印该行,b) 返回退出代码,c) 终止。正如预期的那样。
tail -f test.file | awk '/OPEN/ { print $0 ; exit 100 }' || echo $? &
{ sleep 2 ; echo OPEN > test.file ; }
然而与inotifywait -m
结果却截然不同。
inotifywait -m -e OPEN | awk '/OPEN/ { print $0 ; exit 100 }' || echo $? &
{ sleep 2 ; touch test.file ; }
这将打印该行(因此inotifywait
被触发并awk
看到它),但不显示退出代码也不终止。只有像这样的另一个触发器touch test.file
才能停止awk
也许控制字符?
我想也许我在这里缺少一个信号awk
用途,所以我尝试使用cat -A
(父文件夹中的结果文件,所以否则会触发第二个“OPEN” inotifywait
)进行分析:
tail -f test.file | tee >(cat -A >../stream) | ....
cat ../stream
OPEN$
和
inotifywait -m -e OPEN | tee >(cat -A >../stream) | ....
cat ../stream
./ OPEN test.file$
所以没有遗漏任何看不见的控制字符。
这种行为的原因是什么?
我错过了换行符吗?为什么awk
打印该行,但不在exit
同一代码块中运行该命令?但为什么它可以与 一起使用tail
呢?
版本
awk --verison
:GNU Awk 4.2.1,API:2.0(GNU MPFR 4.0.2,GNU MP 6.1.2)
inotifywait -h
: inotifywait 3.14
tail --verison
:尾部(GNU coreutils)8.30
根据 Kusalananda 的评论进行编辑:
尾部-f
test.file
存在并具有以下内容:
*情况1
OPEN
spam
*案例2
spam
OPEN
*情况3(文件为空)
上面的触发器没有运行,即
tail -f test.file | awk '/OPEN/ {print $0 ; exit 100 }' || echo $?
情况 1 & 2 :立即返回匹配行、退出代码并终止。
情况 3:等待,打开其他终端和echo OPEN >> 3
/或echo OPEN > 3
返回字符串、退出代码并终止。
答案1
echo $?
在整个管道(之前的代码||
)终止后运行。
在终止inotifywait … | awk … || echo …
后仍然运行的情况下。只有当它尝试写更多时它才会得到。再次尝试到达此点并触发。awk
inotifywait
SIGPIPE
touch test.file
echo
另一方面,退出后立即终止tail
,因为tail -f … | awk …
awk
GNUtail
采取特殊措施来检测这种情况。
为了使用 inotifywait 重现这一点,需要转发 PID 并通过 awk 发送 SIGPIPE:
{ inotifywait -m -e OPEN ./ & echo $! ; } |
awk 'NR==1 {pid=$0}
/OPEN/ {print $0,pid
system("echo kill -13 "pid)
exit 122 }' ||
echo $?