Мне нужно выполнить практически произвольные команды на (удаленной) оболочке в эфемерных контейнерах/виртуальных машинах для механизма выполнения тестов. Иногда эти процессы утечки, которые затем приводят к зависанию всей команды. Это может быть сводились к этой простой команды:shell: очистить протекающие фоновые процессы, зависающие из-за совместного использования stdout/stderr
$ sh -c 'sleep 30 & echo payload'
payload
$
Здесь представлена справочная информация sleep 30
играет роль просочилась процесса (который на самом деле будет что-то вроде dbus-daemon
) и эхо является фактическим, что я хочу работать. sleep 30 & echo payload
следует рассматривать как атомную непрозрачную команду примера здесь.
Вышеуказанная команда в порядке и немедленно возвращается, так как stdout/stderr сна также являются PTY. Тем не менее, при захвате вывода команды в трубе/файл (тест бегун хочет сохранить все в журнал, в конце концов), вся команда зависание:
$ sh -c 'sleep 30 & echo payload' | cat
payload
# ... does not return to the shell (until the sleep finishes)
Теперь, это может быть исправлено с некоторыми довольно смехотворно сложная оболочечная магия, которая определяет FDs stdout/err от /proc/$$/fd/{1,2}
, итерации над ls /proc/[0-9]*/fd/*
и убийства каждого процесса, который также имеет тот же stdout/stderr. Но это связано с большим количеством хрупкого кода оболочки и дорогостоящих сравнений строк оболочки.
Есть ли способ очистить эти пропущенные фоновые процессы более элегантным и простым способом? setsid
не помогает:
$ sh -c 'setsid -w sh -c "sleep 30 & echo payload"' | cat
payload
# hangs...
Обратите внимание, что группы процессов/сессии и их убийство оптовыми не является достаточным, как просочились процессы (например, Dbus-демон) часто setsid себя.
P.S. Я могу только предполагать оболочку POSIX или bash в этих средах; нет Python, Perl и т. д.
Спасибо заранее!
Следующие работы, но я не могу ответить на этот вопрос: 'sh -c '{sleep 30 | Кот ; } & {echo полезная нагрузка | Кот ; } '' –
Спасибо, но я специально не ищу решение для сна и эха; это всего лишь пример команды для ситуации «некоторая команда утечки фоновой команды». Я добавил некоторые разъяснения к вопросу. –
Я нашел начальное приближение: '$ setsid -w sh -c 'sleep 30 & echo полезная нагрузка; RC = $ ?; для p в $ (pgrep --pgroup 0); do [$ p = $$] || kill $ p; сделанный; exit $ RC '| cat' Просто использование 'kill - - $$' слишком агрессивное, поскольку оно также убивает оболочку. –