Czytam skrypt bash Nie rozumiem, co się tam dzieje.
#!/bin/sh
[ x$1 = x ]
Co dzieje się na drugiej linii i co to [ x$1 = x ]
znaczy?
To sprawdza, które $1
są puste, choć powinny być cytowane (identycznie jak [ -z "$1" ]
). Niektóre bardzo stare powłoki nie obsługiwały poprawnie pustych łańcuchów, więc autorzy skryptów przenośnych przyjęli ten styl sprawdzania. Nie było to konieczne od dziesięcioleci, ale ludzie nadal robią to w ten sposób, ponieważ ludzie nadal tak robią.
[ x$1 = x ]
jest nadal niepoprawny, ale[ "x$1" = x ]
dotyczyłby powłok, które mają problem z gdzie$1
jest!
lub(
lub-n
....[ "" = "$1" ]
icase $1 in "")
również byłyby OK.[ -z "$1" ]
i[ "$1" = "" ]
nadal nie działa z / bin / sh Solaris 10, poprzedni z dash-0.5.4.[ "$1" = "" ]
nadal nie działa z jego/bin/sh
(choć tylko chcesz używać/usr/xpg4/bin/sh
tam, nie/bin/sh
). kres został naprawiony w tym względzie w styczniu 2009 r.Nawiasy kwadratowe wskazują na test , więc
[ x$1 = x]
bezif
lub coś podobnego jest bez znaczenia, chociaż składniowo ok.Ma on oceniać jako prawda, jeśli
x$1
rozwija sięx
, a w przeciwnym razie fałsz, ale ponieważ nie jest cytowany, jeśli$1
jest (np.) „Hej x”, powłoka zobaczyx = x
, więc ta konstrukcja nadal nie jest bezpieczna.Celem tego
x = x
sprawdzenia jest ustalenie, czy zmienna jest pusta. Częstszym sposobem na to byłoby po prostu użycie cudzysłowów:Operatorzy testowe bash
-z
i-n
może być również używany, ale są one mniej przenośne do innych rodzajów muszli. 1Powodem cytowania lub tego
x$1
jest to, że lewa strona nie rozwija się do zera, co byłoby błędem składniowym:1. W rzeczywistości
test
może być samodzielnym narzędziem, ale większość powłok implementuje je jako wbudowane; sprawdź różnicę międzywhich test
itype test
. W GNU / Linuxman test
twierdzi, że odnosi się do wbudowanego, ale jeśli wywołasz (np.)/usr/bin/test
, To narzędzie wydaje się implementować funkcje udokumentowane na stronie podręcznika, w tym-z
i-n
.źródło
[ x$1 = x ]
oceni również prawdę, jeśli tak$1
jest na przykład" -o x"
. Spróbowaćsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
jest zły i nie ma sensu.if
go używaćtest
, możesz go użyć przed&&
,||
powhile
lub sprawdzić wynik za pomocą$?
Ma to sens tylko w
zsh
. To porównuje konkatenacjęx
z pierwszym argumentem skryptu dox
. Tak więc[
polecenie zwraca true, jeśli$1
jest puste lub nie zostało podane.Nie działałoby, ponieważ
zsh
gdy pusta zmienna nie jest cytowana w kontekstach list, nie rozwija się w ogóle do żadnego argumentu zamiast pustego argumentu, więc gdyby$1
były nieustawione lub puste,[
polecenie otrzymywałoby tylko jako argumenty[
,=
pusty ciąg i z]
czego to nie miało sensu.[ -z "$1" ]
lub[ "$1" = "" ]
byłoby OK, chociaż jak w powłokach POSIX.W powłokach typu Bourne'a / POSIX
[ x$1 = x ]
nie ma sensu. To jest operator split + glob w jakiś sposób zastosowany do konkatenacjix
i pierwszy argument skryptu, mając nadzieję, że wynik i,=
ix
, i]
tworzą prawidłowe wyrażenie testowe dla[
polecenia.Na przykład, jeśli skrypt został przekazany jednego
" = x -o x ="
argumentu,[
by otrzymać te argumenty:[
,x
,=
,x
,-o
,x
,=
,x
,]
, który[
zrozumie porównaćx
zx
ix
zx
a return true.Gdyby tak
$1
było"* *"
, to powłoka przekazałaby do[
polecenia listę plików w bieżącym katalogu, których nazwa zaczyna się odx
(globalne rozszerzeniex*
), a następnie listę plików nie ukrytych (rozszerzenie*
) ... co[
jest mało prawdopodobne z jakiegokolwiek sensu. Jedynymi przypadkami, w których byłoby to sensowne, jest to,$1
że nie zawiera symboli wieloznacznych ani pustych znaków.Teraz czasem znajduje się kod:
Służy do sprawdzania, czy
$1
jest pusty lub rozbrojony.Normalny sposób testowania pustej lub nieuzbrojonej zmiennej to:
Ale to nie udaje się w przypadku niektórych wartości
$1
podobnych=
w niektórych[
implementacjach (nie POSIX), takich jak wbudowana w powłoce Bourne'a, jak znaleziono/bin/sh
w Solarisie 10 i wcześniejszych wersjach lub niektórych starych wersjachdash
(do 0.5.4) lubsh
niektórych BSD.To dlatego, że
[
widzi[
,-z
,=
,]
i narzeka na brak argumentów do=
operatora binarnego zamiast zrozumienia go jako-z
operator jednoargumentowy stosowane do=
łańcucha.Podobnie
[ "$1" = "" ]
nie udaje się w przypadku niektórych implementacji[
if$1
is!
lub(
.W tych powłokach /
[
implementacjach:jest zawsze ważnym testem niezależnie od wartości
$1
, więc są:i:
i
Oczywiście, jeśli chcesz sprawdzić, czy nie podano argumentu, wykonaj następujące czynności:
Oznacza to, że sprawdzasz liczbę argumentów przekazanych do skryptu.
Należy zauważyć, że w dzisiejszych czasach,
[ -z "$var" ]
jest jasno określony przez POSIX i nie może zabraknąć w zgodnymi[
wdrożeń (abash
„s[
jest i był przez dziesięciolecia). Powinieneś więc móc polegać na nim w POSIX sh lubbash
skryptach.źródło
x$1
jest łączeniem dwóch łańcuchów,x
a$1
jeśli $ 1 jest pusty, x $ 1 równa się x, a [x $ 1 = x] będzie w rezultacie prawdziwe.x = y
służy do porównywania napisów w shźródło
x$1
nie jest cytowany, więc dzielenie i globowanie jest wykonywane na nich.[ x$1 = x ]
ma wartość true, jeśli$1
jest nieustawione / zerowe / puste lub nie.Wypróbuj się z:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
i
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
źródło
[ x$1 = x ]
jest również prawdą, jeśli tak$1
jest na przykład" -o x"
. Spróbowaćsh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
jest zły i nie ma sensu.