无法将多个shell语句重定向到命名管道

时间:2013-11-12 20:17:55

标签: shell named-pipes io-redirection

观察当我一个接一个地发出两个命令时会发生什么,而不是在一行上用分号分隔:

制作管道并启动电影:

$ mkfifo pipe1
$ tail -f /dev/null > pipe1 &
$ cat pipe1 | omxplayer /path/to/video.mp4

退出试用版1:

$ echo -n q > pipe1; # Exits movie, but omxplayer hangs
$ echo > pipe1; # Completes exit process

退出试用2:

$ echo -n q > pipe1; echo > pipe1 # Does nothing

退出试用3:

$ echo -n q > pipe1; sleep 1; echo > pipe1 # Works just like trial 1

有人可以解释为什么试验2什么都不做。另外,有没有更好的方法通过命名管道发出quit命令,不需要两个echo语句?

3 个答案:

答案 0 :(得分:2)

如果fifo上的最后一个作者死了并且读者检查了fifo,它会看到文件结束。如果在读者检查之前再次有新的作者,则读者看不到文件结尾。我想你的读者(omxplayer)会检查文件结尾。

从读者omxplayer的角度来看它:它看到了

  1. "q" EOF ... <LF> EOF
  2. "q"EOF可能看不到omxplayer<LF> EOF
  3. "q" EOF ... <LF> EOF
  4. 完全取决于omxplayer如何处理这个问题,而不是你,操作系统或你的shell搞砸了它。

答案 1 :(得分:1)

我怀疑某种程度上涉及到缓冲。 (1)和(3)都在q和换行之间提供了一段相对较长的时间,停止了电影但是在读完整行之前没有退出。在(2)中,q和换行是如此接近,也许omxplayer只是忽略整个字符串。 echo q > pipe1(类似于(2),但更快)做什么?

答案 2 :(得分:1)

omxplayer 对其(命令)输入有点挑剔。它不喜欢用换行符q终止的命令(例如'\n')。 将新行作为命令('q''\n')的一部分进行错误处理,从而导致出现未知命令(而'q'仅作为有效命令存在)。因此,当-necho发送命令时,omxplayer选项是必需的。

除了omxplayer的'错误处理'之外,使用cat pipe1 | cat时可以看到相同的行为。在杀死第二个 cat后,它是终止第一个 echo的最后一个(或第一个)cat