$ 1 ve $ 2 boş olup olmadığını kontrol etmek nasıl?


40

String argümanını geçen bazı scriptleri çalıştırıyorum ve else ifadesi aşağıdaki gibi gösteriliyorsa yapmak istiyorum:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

ama gösterdi Error too many argument. Neden?


1. betiği çağırdığınız komutu ve 2. tam çıktısını sağlamalısınız.
Lucio

2
Kullanmalısın [[ ]]. Aksi halde değişkenlerinizden alıntı yapmanız gerekir.
Christophe De Troyer,

Eğer 1 $ olmasaydı, 2 $ 1 olur ve bu da 1 $ ve 2 $ 'nın testini geçersiz kılar.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Mutlaka alakasız değil - bazı durumlarda argümanlarda boş veya boş dize yerine bir şey olduğundan emin olmak istersiniz. $1komut dosyası kullanıcısı tarafından ayarlanmamış veya boş dize olarak ayarlanmış olabilir. Bu komut sırasını göz önünde bulundurun: $ set '' barsonra echo "x${1}x";Her iki değişken de ayarlanır, ancak bunlardan biri boş.
Sergiy Kolodyazhnyy

Yanıtlar:


55

-Z testini kullanmayı deneyin:

if [ -z "$1" ] && [ -z "$2" ]

Adamdan bash:

-z string
   True if the length of string is zero.

Bu benim için çalışıyor!
pengisgood

En çok oy alan ve kabul edilen cevabın aslında sorulan soruyu cevaplamaması ilginçtir .
mehmet

Portatif kabuk betikleri yazarken, bu bayrak dikkatli kullanılmalıdır, çünkü bazı ticari Unixlerde bu bayrak hatalıdır. Bağlantılı kaynaklar için cevabımı gör.
Sergiy Kolodyazhnyy


3

Aşağıdaki de çalışır,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi

&&Ve diğer mantıksal komut ayırıcıları klasik izin verilmez test. Bunun yerine diğer test yapılarını kullanmak zorundasınız ( -asanırım)
muru

3

Cevabın eski versiyonu için bu cevabın ikinci kısmına bakınız. Ayrıntıları bilmek istiyorsanız, okumaya devam edin.

Sorunun nedeni

Sorunun kendisinde, OP'nin too many arguments errortest edildiğinde durum bashböyle görünmediğini gördüğü bildirildi :

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

İle /bin/shhangi aslında sembolik olarak bir /bin/dashaşağıdaki gibi Ubuntu, hata bildirdi:

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

Ve bağımsız /bin/testda:

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

Sidenote: Eğer ne olduğunu merak ediyorsanız /usr/bin/testve neden kullanıyorum bashve sho zaman bilmelidir ki, [için diğer adıdır testaynı zamanda bağımsız çalıştırılabilir ya da daha yaygın olarak var komutu - kabuk olarak yerleşik olan her kabuk ilk kullanacak budur . ifİfadelere gelince , komutların çıkış heykelleri üzerinde çalışırlar, bu yüzden neden [ve testöyledirler, her şey o komutlara argüman olarak gelirler - bu komut satırı arglarının yanlış sıralanması hatalara yol açar.

Konuya geri dönelim: OP'nin ilgisiz hatanın nasıl oluştuğu belli değil. Ancak, her 3 durumda da sorun aynıdır - ayarlanamayan değişken boş olarak değerlendirilir, bu nedenle kabuğun bu alıntılanmamış değişkenlerle gördüğü

[ != '' ]

hangi testanlamaları sözdizimini kırar . Hatalı komut satırı argümanları hakkında söylediklerimi hatırlıyor musun? Bu yüzden neden alıntı yapmak önemlidir? Tanısal çıktıyı etkinleştirelim ve hangi kabuğun çalıştığını görelim:

$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ] 
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars

Değişmeyen değişkenleri test etmenin daha iyi yolu

Çevresinde gördüğünüz çok sık bir yaklaşım şudur:

 if [ "x$var1" == "x"  ] && [ "x$var2" == "x"  ];                                                                
 then
     echo "both variables are null"
 fi

Gilles'dan alıntı yapmak için :

["X $ 1" = "x"] 'de, x öneki x "$ 1"' in bir operatör gibi görünmemesini sağlar ve böylece kabuğun bu testi ayrıştırmasının tek yolu = ikili operatör olarak davranmaktır.

Muhtemelen, bunları /bin/shsenaryolarda gördüğümden beri oldukça taşınabilir olmalı . Aynı zamanda olduğu gibi birleştirilebilir

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

Elbette -zbayrak kullanabiliriz , ancak bazı kabukları araştırmaya göre, özellikle ksh88'i ( Stephane Chazelas'a göre ), bu bayrak hatalı.

Ayrıca bakınız


Çok ilginç bir yaklaşım için +1.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Daha da ilginç hale getirmek için düzenlendi :)
Sergiy Kolodyazhnyy

1

Mesajın amacı $ 1 ve $ 2'nin boş olup olmadığını kontrol etmek olduğundan, mesajın başlığının doğru olmadığını düşünüyorum. Verilen örnek, 1 $ ve 2 $ 'lık işe yarayan çift tırnak işareti eksikti. Dizeleri karşılaştırırken değişkenlerin genişletilmesi için iki kez alıntılanması gerekir. Ancak, $ 1 ve $ 2 olup olmadığını kontrol etmek için $ 2 olup olmadığını kontrol etmekle aynıdır, 1 $ yoksa mevcut olamaz. Bu durumda 'if' komutuna da gerek duyulmaz, çünkü 'test' true / false değerini döndürür ve return 0 / true ise '&&' ifadesini 'sonra' olarak kullanır:

[ "$2" != '' ] && commands...

Basit, -n (sıfır olmayan) ile:

[ -n "$2" ] && commands...

"$ 1 ve $ 2'nin boş olup olmadığını kontrol etmek", parametre olup olmadığını kontrol etmekle aynı olacaktır:

[ $# -eq 0 ] && commands...
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.