Mam skrypt powłoki, który działa w systemie Linux i używa tego wywołania, aby uzyskać wczorajszą datę w YYYY-MM-DD
formacie:
date -d "1 day ago" '+%Y-%m-%d'
Działa przez większość czasu, ale kiedy skrypt został uruchomiony wczoraj rano 2013-03-11 0:35 CDT
, "2013-03-09"
zamiast tego powrócił "2013-03-10"
.
Prawdopodobnie winny jest czas letni (który rozpoczął się wczoraj). Domyślam się, że sposób "1 day ago"
jest zaimplementowany to odjęto 24 godziny, a 24 godziny wcześniej 2013-03-11 0:35 CDT
było 2013-03-09 23:35 CST
, co doprowadziło do wyniku "2013-03-09"
.
Więc jaki jest dobry, bezpieczny dla czasu letniego sposób na uzyskanie wczorajszej daty w bash w systemie Linux?
Odpowiedzi:
Myślę, że to powinno działać, niezależnie od tego, jak często i kiedy je uruchamiasz ...
źródło
date -d yesterday 13:00 -I
data w systemie Mac OSX jest nieco inna.
Na wczoraj
W zeszłym tygodniu
źródło
gdate
, dostępnego wcoreutils
pakiecie homebrew .date
jest inny.To też powinno działać, ale może to za dużo:
źródło
date
który nie obsługujeyesterday
składni ...Jeśli masz pewność, że skrypt działa w pierwszych godzinach dnia, możesz to po prostu zrobić
BTW, jeśli skrypt jest uruchamiany codziennie o 00:35 (przez crontab?), Powinieneś zadać sobie pytanie, co się stanie, jeśli zmiana czasu letniego nastąpi o tej godzinie; skrypt nie mógł się uruchomić lub w niektórych przypadkach uruchomić dwukrotnie. Nowoczesne implementacje
cron
są jednak pod tym względem sprytne .źródło
możesz użyć
aby uzyskać datę sprzed 30 dni, analogicznie możesz zamienić 30 na x ilość dni
źródło
%Y%m%d
aby pasował do pytania. I tak zagłosowałem za, ponieważ działało poprawnie.Tutaj rozwiązanie, które będzie działało również z Solarisem i AIXem.
Manipulowanie strefą czasową jest możliwe w celu zmiany zegara o kilka godzin. Ze względu na czas letni, 24 godziny temu może być dzisiaj lub przedwczoraj.
Jesteś pewien, że wczoraj było 20 lub 30 godzin temu. Który? Cóż, najnowszy, którego nie ma dzisiaj.
Parametr -e użyty w poleceniu echo jest potrzebny w bash, ale nie będzie działał z ksh. W ksh możesz użyć tego samego polecenia bez flagi -e.
Gdy twój skrypt będzie używany w różnych środowiskach, możesz uruchomić skrypt za pomocą #! / Bin / ksh lub #! / Bin / bash. Możesz także zastąpić \ n nową linią:
źródło
Po prostu użyj
date
i zaufane sekundy:Jak słusznie zauważyłeś, wiele szczegółów dotyczących podstawowych obliczeń jest ukrytych, jeśli polegasz na angielskiej arytmetyce czasu. Np.
-d yesterday
I-d 1 day ago
będzie się zachowywał inaczej.Zamiast tego możesz niezawodnie polegać na (dokładnie udokumentowanych) sekundach od czasu UTC w epoce unixa i na arytmetyce basha, aby uzyskać odpowiedni moment:
Wskazano na to w innej odpowiedzi . Ten formularz jest bardziej przenośny na różnych platformach z różnymi
date
flagami wiersza poleceń, jest niezależny od języka (np. „Wczoraj” kontra „hier” w języku francuskim) i, szczerze mówiąc (w dłuższej perspektywie), będzie łatwiejszy do zapamiętania, ponieważ już to wiem. W przeciwnym razie możesz zadawać sobie pytanie: „Czy to było-d 2 hours ago
czy-d 2 hour ago
znowu?” lub „Czy to-d yesterday
albo-d 1 day ago
że chcę?”). Jedynym trudnym fragmentem jest tutaj@
.Uzbrojony w bash i nic więcej:
Bash wyłącznie na bash, możesz również uzyskać wczorajszy czas, za pomocą wbudowanego printf:
Więc,
lub równoważnie ze zmienną temp (zewnętrzna podpowłoka jest opcjonalna, ale utrzymuje zmienne środowiskowe w czystości).
Uwaga: pomimo strony podręcznika informującej, że żaden argument do programu
%()T
formatującego nie przyjmie wartości domyślnej-1
, zamiast tego wydaje mi się, że otrzymuję 0 (dziękuję, wersja podręcznika bash 4.3.48)źródło
Aby użyć tego później:
źródło
Możesz użyć:
Lub czas, który chcesz odzyskać, zostanie pobrany przez bash.
Za miesiąc:
źródło
Ponieważ to pytanie jest oznaczone grzmotnąć „DST bezpieczny”
Używając widelca do
date
polecenia implie delay, istnieje prosty i bardziej wydajny sposób użycia wbudowanego czystego bash :Jest to o wiele szybsze na bardziej przyjaznym dla systemu niż konieczność rozwidlania się
date
.Z grzmotnąćV> = 5,0 , jest nowa zmienna
$EPOCHSECONDS
źródło