bash betiği [x $ 1 = x]


21

Bash betiği okuyorum orada ne olduğunu anlamıyorum.

#!/bin/sh
[ x$1 = x ] 

İkinci satırda neler oluyor ve ne [ x$1 = x ] anlama geliyor?

Yanıtlar:


27

Bu $1alıntılar boş olsa da, alıntı yapılmalı (özdeş [ -z "$1" ]). Çok eski bazı kabukları, boş dizeleri düzgün bir şekilde idare edemedi, bu yüzden taşınabilir senaryo yazarları bu kontrol tarzını benimsediler. Onlarca yıldır gerekmemişti, ancak insanlar hala bu şekilde yapıyor çünkü insanlar hala bu şekilde yapıyor.


Evet, artık böyle yapmamalı ve daha modern bir tarz benimsemelisin. Bir PDP11 üzerinde çalışmıyorsanız.
MacLemon

4
Boş dizelerle ilgili değil. [ x$1 = x ]hâlâ yanlışsa, fakat [ "x$1" = x ]bir sorun var kabukları olurdu $1olduğu !veya (ya -n.... [ "" = "$1" ]ve case $1 in "")ayrıca Tamam olsa olurdu.
Stéphane Chazelas,

2
@ MacLemon, o kadar geriye gitmenize gerek yok. [ -z "$1" ]ve [ "$1" = "" ]hala Solaris 10 / bin / sh ile çalışmıyor, eski tire-0.5.4.
Stéphane Chazelas 16:14

1
son cümle için ilave +1!
glenn jackman

1
@glennjackman, bu son cümle yanlıştır. Solaris 10 hala Solaris'in en yaygın kullanılan sürümüdür ve [ "$1" = "" ]hala onunla çalışmaz /bin/sh(orada kullanmak istemesen /usr/xpg4/bin/shde /bin/sh). çizgi bu konuda Ocak 2009'da düzeltildi.
Stéphane Chazelas

8

Köşeli parantezler bir testi gösterir , bu yüzden sözdizimsel olarak tamam olsa da , [ x$1 = x]onsuz ifveya benzer bir şey anlamsızdır.

x$1Genişlerse xve yanlışsa, doğru olup olmadığını değerlendirmek istenmiştir , ancak alıntı $1yapılmayacağından (örneğin) "hey x" ise kabuk görecektir x = x, bu yüzden bu yapı hala güvenli değildir.

x = xKontrolün amacı bir değişkenin boş olup olmadığını belirlemektir. Bunu yapmanın daha yaygın bir yolu sadece tırnak kullanmak olacaktır:

if [ "$1" = "" ]; then

Bash test operatörleri -zve -nayrıca kullanılabilir, ancak bunlar diğer kabuk tiplerine daha az taşınabilir. 1

Alıntıların ya da x$1, bunun nedeni, sol tarafın hiçbir şeye genişlememesidir, ki bu sözdizimsel bir hata olacaktır:

if [  = x ]  # No good!
if [ "" =  "" ] # Okay.
if [ x = x ] # Also okay.

1. Aslında, testbağımsız bir yardımcı program olabilir , ancak çoğu kabuk onu yerleşik olarak uygular; which testve arasındaki farkı kontrol edin type test. GNU / Linux üzerinde man testiddialar başvurmak için dahili, ancak ararsanız (örneğin) /usr/bin/test, o yarar dahil sayfasında açıklandığı özellikleri uygulamak gibi görünüyor -zve -n.


1
[ x$1 = x ]$1Örneğin, true olup olmadığını da değerlendirecektir " -o x". Dene sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'. [ x$1 = x ]yanlış ve mantıklı değil.
Stéphane Chazelas

@ StéphaneChazelas Teşekkürler SC - düzenlendi (2. para).
goldilocks

ifkullanmana gerek yok test, daha önce kullanabilirsin &&, ||ya whileda sonucunu kullanabilirsin ya da kullanarak sonucu inceleyebilirsin$?
Jasen

8
[ x$1 = x ]

