在bash中在主管道之外的进程之间管道数据的简便方法

时间:2018-05-07 15:24:04

标签: bash file-descriptor mkfifo

我希望能够在现有bash管道中的进程之间管道数据。为了更好地说明我的意思,请采用这个简单的例子,我假设文件描述符3的行为类似于fifo。

seq 5 | tee >(while read num; do echo $(($num * $num)); done >&3) | paste - <(<&3 cat)

我想要输出

1   1
2   4
3   9
4   16
5   25

然后终止。理想情况下,解决方案类似于exec 3<>-,其中bash会将文件描述符3作为读写缓冲区打开。据我所知,在bash中没有对此的支持,所以我转向this question来创建匿名管道。根据讨论,我想出了这个功能:

function temp_pipe() {
  [[ "$1" =~ [3-9] ]] || return 1
  PIPE_DIR="$(mktemp -d)"
  PIPE="$PIPE_DIR/pipe"
  mkfifo "$PIPE"
  eval "exec $1<>'$PIPE'"
  rm -f "$PIPE"
  rmdir "$PIPE_DIR"
}

将文件描述符作为参数,并将其附加到匿名fifo。这原则上有效,但是当我写完输出信息时,我无法弄清楚如何关闭fifo。以下几乎按预期工作:

temp_pipe 3 && seq 5 | tee >(while read num; do echo $(($num * $num)); done >&3) | paste - <(<&3 cat)

因为它输出正确的结果,但粘贴保持打开,因为文件描述符3永远不会关闭。我天真地以为我可以将exec 3>&-附加到子进程的末尾以关闭文件描述符并使所有内容按预期工作,但这不起作用。父文件描述符未关闭,因为关闭操作在子进程中运行,因此关闭对同一描述符的继承引用,而不是关闭父进程中的描述符。

我理想地寻找一种解决方案,在没有大量临时fifos或文件描述符的手动管理的情况下构建复杂流水线相对容易。

0 个答案:

没有答案