Unix: uśpienie do określonego czasu

12

Czy istnieje (pół-) standardowe polecenie uniksowe, które śpi do czasu określonego w wierszu poleceń? Innymi słowy, szukam czegoś podobnego sleep, co zająłoby raczej czas budzenia niż czas trwania.

Na przykład: sleeptill 05:00:00

Mogę coś zaprogramować, ale wolałbym nie wymyślać od nowa koła, jeśli już coś tam jest.

Dodatkowe pytanie: byłoby wspaniale, gdyby mógł zająć strefę czasową (jak w sleeptill 05:00:00 America/New_York).

edytuj Ze względu na naturę tego, co robię, szukam rozwiązania „uśpienie do T” zamiast „uruchom polecenie w T”.

edytuj Aby uniknąć wątpliwości, jeśli uruchomię polecenie o godzinie 18:00 i powiem, aby obudził się o godzinie 17:00, spodziewam się, że będzie spał przez 23 godziny (lub, w niektórych przypadkach związanych z czasem letnim, przez 22 lub 24 godziny).

NPE
źródło
Chyba mógłbyś użyć cron.
Bobby,
Dzięki, ale do zamierzonego zastosowania to naprawdę musi być sleeppodobne.
NPE
Podobne pytanie na Unix.SE
palswim 24.04.19

Odpowiedzi:

18

Jeśli korzystasz z Uniksa, który ma porządną datę i używasz bash, możesz użyć formatu% s do obliczenia czasu.

sleep $(( $(date -j 1700 +%s) - $(date +%s) ))

(1700 to 17.00, a -j mówi datę, żeby nie ustawiać daty)

w00t
źródło
(+1) za sugestię. Jeśli uruchomię polecenie o godzinie 18:00 i każę mu się obudzić o godzinie 17:00, spodziewam się, że będzie spał przez 23 godziny (lub, w niektórych przypadkach związanych z czasem letnim, przez 22 lub 24 godziny). To tam sugestia niestety się załamuje. [Musiałam też zmienić -jsię -d. Aby go uruchomić na moich systemów Linux]
NPE
7
@ aix: W Linuksie (i innych systemach z datą GNU) możesz używać zaawansowanych specyfikacji dat, takich jak date -d 'tomorrow 17:00'.
Gilles „SO- przestań być zły”
3
@NPE, btw, można wyrównać za pomocą przypominania-podział: echo $(( ($(date -d "3:00" +%s) - $(date +%s) + (60*60*24)) % (60*60*24) ))(nie może być tylko niektóre zagadnienia wokół DST-zmianami)
HVR
13

Co powiesz na to (łączenie pomysłów W00T i Gille'a w funkcję)?

function sleep_until {
  seconds=$(( $(date -d "$*" +%s) - $(date +%s) )) # Use $* to eliminate need for quotes
  echo "Sleeping for $seconds seconds"
  sleep $seconds
}

Stosowanie:

sleep_until 8:24
Sleeping for 35 seconds

sleep_until '23:00'
Sleeping for 52489 seconds

sleep_until 'tomorrow 1:00'
Sleeping for 59682 seconds
Tyler Rick
źródło
9

Sprawdź atkomendę linux / unix . Korzystając z przykładu 5AM:

at 05:00 some_command

Obsługuje także strefy czasowe:

Można podać nazwę strefy czasowej GMT, UCT lub ZULU (bez rozróżniania wielkości liter), aby określić, że czas jest w uniwersalnym czasie koordynowanym. Inne strefy czasowe można określić za pomocą zmiennej środowiskowej TZ.

Jeremy L.
źródło
(+1) za sugestię. Niestety nie pasuje naturalnie do mojego przepływu pracy. Mam skrypt, który uruchamia kilka rzeczy po kolei i chcę się upewnić, że pewne kroki nie zostaną uruchomione do określonych czasów. Można to oczywiście przekształcić w coś, co wykorzystuje cronlub at, ale byłoby to trudne. To jest powód, dla którego szukam czegoś sleeppodobnego. Na razie napisałem własny.
NPE
Ach, więc chcesz harmonogram blokowania. Dlaczego nie mieć pliku stanu śledzącego każdy etap procesu?
Jeremy L,
Mógłby, ale brzmi to trochę bardziej skomplikowanie, niż myślę, że musi być. Kroki są rozbieżnymi poleceniami, a skrypt powłoki jest tym, co organizuje przepływ pracy. Możliwość „spania do 17:00” w skrypcie jest wszystkim, czego naprawdę potrzebuję.
NPE
W takim przypadku odpowiedź w00t może być dokładnie tym, czego szukasz.
Jeremy L,
Tak, to zdecydowanie we właściwym duchu. Niestety, rozkłada się w niektórych ważnych (dla mnie) przypadkach i nie robi stref czasowych.
NPE