Wydaje się, że istnieje tu pewne nieporozumienie dotyczące wbudowanego Basha true
, a dokładniej tego, w jaki sposób Bash rozwija i interpretuje wyrażenia w nawiasach.
Kod w odpowiedzi Miku ma absolutnie nic wspólnego z wbudowanego polecenia bash true
, ani /bin/true
, ani żaden inny smak true
polecenia. W tym przypadku true
jest to zwykły ciąg znaków i nigdy nie jest wywoływane true
polecenie / polecenie wbudowane, ani przez przypisanie zmiennej, ani przez ocenę wyrażenia warunkowego.
Poniższy kod jest funkcjonalnie identyczny z kodem w odpowiedzi miku:
the_world_is_flat=yeah
if [ "$the_world_is_flat" = yeah ]; then
echo 'Be careful not to fall off!'
fi
Tylko różnicą jest to, że cztery znaki są porównywane są „Tak”, „e”, „a” i „H”, a nie „t”, „R”, „u” i „E”. Otóż to. Nie próbuje się wywoływać komendy ani wbudowanego programu o nazwie yeah
, ani też (w przykładzie miku) nie ma żadnej specjalnej obsługi, gdy Bash analizuje token true
. To tylko struna i całkowicie dowolna.
Aktualizacja (2014-02-19): Po podążeniu za linkiem w odpowiedzi miku, teraz widzę, skąd bierze się zamieszanie. Odpowiedź Miku używa pojedynczych nawiasów, ale fragment kodu, do którego prowadzi łącze, nie używa nawiasów. To poprostu:
the_world_is_flat=true
if $the_world_is_flat; then
echo 'Be careful not to fall off!'
fi
Oba fragmenty kodu będą zachowywać się w ten sam sposób, ale nawiasy całkowicie zmieniają to, co dzieje się pod maską.
Oto, co robi Bash w każdym przypadku:
Bez nawiasów:
- Rozwiń zmienną
$the_world_is_flat
do ciągu "true"
.
- Próba przetworzenia ciągu
"true"
jako polecenia.
- Znajdź i uruchom
true
polecenie (wbudowane lub /bin/true
, w zależności od wersji Bash).
- Porównaj kod wyjścia
true
polecenia (który zawsze wynosi 0) z 0. Przypomnij sobie, że w większości powłok kod wyjścia 0 oznacza sukces, a cokolwiek innego wskazuje na niepowodzenie.
- Ponieważ kodem wyjścia było 0 (sukces), należy wykonać klauzulę
if
instrukcjithen
Wsporniki:
- Rozwiń zmienną
$the_world_is_flat
do ciągu "true"
.
- Analizuj teraz w pełni rozwinięte wyrażenie warunkowe, które ma formę
string1 = string2
. =
Operator bash męska porównanie ciąg operator. Więc...
- Wykonaj porównanie ciągów na
"true"
i "true"
.
- Tak, dwa ciągi były takie same, więc wartość warunku jest prawdziwa.
- Wykonaj klauzulę
if
instrukcji then
.
Kod bez nawiasów działa, ponieważ true
polecenie zwraca kod wyjścia 0, co oznacza sukces. Kod w nawiasach działa, ponieważ wartość $the_world_is_flat
jest identyczna z literałem łańcucha true
po prawej stronie =
.
Aby doprowadzić punkt do domu, rozważ następujące dwa fragmenty kodu:
Ten kod (jeśli jest uruchamiany z uprawnieniami administratora) uruchomi ponownie komputer:
var=reboot
if $var; then
echo 'Muahahaha! You are going down!'
fi
Ten kod po prostu wypisuje „Niezła próba”. Polecenie ponownego uruchomienia nie jest wywoływane.
var=reboot
if [ $var ]; then
echo 'Nice try.'
fi
Aktualizacja (2014-04-14) Aby odpowiedzieć na pytanie w komentarzach dotyczące różnicy między =
i ==
: AFAIK, nie ma różnicy. ==
Operator jest synonimem atakujących specyficzne dla =
, io ile widziałem, one działają dokładnie tak samo we wszystkich kontekstach.
Należy jednak pamiętać, że jestem specjalnie mówić o =
i ==
operatorów porównania ciąg używany zarówno w [ ]
lub [[ ]]
testów. Nie sugeruję tego =
i ==
są one wymienne wszędzie w bash.
Na przykład, oczywiście nie możesz wykonać przypisania zmiennej ==
, na przykład var=="foo"
(cóż, technicznie możesz to zrobić, ale wartość var
będzie "=foo"
, ponieważ Bash nie widzi ==
tutaj operatora, widzi =
operatora (przypisanie), po którym następuje dosłowna wartość ="foo"
, która właśnie się staje "=foo"
).
Ponadto, chociaż =
i ==
są wymienne, należy pamiętać, że jak te testy praca nie zależy od tego, czy używasz go wewnątrz [ ]
lub [[ ]]
, a także od tego, czy argumenty są notowane. Możesz przeczytać więcej na ten temat w Advanced Bash Scripting Guide: 7.3 Inne operatory porównania (przewiń w dół do dyskusji na temat =
i ==
).
true
orazfalse
w kontekście większości fragmentów poniżej są po prostu ciągi, a nie tobash built-ins
!!! Przeczytaj odpowiedź Mike'a Holta poniżej. (Jest to jeden z przykładów, w których wysoko głosowana i zaakceptowana odpowiedź jest myląca i