тайм-аут stty зависает

Сделайте и то, и другое, затем отсортируйте по уникальному варианту:

(ps a; ps x) | sort -ur

Затем я отфильтровал часть шума. Это может удалить команды bash, sort и т. д., которые вы ищете :

.
(ps a; ps x) | sort -ur | grep -v "bash$\|sort$\|ps \|sshd:"
0
03.09.2021, 21:27
1 ответ

Это происходит потому, что 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), способен ловить и убивать любых дочерних элементов, порожденных командой, даже если они пытаются выйти из своей группы процессов или сеанса.

1
03.09.2021, 22:09

Теги

Похожие вопросы