Как элегантно ничего не делать вечно?

Как элегантно ничего не делать вечно?

У меня есть программа, которая выдает полезную информацию на stdout, но также читает из stdin. Я хочу перенаправить ее стандартный вывод в файл, не предоставляя ничего на стандартный ввод. Пока все хорошо: Я могу сделать:

program > output

и ничего не делайте в телетайпе.

Однако проблема в том, что я хочу сделать это в фоновом режиме. Если я это сделаю:

program > output &

программа будет приостановлена ​​(«suspended (tty input)»).

Если я сделаю:

program < /dev/null > output &

программа немедленно завершается, поскольку достигает EOF.

Кажется, мне нужно перенаправить во programчто-то, что ничего не делает в течение неопределенного времени и не читает stdin. Работают следующие подходы:

while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &

Однако, это все очень некрасиво.имеетбыть элегантным способом, используя стандартные утилиты Unix, "ничего не делать, бесконечно" (перефразируя man true). Как я могу этого добиться? (Мои основные критерии элегантности здесь: никаких временных файлов; никаких активных ожиданий или периодических пробуждений; никаких экзотических утилит; как можно короче.)

решение1

Я не думаю, что вы станете более элегантными, чем

tail -f /dev/null

что вы уже предложили (предполагая, что это использует inotify внутри, не должно быть опросов или пробуждений, так что, за исключением того, что это выглядит странно, этого должно быть достаточно).

Вам нужна утилита, которая будет работать бесконечно, будет держать свой stdout открытым, но на самом деле ничего не будет писать в stdout и не будет выходить, когда ее stdin будет закрыт. Что-то вроде того, что yesна самом деле пишет в stdout. catбудет выходить, когда ее stdin будет закрыт (или что-то, что вы перенаправите в него, будет выполнено). Я думаю, что sleep 1000000000dэто может сработать, но tailявно лучше. На моем компьютере с Debian есть , tailfкоторый немного сокращает команду.

А как насчет запуска программы под управлением screen?

решение2

sleep infinityсамое ясное решение, которое я знаю.

Вы можете использовать, infinityпоскольку sleepпринимает число с плавающей точкой*, что может бытьдесятичная дробь,шестнадцатеричный,бесконечность, илиNaN, в соответствии с man strtod.

* Это не часть стандарта POSIX, поэтому не так переносимо, как tail -f /dev/null. Однако поддерживается в GNU coreutils (Linux) и BSD (используется на Mac) (по-видимому, не поддерживается в новых версиях Mac — см. комментарии).

решение3

sleep 2147483647 | program > output &

Да, 2^31-1это конечное число, и оно не будет работать.навсегда, но я дам вам 1000 долларов, когда сон наконец закончится. (Подсказка: к тому времени один из нас уже умрет.)

  • временных файлов нет; проверьте.
  • нет напряженного ожидания или периодических пробуждений; проверьте
  • никаких экзотических утилит; проверено.
  • как можно короче. Ладно, можно короче.

решение4

Вы можете создать двоичный файл, который делает именно это, с помощью:

$ echo 'main(){pause();}'| gcc -Wno-all -xc - -o pause

Я нахожу это элегантным, потому что pauseсистемный вызов — это буквально единственный системный вызов, единственной целью которого является ничегонеделание вечно (или пока сигнал не завершит процесс) без активного ожидания, выполнение этого как побочный эффект чего-то другого или без уведомления родительского процесса (родители могут элегантно неблокировать waitpidсвои дочерние процессы, останавливая их по сигналу, и многие (особенно оболочки) так и делают, в то время как гораздо сложнее дождаться блокировки дочернего процесса в системном вызове без подачи сигнала).

Связанный контент