I need to redirect output from udevadm monitor
to a named pipe. For that end I use the following command:
sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test &
It works until a process reading from the pipe is interrupted and socat
exists with a "Broken pipe" error, which is expected. However, when I list running processes it turns out that udevadm
is still running.
$ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3972 pts/0 00:00:00 ps $ sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test & [1] 3973 $ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3973 pts/0 00:00:00 sudo 3974 pts/0 00:00:00 socat 3975 pts/0 00:00:00 socat 3976 pts/0 00:00:00 udevadm 3977 pts/0 00:00:00 ps $ cat /tmp/test monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent ^C $ 2020/06/01 12:36:06 socat[3974] E write(6, 0x1dfbc60, 147): Broken pipe [1]+ Exit 1 sudo socat -u SYSTEM:"udevadm monitor" PIPE:/tmp/test $ ps -a PID TTY TIME CMD 3539 tty1 00:00:00 bash 3619 tty2 00:00:00 bash 3976 pts/0 00:00:00 udevadm 3980 pts/0 00:00:00 ps $
When I replaced udevadm monitor
with yes
(to simply feed a stream of data to the pipe), it died along with socat
.
If I simply interrupt socat
with kill
command, udevadm
perishes neatly.
If I kill parent bash process socat
and udevadm
die as well, so I tried wrapping udevadm
with sh -c
:
sudo socat -u SYSTEM:'sh -c \"udevadm monitor\"' PIPE:/tmp/test &
hoping that dying shell would kill udevadm
, but to no avail.
I am aware, that orphaned process can be adopted by INIT, but it doesn't seem to be the case, because out of all processes only udevadm
seems to cheat death like this. To sum up my experiments:
- Process tree bash->sudo->socat->udevadm - kill
socat
- all die - Process tree bash->sudo->socat->udevadm - broken pipe - only udevadm lives on
- Process tree bash->sudo->socat->sh->udevadm - broken pipe - only udevadm lives on
- Process tree bash->sudo->socat->yes- broken pipe - all die
- Process tree bash->sudo->socat->udevadm - kill sudo - all die
- Process tree bash->sudo->socat->udevadm - kill bash - all die
The problem I really want to solve are lingering udevadm
processes.
My preferred solution would be to udevadm
die nicely along with other processes. Acceptable solution would be to have persistent pipe, which would not break when reading process dies.
Are there any options or settings I can pass either to socat
or to udevadm
to solve my problem?
If socat
if a wrong tool for my ultimate objective to have udevadm
output sent to a pipe, I am obviously open for suggestions.