Chcę napisać funkcję bash, która sprawdza, czy plik ma określone właściwości i zwraca wartość true lub false. Następnie mogę użyć go w moich skryptach w „if”. Ale co mam zwrócić?
function myfun(){ ... return 0; else return 1; fi;}
następnie używam tego w ten sposób:
if myfun filename.txt; then ...
oczywiście to nie działa. Jak można tego dokonać?
function
słowo kluczowe,myfun() {...}
wystarczyif
status zerowego wyjściamyfun
: jeślimyfun
wychodzi z0
,then ...
jest wykonywany; jeśli to cokolwiek innegoelse ...
jest wykonywane.function
słowo kluczowe to bashism i spowoduje błędy składniowe w niektórych innych powłokach. Zasadniczo jest to zbędne lub zabronione, więc po co z niego korzystać? Nie jest nawet przydatny jako cel grep, ponieważ może go nie być (()
zamiast tego grep ).Odpowiedzi:
Użyj 0 dla true i 1 dla false.
Próba:
Edytować
Z komentarza @ amichair są one również możliwe
źródło
[ -d "$1" ]
.Dlaczego powinieneś przejmować się tym, co mówię, pomimo ponad 250 pozytywnych odpowiedzi
To nie tak
0 = true
i1 = false
. Jest to: zero oznacza brak awarii (sukces), a niezerowe oznacza uszkodzenie (typu N) .Podczas gdy wybrana odpowiedź jest technicznie „true” proszę nie umieszczać
return 1
** w kodzie na false . Będzie miał kilka niefortunnych skutków ubocznych.Naucz się bashu
Podręcznik bash mówi (moje podkreślenie)
Dlatego nie musimy NIGDY używać 0 i 1, aby wskazać Prawda i Fałsz. Fakt, że robią to, jest w zasadzie trywialną wiedzą przydatną tylko do debugowania kodu, pytań do wywiadu i zaskakiwania umysłów początkujących.
Podręcznik bash również mówi
Podręcznik bash również mówi
Zaraz, poczekaj. Rurociąg? Jeszcze raz przejdźmy do instrukcji bash .
Tak. Powiedzieli, że 1 polecenie to potok. Dlatego wszystkie 3 cytaty mówią to samo.
$?
mówi ci, co się stało ostatnio.Moja odpowiedź
Tak więc, chociaż @Kambus wykazał, że przy tak prostej funkcji nie
return
jest wcale potrzebny. Myślę, że było nierealistycznie proste w porównaniu z potrzebami większości ludzi, którzy to przeczytają.Dlaczego
return
?Jeśli funkcja zwraca status wyjścia ostatniego polecenia, po
return
co w ogóle używać ? Ponieważ powoduje to, że funkcja przestaje działać.Zatrzymaj wykonywanie w wielu warunkach
Mamy tutaj ...
Wiersz
04
jest jawnym [-ish] zwróconym prawdą, ponieważ RHS&&
jest wykonywany tylko wtedy, gdy LHS był prawdziwyLinia
09
zwraca wartość true lub false pasującą do stanu linii08
Linia
13
zwraca false z powodu linii12
(Tak, można to zagrać w golfa, ale cały przykład jest wymyślony).
Kolejny wspólny wzór
Zwróć uwagę, jak ustawienie
status
zmiennej demistyfikuje znaczenie$?
. (Oczywiście, że wiesz, co to$?
znaczy, ale ktoś mniej znający się na tym od Ciebie będzie musiał go kiedyś Google. O ile twój kod nie zajmuje się handlem wysokimi częstotliwościami, okaż trochę miłości , ustaw zmienną.) Ale prawdziwą rzeczą na wynos jest „jeśli status „nie istnieje” lub odwrotnie „jeśli status wyjścia” można odczytać na głos i wyjaśnić ich znaczenie. Jednak ten ostatni może być nieco zbyt ambitny, ponieważ zobaczenie tego słowaexit
może sprawić, że pomyślisz, że wychodzi on ze skryptu, podczas gdy w rzeczywistości wychodzi z$(...)
podpowłoki.** Jeśli absolutnie nalegasz na użycie
return 1
fałszywego, sugeruję przynajmniej użyćreturn 255
zamiast tego. Spowoduje to, że twoje przyszłe ja lub inny programista, który będzie musiał utrzymywać Twój kod, będzie pytał „dlaczego to jest 255?” Wtedy będą przynajmniej uważać i będą mieli większą szansę na uniknięcie błędu.źródło
if
sukces zrób to,else
zrób to”. Sukces w czym? Może sprawdzać wartość true / false, może sprawdzać ciąg, liczbę całkowitą, plik, katalog, uprawnienia do zapisu, glob, regex, grep lub dowolne inne polecenie podlegające awariom .true
ifalse
poleceń. Oznacza to, że słowo kluczowetrue
dosłownie zwraca kod stanu 0. Ponadto instrukcje typu „jeśli-to” z natury działają na boolach, a nie na kodach sukcesu. Jeśli błąd wystąpi podczas operacji logicznej, nie powinien zwracać wartości true lub false, ale po prostu przerywać wykonywanie. W przeciwnym razie otrzymujesz fałszywe alarmy (pun).return 1
należy unikać używania . Zakładając, że mamvalidate
funkcję, uważam za uzasadnione,return 1
jeśli sprawdzanie poprawności się nie powiedzie. W końcu jest to powód, aby zatrzymać wykonywanie skryptu, jeśli nie jest on odpowiednio obsługiwany (np. Podczas używaniaset -e
).return 1
jest ważna. Moje obawy dotyczą wszystkich komentarzy tutaj: „0 = prawda 1 = fałsz to [wstaw słowo wykluczające]”. Ci ludzie prawdopodobnie kiedyś przeczytają Twój kod. Dlatego dla nich widzeniereturn 255
(lub 42, a nawet 2) powinno pomóc im w większym zastanowieniu się i nie pomylić tego z „prawdą”.set -e
nadal go złapię.źródło
Zachowaj ostrożność, sprawdzając katalog tylko z opcją -d!
jeśli zmienna $ 1 jest pusta, sprawdzanie nadal się powiedzie. Dla pewności sprawdź także, czy zmienna nie jest pusta.
źródło
$1
("$1"
), nie musisz sprawdzać pustej zmiennej. Nie[[ -d "$1" ]]
powiedzie się, ponieważ""
nie jest to katalog.Natknąłem się na jakiś punkt (jeszcze nie wymieniony?), Nad którym się potknąłem. Oznacza to, że nie jak zwrócić wartość logiczną, ale jak poprawnie ją ocenić!
Próbowałem powiedzieć
if [ myfunc ]; then ...
, ale to po prostu źle. Nie wolno używać nawiasów!if myfunc; then ...
jest na to sposób.Podobnie jak w @Bruno i innych powtórzonych,
true
ifalse
są to polecenia , a nie wartości! To bardzo ważne, aby zrozumieć booleany w skryptach powłoki.W tym poście wyjaśniłem i pokazałem przy użyciu zmiennych boolowskich : https://stackoverflow.com/a/55174008/3220983 . Zdecydowanie sugeruję sprawdzenie tego, ponieważ jest tak ściśle powiązane.
Tutaj podam kilka przykładów zwracania i oceny wartości logicznych z funkcji:
To:
Nie generuje echa. (tzn.
false
zwraca false)Produkuje:
(tzn.
true
zwraca true)I
Produkuje:
Ponieważ 0 (tj. Prawda) zostało zwrócone niejawnie .
Teraz to mnie spieprzyło ...
Produkuje:
I
TAKŻE produkuje:
Użycie nawiasów tutaj wytworzyło fałszywy wynik pozytywny ! (Wnioskuję, że wynikiem polecenia „zewnętrznego” jest 0.)
Najważniejsze odejście od mojego postu: nie używaj nawiasów, aby ocenić funkcję boolowską (lub zmienną), tak jak w przypadku typowej kontroli równości, np.
if [ x -eq 1 ]; then...
!źródło
Użyj poleceń
true
lubfalse
bezpośrednio przed swoimreturn
, a następniereturn
bez parametrów.return
Automatycznie użyje wartości ostatniego polecenia.Podanie argumentów
return
jest niespójne, specyficzne dla typu i podatne na błędy, jeśli nie używasz 1 lub 0. I jak stwierdzono w poprzednich komentarzach, użycie 1 lub 0 tutaj nie jest właściwym sposobem podejścia do tej funkcji.Wynik:
źródło
Może to działać, jeśli przepiszesz to
function myfun(){ ... return 0; else return 1; fi;}
w ten sposóbfunction myfun(){ ... return; else false; fi;}
. To znaczy, jeślifalse
jest ostatnią instrukcją w funkcji, otrzymujesz fałszywy wynik dla całej funkcji, ale i takreturn
przerywa działanie z prawdziwym wynikiem. Uważam, że tak jest przynajmniej w przypadku mojego tłumacza bash.źródło
Znalazłem najkrótszą formę, aby przetestować wynik funkcji jest po prostu
źródło
Uważam, że ze względu na czytelność zwracanie wartości true / false powinno:
return
a następnie inne słowo kluczowe (true
lubfalse
)Moje rozwiązanie jest
return $(true)
lubreturn $(false)
jak pokazano na rysunku:źródło
Kontynuując @Bruno Bronosky i @mrteatime, proponuję, abyś po prostu napisał zwrot boolowski „wstecz”. To jest to co mam na mysli:
Eliminuje to brzydkie wymagania dwóch wierszy dla każdej instrukcji return.
źródło