How to disown bash process substitution

500 Views Asked by At

To redirect stderr for a command to syslog I use a helper like

with_logger my-tag command arg1 ...

where with_logger is

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

Here 2 exec calls and the process substitution is used to avoid having a bash process waiting for the command or logger command to finish. However this creates a zombie. That is, when the logger process exits after the command exits closing its stderr, nobody waited for the process. This results in the parent process receiving an unexpected signal about unknown child processes.

To solve this I suppose I have to somehow disown the >() process. Is there a way to do it?

Update to clarify the question

I need to invoke my wrapper script from another program, not from a bash script.

Update 2 - this was a wrong question

See the answer below.

2

There are 2 best solutions below

1
On BEST ANSWER

My question was wrong.

In my setup I use supervisord to control few processes. As it has limited syslog support and does not allow to use different tags when redirecting processes' stderr to syslog, I use the above shell script for that. While testing the script I noticed CRIT reaped unknown pid <number> messages in the log for supervisord itself. I assumed that this was bad and tried to fix this.

But it turned out the messages are not critical at all. In fact supervisord was doing the proper job and in its latest source the message was changed from CRIT to INFO. So there is nothing to answer here as there are no issues with the script in question :)

2
On

I would just define a short shell function

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

and call your code with the minimally longer

2> >(to_logger my-tag) command arg1 ...

This has several benefits:

  1. The command can be any shell construct; you aren't passing the command as arguments to another command; you are just redirecting standard error of an arbitrary command.

  2. You are spawning one fewer process to handle the logging.