Bash 如何显示NUL分隔数据的中间管道结果?

Bash 如何显示NUL分隔数据的中间管道结果?,bash,sh,Bash,Sh,如何组合以下两个命令: find . -print0 | grep -z pattern | tr '\0' '\n' find . -print0 | grep -z pattern | xargs -0 my_command 进入一条管道?如果我不需要NUL分隔符,那么我可以: find . | grep pattern | tee /dev/tty | xargs my_command 我希望避免使用这样的临时文件: find . -print0 | grep -z pattern &

如何组合以下两个命令:

find . -print0 | grep -z pattern | tr '\0' '\n'
find . -print0 | grep -z pattern | xargs -0 my_command
进入一条管道?如果我不需要NUL分隔符,那么我可以:

find . | grep pattern | tee /dev/tty | xargs my_command
我希望避免使用这样的临时文件:

find . -print0 | grep -z pattern > tempfile
cat tempfile | tr '\0' '\n'
cat tempfile | xargs -0 my_command
rm tempfile
这个问题是这些答案的后续问题:

1) 使用/dev/tty显示中间管道结果:

2) 使用NUL分隔的文件列表:

编辑为使用
my_命令
而不是
命令

跟进问题:


可以使用XARG执行多个命令,如下所示:

find . -print0 | grep -z pattern | xargs -0 -I% sh -c 'echo "%"; command "%"'
资料来源:

根据讨论,上述情况是不安全的,这要好得多:

find . -print0 | grep -z pattern | xargs -0 -n 1 sh -c 'echo "$1"; my_command "$1"' _

其中一种可能性是:

find . -print0 | grep -z pattern | { exec {fd}> >(tr '\0' '\n' >/dev/tty); tee "/dev/fd/$fd"; } | xargs -0 command

其中,我们创建了一个临时文件描述符
fd
,其中
exec
处于动态状态,通过标准流程替换连接到
tr
的stdin
tee
将所有内容传递给stdout(结束于
xargs
),并将副本传递给
tr
子流程,该子流程输出到
/dev/tty

您只需将tee更改为指向proc sub,然后在其中执行完全相同的操作

   find . -print0 | grep -z pattern | tee >(tr '\0' '\n' > /dev/tty) | xargs -0 command

以这种方式使用tee的唯一问题是,如果xargs命令也打印到屏幕上,那么所有输出都可能变得混乱,因为管道和进程子对象都是异步的

为什么不直接使用
tee>(tr'\0'\n'>/dev/tty)
,而不是使用一堆只在bash版本中可用的功能,这些功能在任何地方都不可用(特别是在MacOS上不可用)?@CharlesDuffy,你说得对,这更简单。我被迷住了这在OSX10.6.8上不起作用,执行者不喜欢它:
bash:exec:{fd}:notfound
。不过,它可以与tee>(…)一起使用!为了验证我的理解,这创建了一个新的流,tee将其视为输出文件。这反过来形成了子shell的stdin。@cjfp,…因此,在
tee>(tr…
的情况下,您要做的是生成一个文件名,当写入时,它将写入一个由
tr
读取的管道,并将该文件名作为参数传递给
tee
@cjfp,…此处答案中的原始版本是动态分配文件描述符并将其打开到这样的管道,然后传递名称
/dev/fd/NN
,其中
NN
是该文件描述符的编号,作为
tee
的参数。这只适用于文件名中支持
/dev/fd/
的操作系统,我不确定这在MacOS上是否可用——除了bash 4.2或更高版本的自动分配语法之外。这是可能的,但这是一种危险的方法。如果其中一个文件名包含字符串
$(rm-rf~)
,您将度过非常糟糕的一天。正如@CharlesDuffy所说,这是开放的代码注入,您可以使用
bash-c'echo“$1”;命令“$1”{}
来防止这种情况。更好的是,
xargs-0sh-c'用于arg;是否打印“%s\n”$arg;您的_命令“$arg”;“完成”\uu
将重用每个
sh
实例来运行多个命令。(关于:将
echo
替换为
printf
,请参阅的应用程序使用部分)。(顺便说一句,请注意,我根本没有在那里使用
xargs-I
;这是非常有意的,因为这样可以避免发生任何形式的损坏)。@cjfp,
\ucode>作为
$0
的占位符,这样以后的参数就变成了
$1
$2
,等等(这将是
“$@”
的一部分,默认情况下,
迭代)。顺便说一句,
命令实际上是所有POSIX兼容shell中内置的标准UNIX命令,因此选择不同的名称是很理想的(即,
mycommand
yourcommand
)用于用作示例或替身的内容。@CharlesDuffy修复:)好的,这在提示时起作用,但在生成文件中不起作用。即使我像这样转义括号:
\(…\)
,我也会得到
/bin/sh:/dev/tty):权限被拒绝
。我是开始一个新问题还是编辑原始问题,还是将其保留?好的,下面是关于Makefiles的后续问题: