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