Powłoka: czy można opóźnić polecenie bez użycia polecenia „sleep”?


21

Czy są jakieś substytuty, alternatywy lub sztuczki do opóźniania poleceń bez użycia sleep? Na przykład wykonanie poniższej komendy bez użycia trybu uśpienia:

$ sleep 10 && echo "This is a test"

42
Co jest nie tak z sleep?
mur

5
Nie ma innego powodu niż ciekawość. Pomyślałem, że interesujące byłoby poznanie alternatywnych rozwiązań. Myślę, że atmoże być jeden, ale nie mogłem znaleźć żadnych przykładów użycia.
user321697,

1
@ user321697 „at” ma zaplanować pojedyncze zadania. są one wykonywane przez usługę atd, więc nie wstrzymają skryptu powłoki. jednym z przypadków użycia at at może być zrobienie czegoś w określonym czasie (asynchronizacja) i utworzenie pliku znacznika po zakończeniu, podczas gdy skrypt czeka na pojawienie się tego pliku w pętli while. podobny efekt można osiągnąć, planując zadanie wysyłania skryptu SIGCONT, a następnie zamrażając skrypt, wysyłając sobie SIGSTOP.
Grega Bremec,

1
Przybyłem tutaj, oczekując, że wszyscy zasugerują blokadę. Jestem mile zaskoczony wszystkimi odpowiedziami.
Daan van Hoek

3
Re: „Ciekawość” - w unix.stackexchange.com/help/dont-ask , trzeba pamiętać, że wymóg „Należy zwrócić tylko praktyczne, odpowiada na pytania na podstawie rzeczywistych problemów, które możesz napotkać. - że to było dobrze otrzymane pomimo sprzeczności z tą wytyczną czyni to raczej rzadkim wyjątkiem.
Charles Duffy

Odpowiedzi:


17

Masz alternatywy dla sleep: Są ati cron. W przeciwieństwie do sleeptych, musisz podać czas, w którym chcesz je uruchomić.

  • Upewnij się, że atdusługa działa, wykonując service atd status.
    Powiedzmy teraz, że jest godzina 11:17 UTC; jeśli trzeba wykonać polecenie na 11:25 UTC, składnia jest: echo "This is a test" | at 11:25.
    Teraz pamiętaj, że atddomyślnie nie będzie rejestrować ukończenia zadań. Aby uzyskać więcej, zapoznaj się z tym linkiem . Lepiej, aby aplikacja miała własne logowanie.

  • Możesz zaplanować zadania w cron, aby uzyskać więcej informacji: man cronzobacz jego opcje lub crontab -edodaj nowe zadania. /var/log/cronmożna sprawdzić w celu uzyskania informacji o wykonywaniu zadań.

FYI sleep system call zawiesza bieżące wykonanie i planuje zapisanie przekazanego argumentu.

EDYTOWAĆ:

Jak wspomniano w @Gaius, możesz również dodać minuty czasu do atpolecenia, ale powiedzmy, że czas jest, 12:30:30a teraz uruchomiłeś harmonogram now +1 minutes. Mimo że podano 1 minutę, co przekłada się na 60 sekund, attak naprawdę nie czeka aż 12:31:30do wykonania zadania, a raczej wykonuje zadanie o 12:31:00. Jednostki czasu mogą być minutes, hours, days, or weeks. Aby uzyskać więcej informacjiman at

na przykład: echo "ls" | at now +1 minutes


7
To nie jest prawda, możesz zaplanować pracę, powiedzmy teraz +1 minutę, aby biegła za minutę
Gaius

29

Dzięki bashwbudowanym funkcjom możesz:

coproc read -t 10 && wait "$!" || true

Spać przez 10 sekund bez użycia sleep. coprocJest aby tak, że read„s stdin jest rura gdzie nic nigdy nie wyjdzie z. || truejest ponieważ waitstatus wyjścia będzie odzwierciedlał dostarczenie SIGALRM, które spowodowałoby zamknięcie powłoki, jeśli errexitopcja jest ustawiona.

W innych muszlach:

mkshi ksh93mają sleepwbudowane, nie ma sensu używać niczego innego (chociaż oba one również obsługują read -t).

zshobsługuje również read -t, ale ma również wbudowane opakowanie select(), więc możesz również użyć:

