Próbuję uzyskać datę ostatniej modyfikacji pliku za pomocą tego polecenia
TM_LOCAL=`ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
TM_LOCAL ma wartość „2012-05-16 23:18” po wykonaniu tego wiersza
Chciałbym również sprawdzić PIPESTATUS, aby zobaczyć, czy wystąpił błąd. Na przykład, jeśli plik nie istnieje, ls
zwraca 2. Ale $?
ma wartość 0, ponieważ ma wartość zwracaną awk
.
Jeśli uruchomię to polecenie sam, mogę sprawdzić zwracaną wartość ls, patrząc na ${PIPESTATUS[0]}
ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'
Ale $PIPESTATUS
nie działa tak, jak się spodziewałem, jeśli przypiszę wynik do zmiennej, tak jak w pierwszym przykładzie. W tym przypadku $PIPESTATUS
tablica ma tylko 1 element, który jest taki sam jak$?
Pytanie brzmi: w jaki sposób mogę uzyskać oba $PIPESTATUS
i jednocześnie przypisać dane wyjściowe do zmiennej?
Użyj
set -o pipefail
w,bash
aby uzyskać najbardziej niezerowy kod wyjścia w potokowej sekwencji poleceń jako$?
. Odman bash
:Następnie możesz po prostu uzyskać dostęp
$?
. Użyj,set +o pipefail
aby wyłączyć ponownie.źródło
Zakładam, że problemem jest to, że PIPESTATUS znika w całości, jak tylko wykonasz polecenie. Możesz uzyskać pełną tablicę PIPESTATUS w wersji bash 2 lub wyższej w ten sposób:
Następnie dostępu
${status[0]}
,${status[1]}
itpźródło
Główny problem z „tym, czego oczekujesz” polega na tym, że polecenie w cudzysłowach jest wykonywane w podpowłoce;
$PIPESTATUS
istnieje tam, a status zwrócony z m zachowuje te same zasady, jak w przypadku wykonania jednego pliku wykonywalnego (lub skryptu powłoki). Status komendy backquote to status skrajnie prawy (awk
).Aby wdrożyć to, co powiedział @ Daniel Beck , ustaw odpowiednio
pipefail
opcję w podpowłoce:TM_LOCAL=`set -o pipefail; ls -l --time-style=long-iso ~/.vimrc | awk '{ print $6" "$7 }'`
teraz status zapisany$?
później będzie miał statusls
(jeśli niezerowy).Myślę jednak, że wyraźny
if [ -f ~/.vimrc ];
... test byłby bardziej czytelny.Nie można uzyskać danych wyjściowych do zmiennej i
PIPESTATUS
zwracanych bez pliku tymczasowego dla pierwszego, lub łączenia drugiego w ciąg.źródło
Chciałem wysłać e-mail z cron tylko wtedy, gdy status wyjścia nie był równy zero
Sztuczka polega na tym, że aby uzyskać standardowe wejście na koniec potoku, należy umieścić go w podpowłoce - ale wydaje się, że to ukrywa wartość PIPESTATUS ...
test cron wyrzuca część danych wyjściowych i wychodzi z 1 lub 0 ..
AKTUALIZACJA: PIPESTATUS nie jest widoczny, dopóki polecenie potoku nie zostanie przetworzone
źródło
Jedną z opcji jest sprawdzenie istnienia pliku przed uzyskaniem czasu modyfikacji z wywołaniem
stat
. Ponieważstat
zwraca znacznik czasu nieco więcej niż chcesz, możesz go przyciąć za pomocą rozszerzenia parametrów.W GNU
stat
(np. W systemie Linux) możesz uruchomić:W Mac OS X i innych systemach BSD
stat
składnia jest różna i może określać format czasu:źródło
$TM_LOCAL
jest bezpieczna. Jest bezpieczny tylko wtedy, gdy spodziewałeś się, że nie będzie miał wcześniejszej wartości. Powiedzmy, że wartość była wcześniej2020-02-27 17:14
i nie ma~/.vimrc
pliku. Miałbyś wtedy2020-02-27 17
. Dlatego połączę te dwie linie razem z dodatkową&&
lub (najlepiej, ponieważ nie jest to tak czytelne) użyjif
zwrotki.