Сделайте и то, и другое, затем отсортируйте по уникальному варианту:
(ps a; ps x) | sort -ur
Затем я отфильтровал часть шума. Это может удалить команды bash, sort и т. д., которые вы ищете :
.(ps a; ps x) | sort -ur | grep -v "bash$\|sort$\|ps \|sshd:"
Это происходит потому, что timeout
запускает команду в фоновом режиме в отдельной группе процессов.
Когда процесс a )подключен к управляющему терминалу и b )не находится в группе переднего плана и пытается изменить настройки терминала с помощью tcsetattr()
, он получает сигнал SIGTTOU
, который останавливает его.
Именно это и произошло в вашем примере.
В GNU timeout
есть опция для этого :--foreground
, которую вы можете безопасно использовать с простыми программами, которые пытаются возиться с управляющим терминалом, но не разветвляются , потому что тогда их потомки не будут быть убитым.
Возможные обходные пути:
a)перенаправить stdin/stdout/stderr программ из другого места в надежде, что они не будут открываться /dev/tty
явно и оставят управляющий терминал в покое
b)если они не могут быть убеждены с помощью ), тогда дайте им собственный псевдо-терминал -для запуска, что вы можете сделать с помощью программы, подобной script(1)
. Обратите внимание, что вы должны применить обработку )к script(1)
, так как он пытается прочитать из стандартного ввода (, который получит сигнал SIGTTIN
), и он попытается сделать это с помощью tcseattr()
(, который получит сигнал SIGTTOU
):
% cat <<'EOT' > sample.sh; chmod +x sample.sh
#!/bin/sh
t=$(stty -g -F /dev/tty)
sleep 1000 &
echo BEFORE; stty -F /dev/tty "$t"; echo AFTER
EOT
% sh -c 'timeout 2./sample.sh'
BEFORE
# hangs for 2 seconds and exits without writing 'AFTER'
%
% sh -c 'timeout 2 script /dev/null </dev/null -qc./sample.sh'
BEFORE
AFTER
# and it exits immediately
% pgrep sleep
# nothing, the child was killed too
Обратите внимание, что script(1)
не стандартизирован и его синтаксис отличается в других системах, кроме Linux, поэтому вам придется адаптировать пример.
c)если у вас есть systemd, используйте systemd-run -t --user
, который, (в отличие от timeout
), способен ловить и убивать любых дочерних элементов, порожденных командой, даже если они пытаются выйти из своей группы процессов или сеанса.