zmodload zsh/zselect
zselect -t 1000 # centiseconds

Jeśli chcesz zaplanować uruchamianie rzeczy z interaktywnej sesji powłoki, zobacz także zsh/schedmoduł wzsh .


Zastanowiłbyś się read -t 10 < /dev/zero || true?
Jeff Schaller

5
@JeffSchaller Unikałbym tego, ponieważ jest to zajęta pętla.
Stéphane Chazelas,

@ StéphaneChazelas Nie spodziewałbym się, że będzie to zajęta pętla - oczekiwałbym, że każda powłoka readzostanie zaimplementowana przy użyciu select (2) lub czegoś podobnego (co sugeruje, że odpowiedź na żądanie byłaby dobrą odpowiedzią na to pytanie). Wyrażam raczej zdziwienie niż zaprzeczenie, ale czy możesz wskazać na dalszą dyskusję na ten temat?
Norman Gray,

5
@NormanGray, /dev/zeroto plik zawierający nieskończoną ilość danych (NUL bajtów). readCzyta więc tyle, ile może podczas tych 10 sekund. Na szczęście, w przypadku, bashgdy nie obsługuje przechowywania bajtów NUL w jego zmiennych, nie zużyje to żadnej pamięci, ale nadal będzie pochłaniać zasoby procesora.
Stéphane Chazelas,

1
@NormanGray, jeśli zostanie uruchomiony z terminala, /dev/stdoutbędzie urządzeniem tty, więc będzie miał skutki uboczne (takie jak zatrzymanie skryptu, jeśli zostanie uruchomiony w tle) i zwróci, jeśli na przykład użytkownik naciśnie klawisz Enter. read -t 10 /dev/stdout | :działałby w systemie Linux, ale tylko w systemie Linux, podczas gdy coprocpowinien działać niezależnie od systemu operacyjnego.
Stéphane Chazelas,

7

Kilka innych pomysłów.

top -d10 -n2 >/dev/null

vmstat 10 2 >/dev/null

sar 10 1 >/dev/null

timeout 10s tail -f /dev/null

1
„Ukradłeś” mój pomysł na ograniczenie czasowe / przekroczenie limitu czasu .... +1
Rui F Ribeiro

1
Ohhhh, dzięki, byłem w sytuacji bez snu, top jest niesamowity!
Fire-Dragon-DoL

6

Ponieważ istnieją odpowiedzi, które sugerują skorzystanie z niestandardowej -t delayopcji read, oto sposób na odczytywanie limitów czasu w standardowej powłoce:

{ ss=`stty -g`; stty -icanon min 0 time 20; read foo; stty "$ss"; }

Argument stty timejest za dziesiąte sekundy.


5

Korzystanie z wbudowanej zmiennej bash $SECONDSi pętli zajętości:

for((target=$((SECONDS + 10)); SECONDS < target; true)); do :; done

2
To w efekcie zatrzymałoby się na czas od 9 do 10 sekund (z powodu błędu wbash ; zshi mkshmiał podobne problemy, ale od tego czasu zostały naprawione)
Stéphane Chazelas

7
Dobry sposób na wytwarzanie ciepła.
ctrl-alt-delor

6
nie pierwszy raz będę oskarżony o bycie gorącym powietrzem! :)
Jeff Schaller

4

najstarsza sztuczka w książce:

read && echo "This is a test"

Po prostu naciśnij, Entera będzie kontynuowane!


Nie stanie się tak, jeśli proces będzie wymagał uruchomienia bez interakcji lub w tle, prawda?
ss_iwe

Prawidłowo: Ale to nie było jedno z wymagań OP w pierwotnym pytaniu, więc wciąż ważna odpowiedź ... ;-)> :-)
Fabby

1
OP konkretnie podaje przykład (z sleep) i prosi o równoważną alternatywę bez. readPrzepraszam, więc się nie analizuje. ;)
AnoE,

@AnoE Odpowiedź Stéphane'a jest oczywiście najlepsza, moja jest tylko najstarsza --- press «enter» to continue --- ;-)
Fabby

4

W czasach mikrokomputerów z systemem BASIC opóźnienia były zwykle osiągane za pomocą pustej pętli:

FOR I = 1 TO 10000:NEXT

