Jawaban:
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" ]
dan case $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]
tanpa if
atau yang serupa tidak ada artinya, meskipun secara sintaksis ok.
Ini dimaksudkan untuk mengevaluasi ke true jika x$1
diperluas ke x
, dan salah sebaliknya, tetapi karena tidak dikutip, jika $1
(misalnya) "hey x", shell akan melihat x = 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:
if [ "$1" = "" ]; then
Operator uji Bash -z
dan -n
juga dapat digunakan, tetapi mereka kurang portabel untuk jenis shell lainnya. 1
Alasan untuk kutipan, atau x$1
, adalah agar sisi kiri tidak berkembang menjadi apa-apa, yang akan menjadi kesalahan sintaksis:
if [ = x ] # No good!
if [ "" = "" ] # Okay.
if [ x = x ] # Also okay.
1. Sebenarnya, test
bisa menjadi utilitas mandiri tetapi sebagian besar shell mengimplementasikannya sebagai built-in; periksa perbedaan antara which test
dan type test
. Pada GNU / Linux man 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
.
[ x$1 = x ]
juga akan mengevaluasi true jika $1
misalnya " -o x"
. Coba sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
salah dan tidak masuk akal.
if
menggunakan test
, Anda dapat menggunakannya sebelum &&
, ||
atau setelah while
atau memeriksa hasilnya menggunakan$?
[ x$1 = x ]
Masuk akal zsh
. Itu membandingkan gabungan darix
dengan argumen pertama dari skrip x
. Jadi [
perintah mengembalikan true jika $1
kosong atau tidak disediakan.
[ $1 = "" ]
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 rangkaian x
dan argumen pertama dari skrip yang berharap bahwa hasilnya dan =
dan x
, 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 membandingkan x
dengan x
dan x
dengan x
dan kembali benar.
Jika $1
ada "* *"
, maka shell akan meneruskan ke [
perintah daftar file di direktori saat ini yang namanya dimulai denganx
(perluasan segumpal x*
), 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:
[ "x$1" = x ]
Itu digunakan untuk menguji apakah $1
kosong atau tidak disetel.
Cara normal untuk menguji variabel kosong atau tidak disetel adalah:
[ -z "$1" ]
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 lama dash
(hingga 0,5,4) atau sh
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:
[ "x$1" = x ]
selalu merupakan tes yang valid terlepas dari nilai $1
, demikian juga:
[ "" = "$1" ]
dan:
[ -z "${1:+x}" ]
dan
case $1 in "") ...; esac
Tentu saja, jika Anda ingin memeriksa bahwa tidak ada argumen yang diberikan, Anda akan melakukannya:
[ "$#" -eq 0 ]
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 (dan bash
's [
adalah dan telah selama beberapa dekade). Jadi, Anda harus dapat mengandalkannya dalam POSIX sh atau bash
skrip.
x$1
adalah gabungan dua string x
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 sh
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"
[ x$1 = x ]
juga benar jika $1
misalnya " -o x"
. Coba sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'
. [ x$1 = x ]
salah dan tidak masuk akal.