如何拒绝bash进程替换

时间:2014-11-21 20:50:49

标签: bash process-substitution

要将stderr的命令重定向到syslog,我使用像

这样的帮助器
with_logger my-tag command arg1 ...

其中with_logger是

#!/bin/bash
syslog_tag="$1"
shift
exec "$@" 2> >(exec /usr/bin/logger -t "$syslog_tag")

这里有2个exec调用和进程替换用于避免让bash进程等待命令或logger命令完成。然而,这会产生一个僵尸。也就是说,当命令退出关闭其stderr后退出记录器进程时,没有人等待该进程。这导致父进程收到有关未知子进程的意外信号。

要解决这个问题,我想我必须以某种方式否定>()进程。有办法吗?

更新以澄清问题

我需要从另一个程序调用我的包装器脚本,而不是从bash脚本调用。

更新2 - 这是一个错误的问题

请参阅下面的答案。

2 个答案:

答案 0 :(得分:1)

我只想定义一个简短的shell函数

to_logger () {
    exec /usr/bin/logger -t "$1"
}

并使用最短的

来调用您的代码
2> >(to_logger my-tag) command arg1 ...

这有几个好处:

  1. 该命令可以是任何shell构造;你没有将命令作为参数传递给另一个命令;你只是重定向任意命令的标准错误。

  2. 您正在产生少一个处理日志记录的流程。

答案 1 :(得分:0)

我的问题是错的。

在我的设置中,我使用supervisord来控制几个进程。因为它限制了syslog支持,并且在重定向进程时不允许使用不同的标记。 stderr到syslog,我使用上面的shell脚本。在测试脚本时,我注意到日志中的CRIT reaped unknown pid <number>消息,用于监督本身。我认为这很糟糕,并试图解决这个问题。

但事实证明这些消息并不重要。实际上,supervisord正在做正确的工作,并且在最新的source中,消息从CRIT更改为INFO。所以这里没有什么可回答的,因为有问题的脚本没有问题:)