Tej samej zasady można użyć do wstawienia opóźnienia w skrypcie powłoki:

COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done

Oczywiście problemem związanym z tym podejściem jest to, że długość opóźnienia będzie się różnić w zależności od szybkości procesora (lub nawet na tej samej maszynie pod różnymi obciążeniami). W przeciwieństwie do sleeptego, prawdopodobnie spowoduje to również maksymalne obciążenie twojego procesora (lub jednego z jego rdzeni).


2
Dobry sposób na wytwarzanie ciepła.
ctrl-alt-delor

2
Pętle opóźniające są okropnym pomysłem na wszystko oprócz najkrótszych okresów uśpienia (kilka nanosekund lub cykli zegara w sterowniku urządzenia) na każdym nowoczesnym procesorze, który może obsługiwać system operacyjny podobny do Uniksa. tj. sen tak krótki, że procesor nie może pożytecznie nic zrobić podczas oczekiwania, np. zaplanować inny proces lub przejść w stan uśpienia o niskim poborze mocy przed wybudzeniem się po przerwie czasowej. Dynamiczna częstotliwość procesora uniemożliwia nawet skalibrowanie pętli opóźnień dla zliczeń na sekundę, z wyjątkiem minimalnego opóźnienia potencjalnie śpiącego znacznie dłużej przy niskich częstotliwościach zegara przed przyspieszeniem.
Peter Cordes,

Starożytne komputery miały zużycie energii znacznie mniej zależne od obciążenia. Nowoczesne procesory muszą dynamicznie wyłączać różne części układu tak bardzo, jak to możliwe, aby się nie stopiły (np. Wyłączają części jednostek wykonawczych FPU lub SIMD, gdy działa tylko kod całkowity, lub przynajmniej przesyłają sygnał zegara do części układu które nie muszą się przełączać). I przejście w stan uśpienia o niskiej mocy, gdy bezczynny (zamiast wirowania w nieskończonej pętli w oczekiwaniu na przerwania timera) jest również nowszy niż starożytne komputery, o których wspomniałeś.
Peter Cordes,

Aby uzyskać więcej informacji na temat historii procesora, zobacz Nowoczesne mikroprocesory 90-minutowy przewodnik! - lighterra.com/papers/modernmicroprocessors .
Peter Cordes,

3

Nie ma wbudowanego, który robi to samo co sleep(chyba żesleep jest wbudowany). Istnieją jednak inne polecenia, które będą czekać.

Kilka to.

  • ati cron: używane do planowania zadań w określonym czasie.

  • inotifywait: używane do oczekiwania na plik lub pliki do zmodyfikowania / usunięcia / dodania / itp


Dzięki za to. Czy możesz podać przykład wykonania zaplanowanego zadania (za 10 sekund) at?
user321697,

1
edycja i opinia! ;-)
Fabby

cronprzechowywać zadania w crontab, prawda? Gdzie są atprzechowywane zaplanowane dane?
user321697,

@ user321697 Już odpowiedziałem tutaj
Fabby

Przepraszamy za przywrócenie edycji do Q: zmieniłeś główny cel pytania OP, który unieważniłby najprostszą odpowiedź ze wszystkich ... ¯ \ _ (ツ) _ / ¯
Fabby

3

Klasyk z Krainy Windows i partii:

ping -c 11 localhost >/dev/null && echo "This is a test"

Błędna konfiguracja zapory lub systemu nazw może spowodować znaczne dodatkowe opóźnienie.
spectras

1
127.0.0.1 ... @spectras
AnoE

1
Na szczęście nie jest już potrzebny, ponieważ system Windows obsługuje teraz tryb uśpienia natywnie.
Baldrickk,

1
@AnoE> rozwiązuje część systemu nazw, a nie część zapory. Chociaż nie jest to powszechne, można go skonfigurować tak, aby dyskretnie upuszczał polecenia ping na interfejs lokalny. Spowoduje to, że ping będzie czekać znacznie dłużej.
spectras

+1 za „miłe” wspomnienia
AC

0

Jeśli chcesz interaktywnie czekać na nową linię w pliku, to

tail -f
.

Czekasz na zmianę w systemie plików? Następnie użyj np

inotify / inoticoming
.

I są inne opcje, w zależności od tego, co masz na myśli przez „czekać”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.