2013-10-30 46 views
6

Geliştirme iş akışımı kolaylaştırmak için bir kabuk komut dosyası yazıyorum.Neden "tek operatörün beklenen" hatası alıyorum?

Bu dizinde hangi tema klasöründe çalışacağım ve grunt watch'u başlattığım bir argüman alır.

Komut dosyasını gerekli argüman olmadan çağırırsam, şu anda bir temanın komut satırı argümanı olarak belirtilmesi gerektiğine dair bir uyarı yazdırıyorum.

Kullanılabilir seçeneklerin bir listesini yazdırmak istiyorum, ör. Öyle

THEME=$1 

if [ $THEME == '' ] 
then 
    echo 'Need to specify theme from the following' 
    ls workspace/aws/ghost 
else 
    cd 'workspace/aws/ghost/'$THEME'/' 
    grunt watch 
fi 
gibi temalar ana dizinin bir ls ile echo hattının çıkışını değiştirmek istiyorum

İdeal
THEME=$1 

if [ $THEME == '' ] 
then 
    echo 'Need to specify theme' 
else 
    cd 'workspace/aws/ghost/'$THEME'/' 
    grunt watch 
fi 

tema dizinleri

Bu defa ne var ...

Ancak, bu bana aşağıdaki hatayı verir

+1

Boş bir değişkeni kontrol etmek için '-z' kullanmalısınız: eğer [-z" $ THEME "]'. – Kevin

+0

başlığını düzenledim, eğer [[-z "$ THEME"]] '' mükemmel çalışıyorsa, '-z' – Luke

+0

' ile deneyeceğim. – Luke

cevap

23

Bir tema belirtmeyen zaman $THEME hiçbir şey genişler, Aksi

if [ $THEME == '' ] 

ve kabuk bu sözdizimi hatası görür: Sen $THEME buralarda tırnak ihtiyaç tırnak ile

if [ == '' ] 

gibi ek böylece:

if [ "$THEME" == '' ] 
boş $THEME genişlemesi yerine bu geçerli bir karşılaştırma verir

:

if [ "" == '' ] 

çalışma zamanı sözdizimi hataları için bu kapasite kimin arka plan daha geleneksel programlama dillerinde olduğu kişilere şaşırtıcı olabilir, ancak komut kabukları (en azından Bourne geleneğinde olanlar) biraz farklı kod ayrıştırmak. Birçok bağlamda, kabuk parametreleri değişkenlerden daha fazla makro gibi davranır; Bu davranış esneklik sağlar, ancak aynı zamanda da istenmeyen için tuzaklar oluşturur. Bu soruyu bash etiketli yana

, bash (ve Ksh/zsh) mevcut "yeni" testi sözdizimi içindeki parametre genişlemesi sonucu üzerinde gerçekleştirilen hiçbir kelime bölme, yani [[ olduğunu belirtmek gerekir. .. ]]. Yani aynı zamanda bunu yapabilirsiniz: Eğer tırnak işaretleri olmadan kurtulabilir

if [[ $THEME == '' ]] 

yerler here listelenmektedir. Ancak, her zaman parametre genişletme işlemlerini açıkça belirtmek dışında, kelime bölme işlemi yapmak istediğinizde (ve daha sonra dizilerin sorununuzu çözüp çözmeyeceğini görmek için) iyi bir alışkanlıktır.

Boş dize ile yerine eşitlik -z testi operatörünü kullanmak daha deyimsel olurdu: Sen teknik olarak bu basit durumda tırnak işareti gerekmez

if [ -z "$THEME" ] 

; [ -z ], doğru olarak değerlendirir. Fakat daha karmaşık bir ifadeniz varsa, çözümleyici kafası karışacaktır, bu yüzden her zaman alıntıları kullanmak daha iyidir.

if [[ -z $THEME ]] 

Ama [[ ... ]] POSIX standardının parçası değildir;: Tabii ki, [[ ... ]] da burada tırnak gerektirmez Bu konuda, ==. Diğer POSIX kabuklarıyla sıkı bir uyumluluğa önem veriyorsanız, teklif çözümüne bağlı kalın ve -z veya tek bir = kullanın.

+0

Tamam, değişken atamasıyla ilgili alıntıları ekledim, [[]] sözdizimini kullandı ve en iyi uygulamalar için "$ THEME" üzerindeki tırnakları ekledi. Bir tedavi! Teşekkürler. – Luke

+3

Ödevler biraz farklı çalışır; RHS'de en az kelime bölünmesi gerçekleşmiyor, bu yüzden bence THEME = "$ 1" ve "THEME = $ 1" aynıdır, ancak unutmak istediğim köşe davası için düzeltilmeyi çok isterim. – chepner

+0

@chepner - haklısınız, bir ödevin sağ tarafında genişletmeler etrafında tekliflere gerek yok. Tabii ki, herhangi bir harfli boşluğu belirtmeniz gerekiyor. –

0

Lütfen çift tırnaklı sözdizimini düzeltin. $THEME aksi tanımlanmamış veya boş bir dize ve doğruysa

if [ "$THEME" == "" ] then 
    echo 'Need to specify theme from the following' 
    ls workspace/aws/ghost 
2

[ "$THEME" ] false olarak değerlendirecektir. Bkz http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html#Bash-Conditional-Expressions. Sen daha basit koşullu bu davranışı yararlanmak için eğer deyimi yeniden düzenlemek ve sahip olabilir:

 
if [ "$THEME" ]; then 
    cd 'workspace/aws/ghost/'$THEME'/' 
    grunt watch 
else 
    echo 'Need to specify theme from the following' 
    ls workspace/aws/ghost 
fi 

"$THEME" ihtiyaçlarını değeri boşluk içeriyor durumda, çift tırnak içinde olmak.

İlgili konular