tail nie blokuje
Jak zawsze: na wszystko jest odpowiedź, która jest krótka, łatwa do zrozumienia, łatwa do zrozumienia i całkowicie błędna. Tutaj tail -f /dev/nullnależy do tej kategorii;)
Jeśli spojrzysz na to razem strace tail -f /dev/null, zauważysz, że to rozwiązanie jest dalekie od blokowania! Prawdopodobnie jest jeszcze gorsze niż sleeprozwiązanie w pytaniu, ponieważ wykorzystuje (pod Linuksem) cenne zasoby, takie jak inotifysystem. Również inne procesy, które piszą, aby /dev/nullzrobić tailpętlę. (Na moim Ubuntu64 16.10 dodaje to kilka 10 wywołań systemowych na sekundę w już zajętym systemie).
Pytanie dotyczyło polecenia blokującego
Niestety nie ma czegoś takiego.
Przeczytaj: Nie znam sposobu, aby zarchiwizować to bezpośrednio w powłoce.
Wszystko (nawet sleep infinity) może zostać przerwane jakimś sygnałem. Więc jeśli chcesz być naprawdę pewien, że nie zwróci się wyjątkowo, musi działać w pętli, tak jak już to zrobiłeś dla twojego sleep. Należy pamiętać, że (w systemie Linux) /bin/sleepnajwyraźniej jest ograniczony do 24 dni (spójrz strace sleep infinity), dlatego najlepsze, co możesz zrobić, to prawdopodobnie:
while :; do sleep 2073600; done
(Zauważ, że uważam, że sleeppętle są wewnętrznie pętle dla wartości wyższych niż 24 dni, ale to oznacza: nie blokuje, tylko bardzo powoli się zapętla. Dlaczego więc nie przenieść tej pętli na zewnątrz?)
.. ale możesz podejść całkiem blisko z nienazwanym fifo
Możesz stworzyć coś, co naprawdę blokuje, o ile nie ma sygnałów wysyłanych do procesu. Następujące zastosowania bash 4, 2 PID i 1 fifo:
bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'
Możesz sprawdzić, czy to naprawdę blokuje, stracejeśli chcesz:
strace -ff bash -c '..see above..'
Jak to zostało skonstruowane
readblokuje się, jeśli nie ma danych wejściowych (zobacz inne odpowiedzi). Jednak tty(aka. stdin) Zwykle nie jest dobrym źródłem, ponieważ jest zamykane, gdy użytkownik się wylogowuje. Może również ukraść część danych wejściowych z tty. Niemiły.
Aby utworzyć readblok, musimy poczekać na coś takiego, fifoco nigdy nie zwróci niczego. W bash 4nie jest poleceniem, które mogą dostarczyć nam dokładnie z taką fifo: coproc. Jeśli również poczekamy na blokowanie read(które jest nasze coproc), skończymy. Niestety wymaga to otwarcia dwóch identyfikatorów PID i pliku fifo.
Wariant z nazwanym fifo
Jeśli nie zawracasz sobie głowy używaniem nazwanego fifo, możesz to zrobić w następujący sposób:
mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"
Nieużywanie pętli przy odczycie jest trochę niechlujne, ale możesz użyć tego ponownie fifotak często, jak chcesz i sprawić, że reads terminat zostanie użyty touch "$HOME/.pause.fifo"(jeśli czeka więcej niż jeden odczyt, wszystkie są przerywane jednocześnie).
Lub użyj pause()wywołania systemowego Linux
W przypadku nieskończonego blokowania istnieje wywołanie jądra Linuksa, o nazwie pause(), które robi to, co chcemy: Czekaj wiecznie (aż nadejdzie sygnał). Jednak nie ma do tego (jeszcze) programu przestrzeni użytkownika.
do
Stworzenie takiego programu jest łatwe. Oto fragment stworzyć bardzo mały program o nazwie Linux pause, który wstrzymuje na czas nieokreślony (potrzeb diet, gccetc.):
printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause
python
Jeśli nie chcesz samemu kompilować czegoś, ale masz już pythonzainstalowany, możesz użyć tego pod Linuksem:
python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'
(Uwaga: użyj exec python -c ...do zastąpienia bieżącej powłoki, zwalnia to jeden PID. Rozwiązanie można również ulepszyć za pomocą niektórych przekierowań we / wy, zwalniając nieużywane FD. To zależy od Ciebie.)
Jak to działa (chyba): ctypes.CDLL(None)ładuje standardową bibliotekę C i uruchamia pause()w niej funkcję w ramach dodatkowej pętli. Mniej wydajna niż wersja C, ale działa.
Moja rekomendacja dla Ciebie:
Pozostań w zapętlonym śnie. Jest łatwy do zrozumienia, bardzo przenośny i przez większość czasu blokuje.