Saya membaca skrip bash, saya tidak mengerti apa yang sedang terjadi di sana.
#!/bin/sh
[ x$1 = x ]
Apa yang terjadi pada baris kedua dan apa [ x$1 = x ]
artinya?
Itu memeriksa yang $1
kosong, meskipun harus dikutip (identik dengan [ -z "$1" ]
). Beberapa cangkang yang sangat tua tidak menangani string kosong dengan benar, sehingga penulis skrip portabel mengadopsi gaya pemeriksaan ini. Itu tidak perlu selama beberapa dekade, tetapi orang masih melakukannya dengan cara itu karena orang masih melakukannya dengan cara itu.
[ x$1 = x ]
masih salah, tapi[ "x$1" = x ]
akan kerang yang memiliki masalah di mana$1
adalah!
atau(
atau-n
....[ "" = "$1" ]
dancase $1 in "")
juga akan OK sekalipun.[ -z "$1" ]
dan[ "$1" = "" ]
masih tidak berfungsi dengan / bin / sh dari Solaris 10, yang pertama dengan dash-0.5.4.[ "$1" = "" ]
masih tidak berfungsi dengan itu/bin/sh
(meskipun Anda ingin menggunakannya di/usr/xpg4/bin/sh
sana, tidak/bin/sh
). dasbor diperbaiki dalam hal itu pada Januari 2009.Kurung kotak menunjukkan tes , jadi
[ x$1 = x]
tanpaif
atau yang serupa tidak ada artinya, meskipun secara sintaksis ok.Ini dimaksudkan untuk mengevaluasi ke true jika
x$1
diperluas kex
, dan salah sebaliknya, tetapi karena tidak dikutip, jika$1
(misalnya) "hey x", shell akan melihatx = x
, jadi konstruksi ini masih tidak aman.Tujuan
x = x
pemeriksaan adalah untuk menentukan apakah suatu variabel kosong. Cara yang lebih umum untuk melakukan ini adalah dengan hanya menggunakan tanda kutip:Operator uji Bash
-z
dan-n
juga dapat digunakan, tetapi mereka kurang portabel untuk jenis shell lainnya. 1Alasan untuk kutipan, atau
x$1
, adalah agar sisi kiri tidak berkembang menjadi apa-apa, yang akan menjadi kesalahan sintaksis:1. Sebenarnya,
test
bisa menjadi utilitas mandiri tetapi sebagian besar shell mengimplementasikannya sebagai built-in; periksa perbedaan antarawhich test
dantype test
. Pada GNU / Linuxman test
klaim untuk merujuk pada built-in, tetapi jika Anda menelepon (misalnya)/usr/bin/test
, utilitas itu tampaknya mengimplementasikan fitur-fitur yang didokumentasikan dalam halaman manual, termasuk-z
dan-n
.sumber
[ x$1 = x ]
juga akan mengevaluasi true jika$1
misalnya" -o x"
. Cobash -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
salah dan tidak masuk akal.if
menggunakantest
, Anda dapat menggunakannya sebelum&&
,||
atau setelahwhile
atau memeriksa hasilnya menggunakan$?
Masuk akal
zsh
. Itu membandingkan gabungan darix
dengan argumen pertama dari skripx
. Jadi[
perintah mengembalikan true jika$1
kosong atau tidak disediakan.Tidak akan bekerja karena,
zsh
ketika sebuah variabel kosong tidak dikutip dalam konteks daftar, ia tidak memperluas argumen sama sekali alih-alih argumen kosong, jadi jika$1
tidak disetel atau kosong,[
perintah hanya akan menerima sebagai argumen[
,=
string kosong dan]
itu tidak masuk akal.[ -z "$1" ]
atau[ "$1" = "" ]
akan baik-baik saja seperti di shell POSIX.Dalam cangkang Bourne-like / POSIX,
[ x$1 = x ]
tidak masuk akal. Itulah operator split + glob yang entah bagaimana diterapkan pada rangkaianx
dan argumen pertama dari skrip yang berharap bahwa hasilnya dan=
danx
, dan]
membuat ekspresi pengujian yang valid untuk[
perintah tersebut.Misalnya, jika skrip disahkan satu
" = x -o x ="
argumen,[
akan menerima argumen mereka:[
,x
,=
,x
,-o
,x
,=
,x
,]
, yang[
akan mengerti sebagai membandingkanx
denganx
danx
denganx
dan kembali benar.Jika
$1
ada"* *"
, maka shell akan meneruskan ke[
perintah daftar file di direktori saat ini yang namanya dimulai denganx
(perluasan segumpalx*
), maka daftar file non-tersembunyi (ekspansi*
) ... yang[
tidak mungkin untuk dapat masuk akal dari. Satu-satunya kasus di mana itu akan melakukan sesuatu yang masuk akal adalah jika$1
tidak mengandung karakter pengganti atau karakter kosong.Sekarang, apa yang kadang Anda temukan adalah kode seperti:
Itu digunakan untuk menguji apakah
$1
kosong atau tidak disetel.Cara normal untuk menguji variabel kosong atau tidak disetel adalah:
Tapi itu gagal untuk beberapa nilai
$1
seperti=
di beberapa (non-POSIX)[
implementasi seperti yang dibangun di shell Bourne seperti yang ditemukan/bin/sh
pada Solaris 10 dan sebelum atau beberapa versi lamadash
(hingga 0,5,4) ataush
beberapa BSD.Itu karena
[
melihat[
,-z
,=
,]
dan mengeluh tentang hilang argumen ke=
operator biner bukan pemahaman itu sebagai-z
unary operator diterapkan pada=
tali.Demikian pula,
[ "$1" = "" ]
gagal karena beberapa implementasi dari[
jika$1
ini!
atau(
.Dalam shell /
[
implementasi tersebut:selalu merupakan tes yang valid terlepas dari nilai
$1
, demikian juga:dan:
dan
Tentu saja, jika Anda ingin memeriksa bahwa tidak ada argumen yang diberikan, Anda akan melakukannya:
Artinya, Anda memeriksa jumlah argumen yang diteruskan ke skrip.
Perhatikan bahwa saat ini,
[ -z "$var" ]
jelas ditentukan oleh POSIX dan tidak bisa gagal dalam conformant[
implementasi (danbash
's[
adalah dan telah selama beberapa dekade). Jadi, Anda harus dapat mengandalkannya dalam POSIX sh ataubash
skrip.sumber
x$1
adalah gabungan dua stringx
dan$1
dan jika $ 1 kosong, x $ 1 sama dengan x, dan [x $ 1 = x] akan menjadi benar sebagai hasilnya.x = y
digunakan untuk membandingkan string dalam shsumber
x$1
tidak dikutip, jadi pemecahan dan penggumpalan dilakukan pada mereka.[ x$1 = x ]
benar jika$1
tidak disetel / null / kosong atau tidak.Coba sendiri dengan:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
dan
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"
sumber
[ x$1 = x ]
juga benar jika$1
misalnya" -o x"
. Cobash -xc '[ x$1 = x ] && echo yes' sh ' -o x'
.[ x$1 = x ]
salah dan tidak masuk akal.