tail
не блокує
Як завжди: На все є відповідь, який короткий, легкий для розуміння, простий у дотриманні та зовсім неправильний. Тут tail -f /dev/null
підпадає під цю категорію;)
Якщо ви подивитесь на це, strace tail -f /dev/null
ви помітите, що це рішення далеко не блокування! Це, мабуть, навіть гірше, ніж sleep
вирішення питання, оскільки воно використовує (під Linux) дорогоцінні ресурси, як inotify
система. Також інші процеси, які пишуть для /dev/null
створення tail
циклу. (У моєму Ubuntu64 16.10 це додає кілька 10 системних дзвінків в секунду у вже зайнятій системі.)
Питання полягало у блокуванні команди
На жаль, такого немає ..
Читайте: я не знаю жодного способу безпосередньо це архівувати разом із оболонкою.
Все (навіть sleep infinity
) може бути перерване якимсь сигналом. Отже, якщо ви хочете бути впевнені, що це не винятково повертається, воно повинно працювати в циклі, як ви вже робили для свого sleep
. Зверніть увагу, що (в Linux), /bin/sleep
мабуть, обмежено 24 дні (подивіться strace sleep infinity
), отже, найкраще, що ви можете зробити, це:
while :; do sleep 2073600; done
(Зверніть увагу, що я вважаю sleep
, що циклічно циклічні для більш високих значень, ніж 24 дні, але це означає: це не блокує, дуже повільно циклічно. Тож чому б не перемістити цю петлю назовні?)
.. але ви можете підійти зовсім поруч з неназваним fifo
Ви можете створити щось, що насправді блокує, поки в процес не надходять сигнали. Наступне використання bash 4
, 2 PID та 1 fifo
:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Ви можете перевірити, чи дійсно це блокується, strace
якщо вам подобається:
strace -ff bash -c '..see above..'
Як це було побудовано
read
блокує, якщо немає вхідних даних (див. деякі інші відповіді). Однак зазвичай tty
(ака. stdin
) Не є хорошим джерелом, оскільки він закритий, коли користувач виходить із системи. Крім того, він може вкрасти деякий внесок у tty
. Недобре.
Щоб зробити read
блок, нам потрібно чекати чогось подібного, fifo
яке ніколи нічого не поверне. В bash 4
є команда , яка може точно надати нам такі fifo
: coproc
. Якщо ми також будемо чекати блокування read
(яке є нашим coproc
), ми закінчили. На жаль, для цього потрібно залишати відкритими два PID та a fifo
.
Варіант із названим fifo
Якщо ви не переймаєтесь іменем fifo
, ви можете зробити це наступним чином:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Не використовувати цикл для читання є трохи неохайним, але ви можете використовувати це повторно fifo
так часто, як вам подобається, і зробити read
термінал s за допомогою touch "$HOME/.pause.fifo"
(якщо очікується більше одного очікування читання, всі припиняються одразу).
Або скористайтеся системою pause()
виклику Linux
Для нескінченного блокування існує дзвінок ядра Linux, який називається pause()
, який робить те, що ми хочемо: зачекайте вічно (поки не надійде сигнал). Однак для цього немає програми для простору користувачів.
С
Створити таку програму досить просто. Ось фрагмент коду , щоб створити дуже невелику програму Linux під назвою , pause
яка робить паузу на невизначений термін (потреби diet
, і gcc
т.д.):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
Якщо ви не хочете щось самостійно складати, але ви python
встановили, ви можете використовувати це під Linux:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Примітка. Використовуйте exec python -c ...
для заміни поточної оболонки, це звільняє один PID. Рішення можна вдосконалити також за допомогою перенаправлення вводу-виводу, звільнивши невикористані диски. Це залежить від вас.)
Як це працює (я думаю): ctypes.CDLL(None)
завантажує стандартну бібліотеку C і виконує pause()
функцію в ній в якомусь додатковому циклі. Менш ефективний, ніж версія С, але працює.
Моя рекомендація для вас:
Залишайтеся на петельному сні. Це легко зрозуміти, дуже портативний і блокує більшу частину часу.