gpt4 book ai didi

bash exec 将输出发送到管道,怎么样?

转载 作者:行者123 更新时间:2023-11-29 08:51:04 26 4
gpt4 key购买 nike

我尝试执行 bash 本身只是为了重定向输出。如果我使用像这样的重定向

exec >bla.log
ls
exec 1>&2

它按预期工作:ls 输出在 bla.log 中结束,在第二个 exec 之后一切恢复正常,主要是因为句柄 2 仍然绑定(bind)到终端。

现在我想通过管道而不是将输出发送到文件中,一个简单的例子是 exec |猫>bla.log。但是,该命令立即返回。为了弄清楚发生了什么,我这样做了:

exec | bash -c 'echo $$; ls -l /proc/$$/fd /proc/23084/fd'

其中 23084 是当前正在运行的 bash 并且得到了这个:

24002
/proc/23084/fd:
total 0
lrwx------ 1 harald harald 64 Aug 14 20:17 0 -> /dev/pts/1
lrwx------ 1 harald harald 64 Aug 14 20:17 1 -> /dev/pts/1
lrwx------ 1 harald harald 64 Aug 14 20:17 2 -> /dev/pts/1
lrwx------ 1 harald harald 64 Aug 14 20:17 255 -> /dev/pts/1

/proc/24002/fd:
total 0
lr-x------ 1 harald harald 64 Aug 14 21:56 0 -> pipe:[58814]
lrwx------ 1 harald harald 64 Aug 14 21:56 1 -> /dev/pts/1
lrwx------ 1 harald harald 64 Aug 14 21:56 2 -> /dev/pts/1

我们可以看到,子进程24002确实在监听一个管道。但它肯定不是打开此管道的父进程 23084。

知道这里发生了什么吗?

最佳答案

什么

实现可能以其他方式编写的内容的正确方法

exec | cat >bla.log

#!/bin/bash
# ^^^^ - IMPORTANT: not /bin/sh

exec > >(cat >bla.log)

为什么

这是因为 >()process substitution ;它被替换为文件名(如果可能,格式为 /dev/fd/NN,否则为临时 FIFO),写入时将传送到封闭进程的标准输入。 (<() 类似,但方向相反:被替换为类文件对象的名称,该对象将在读取时返回给定进程的标准输出)。

因此,exec > >(cat >bla.log)大致等同于以下内容(在不提供 /dev/fd/proc/self/fds 或类似内容的操作系统上):

mkfifo "tempfifo.$$"           # implicit: FIFO creation
cat >bla.log <"tempfifo.$$" & # ...start the desired process within it...
exec >"tempfifo.$$" # explicit: redirect to the FIFO
rm "tempfifo.$$" # ...and can unlink it immediately.

关于bash exec 将输出发送到管道,怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25316705/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com