Sadece mantıklı geliyor zsh. Bu xbetiğin ilk argümanı ile birleştirme ile karşılaştırır x. Bu nedenle, [komut $1boş veya sağlanmamışsa true olarak döner .

[ $1 = "" ]

İşe yaramaz, çünkü zshboş bir değişken liste bağlamlarında belirtilmediğinde, boş bir argüman yerine hiçbir argümana genişlemez, bu nedenle $1ayarlanmamış veya boş [olsaydı , komut yalnızca argümanlar olarak alır [, =boş dize ve ]bunun mantıklı olamadığı. [ -z "$1" ]veya [ "$1" = "" ]POSIX kabukları gibi olsa tamam olurdu.

Bourne benzeri / POSIX mermilerinde, bir [ x$1 = x ]anlam ifade etmiyor. Split + glob operatörü bir şekilde xsonucun ve =ve x, ve komut ]için geçerli bir test ifadesi oluşturduğunu ümit ederek komut dosyasının ilk argümanına ve ilk argümanına uygulanır [.

Senaryo biri geçti Örneğin, eğer " = x -o x ="argüman, [bu argümanları alacağı: [, x, =, x, -o, x, =, x, ], hangi [karşılaştırma olarak anlayacak xile xve xile xve gerçek dönün.

Eğer $1vardı "* *", sonra kabuk için geçerdi [Adını başlar ile geçerli dizinde komuta dosyaların listesini x(bir glob genişlemesi x*) olmayan gizli dosyaları (genişleme birleştirdikten sonra liste *) ... [edebilmek pek mümkün değildir mantıklı olmak için. Mantıklı bir şey yapabileceği tek durum $1, joker veya boş karakterler içermemesidir.

Şimdi, bazen bulduğunuz şey şuna benzer:

[ "x$1" = x ]

$1Boş olup olmadığını test etmek için kullanılır .

Boş veya ayarlanmamış bir değişkeni test etmenin normal yolu şudur:

[ -z "$1" ]

Ancak bu, bazı değerler için başarısız $1gibi =bazı (POSIX olmayan) 'de [bulunmuştur Bourne kabukta yerleşik gibi uygulamalarda /bin/shSolaris 10 önce ya da bazı eski sürüm dash(0.5.4 kadar) ya da shbir BSD türevi.

Bunun nedeni olduğunu [görür [, -z, =, ]ve argümanlar eksik şikâyet =ikili operatör yerine olarak anlaşılması -ztekli operatör uygulanan =dize.

Benzer şekilde, [ "$1" = "" ]bazı uygulamalar için başarısız [olursa $1bir !ya da (.

Bu kabukta / [uygulamalarda:

[ "x$1" = x ]

değeri ne olursa olsun, her zaman geçerli bir testtir $1;

[ "" = "$1" ]

ve:

[ -z "${1:+x}" ]

ve

case $1 in "") ...; esac

Tabii ki, hiçbir argüman sağlanmadığını kontrol etmek istiyorsanız, şunları yapmalısınız:

[ "$#" -eq 0 ]

Diğer bir deyişle, komut dosyasına iletilen bağımsız değişkenlerin sayısını kontrol edersiniz.

Günümüzde, Not [ -z "$var" ]açıkça POSIX tarafından belirlenir ve uygun olan başarısız olamaz [uygulamaları (ve bash'ın [ve yıllardır olmuştur). Bu yüzden POSIX sh veya bashscriptlerinde buna güvenebilmelisiniz .


0

x$1İki dizesinin edilir xve $1$ ve 1 boşsa, $ 1 x x eşittir ve [x $ 1 = x] sonuç olarak geçerli olacak. x = ydize sh karşılaştırmak için kullanılır


2
Hayır x$1, alıntı yapılmaz, bu yüzden ayrılma ve toplanma bunlara uygulanır.
Stéphane Chazelas

0

[ x$1 = x ]$1unset / null / empty veya değil ise doğrudur .
Kendinizi deneyin:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
ve
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"


1
[ x$1 = x ]$1Mesela mümkünse de geçerlidir " -o x". Dene sh -xc '[ x$1 = x ] && echo yes' sh ' -o x'. [ x$1 = x ]yanlış ve mantıklı değil.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.