Я пытаюсь написать очень минималистическую версию идеи «проглатывания окон», которая может работать с Xterm или любым эмулятором терминала, который предоставляет возможность -e
запускать указанную программу в качестве оболочки терминала.
Я написал следующий скрипт, сохранил его в run.sh
и передаю его в Xterm с помощью -e ./run.sh
run.sh:
#!/bin/sh
PROG=''
read PROG
($PROG &) && exit
Намерение состоит в том, что откроется окно Xterm, получит имя программы в качестве входных данных от пользователя, запустит программу и разветвит ее, а затем закроется. Проблема в том, что Xterm немедленно закрывается, а указанная программа никогда не открывается. Я предполагаю, что родительский процесс уничтожается до того, как дочерний процесс сможет разветвиться, но я не уверен? && exit
должен гарантировать, что родительский процесс не завершится, пока не получит код успеха от дочернего процесса.
Я изменил скрипт вот так, и он ведет себя так, как задумано:
PROG=''
read PROG
($PROG & sleep 1) && exit
Что усиливает мою гипотезу. Я хотел бы иметь возможность удалить этот сон, потому что он делает программу очень некрасивой, оставляя исходный Xterm открытым еще на секунду.
Обратите внимание, что программы, с которыми я это использую, являются графическими (на самом деле я тестирую их, запуская другое окно Xterm), поэтому при запуске они должны открывать собственное окно. Я не ожидаю, что программы CLI возьмут на себя управление окном Xterm, поскольку я намерен, очевидно, закрыть его.
Когда управляющий терминал процесса исчезнет, процесс получит SIGHUP
.
Если сон имеет значение, вы, вероятно, наблюдаете гонку между процессом, получающим SIGHUP
, и процессом, устанавливающим свои обработчики сигналов.
Традиционный способ заставить процесс игнорировать SIGHUP — использовать nohup
, но он также работает, устанавливая обработчик сигнала, поэтому не решает проблему гонки.
Вместо этого вы можете синхронно игнорировать SIGHUP
в оболочке, а затем запустить процесс в фоновом режиме:
#!/bin/sh
PROG=''
read PROG
( trap '' HUP; $PROG < /dev/null > /dev/null 2>&1 &) && exit