Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 来自'的管道输出;超时';至';wc-l';失败_Linux_Console_Timeout_Pipe_Signals - Fatal编程技术网

Linux 来自'的管道输出;超时';至';wc-l';失败

Linux 来自'的管道输出;超时';至';wc-l';失败,linux,console,timeout,pipe,signals,Linux,Console,Timeout,Pipe,Signals,我试图计算给定时间段内的所有击键次数。 当前我的代码如下所示: $ timeout -s 9 10s xinput test 8 | wc -l $ xinput test 8 > output.log & sleep 10 && wc -l output.log && kill $! 这是回报 Killed 而不是预期的按键次数。 当我在没有管道的情况下运行timeout时,输出与预期的一样 $ timeout -s 9 20s xinput

我试图计算给定时间段内的所有击键次数。 当前我的代码如下所示:

$ timeout -s 9 10s xinput test 8 | wc -l
$ xinput test 8 > output.log & sleep 10 && wc -l output.log && kill $!
这是回报

Killed
而不是预期的按键次数。 当我在没有管道的情况下运行timeout时,输出与预期的一样

$ timeout -s 9 20s xinput test 8
key release 36 
key press   42 
key release 42 
key press   26 
key release 26 
key press   28 
key release 28 
key press   38 
key release 38 
key press   46 
key release 46 
key press   31 
key release 31 
key press   41 
key release 41 
key press   26 
key release 26 
Killed
无论是更改信号还是添加参数--preserve status都无法解决此问题

我想知道为什么这不起作用。“超时”是否会以某种方式劫持标准输出

编辑:
然而,添加前景解决了我的问题。但我不明白为什么。

它可以工作,因为这样,timeout命令不会杀死任何子进程,从而避免了wc来计算行数

$ timeout --foreground -s 15 10s xinput test 8 | wc -l
另一种方式是这样的:

$ timeout -s 9 10s xinput test 8 | wc -l
$ xinput test 8 > output.log & sleep 10 && wc -l output.log && kill $!
这样,您就不需要超时。第一部分将xinput的输出重定向到一个文件,并将命令发送到后台,然后休眠(等待文件接收到一些数据),在休眠完成后,我们运行wc并优雅地终止xinput后台命令。

使用
--foreground
wc-l
只会看到一个EOF,因此它会打印行数

如果没有
--前台
wc-l
会被
SIGKILL
杀死。(我用另一个终端的
strace-p$(pidof-wc)
追踪它)

跟踪
超时
本身,以查看有无
--前台
时的不同功能:

除内存地址不同外:

在时间到期后,
--front
只是杀死并等待(2)s它分叉的子对象(
clone(2)
),然后通过正常的
exit\u组(2)
系统调用退出

如果没有
--前台
,它会

setpgid(0, 0)                           = 0
在用叉子叉孩子之前。在时间到期后,它
kill()
s子对象,然后使用
kill(0,SIGKILL)
杀死自己

kill(2)

如果pid等于0,则sig被发送到调用进程的进程组中的每个进程

我忘记了信号语义的细节,我不知道为什么这解释了
wc
接收
SIGKILL
。根据
pstree
wc
xinput
都是bash的孩子,而不是彼此的孩子。不过,进程是按照它们在管道中出现的顺序启动的



timeout(1)
手册页显示了关于
--front
:“在此模式下,命令的子项不会超时”。这似乎包括管道中的后续元素。IDK如果shell可以安排管道的不同元素不在同一个进程组中以避免这种情况,或者什么。

您的解决方案将所有按下的键存储在一个文件中的磁盘上。出于安全考虑,我不想那样。啊,好的。因此,超时似乎最适合您。