$ Mı kullanıyorsunuz? if ifadesinde


12
function foo {
   (cd $FOOBAR;
   <some command>
   if [$? -ne 0]
   then
      echo "Nope!"
   else
      echo "OK!"
   fi
   )
}

Yukarıdaki gibi bir işlev yazmak ve benim .bashrc dosyaya yerleştirmek çalışıyorum. Dosyayı çalıştırıp çalıştırdıktan sonra şunu alıyorum:

Toplam süre: 51 saniye-
bas: [1: komut bulunamadı
!

Birisi neyi yanlış yaptığımı anlamama yardımcı olabilir mi?


4
Eğer test $?isimli bir ile 0'a eşit ifaçıklamada, anlamsız ifbir komut bekler ve eğer komut döner dedi 0, bu blok içinde kod çalışır. böylece if true; then echo hello; fikomut yankı olacaktır merhaba beri truedöndü 0.
llua

1
@llua Anlamsız değil. ifadede ( ) komutu olmayan $?son ardışık düzenin durumunu tutar . Örnek, başarılı olup olmadığını test etmektir . Aynı işlemi ve ile yapabilirsiniz, ancak karşılaştırıldığında uzun, okunamayan çizgiler yapabilir . Aynı argüman için gidiyortest[ifsome command&&||if [ $? -eq 0 ]if some command
bonsaiviking

@bonsaiviking Neyin $?genişlediğinin farkındayım, testkullanılmakta olan bir nokta olmadığına işaret ediyorum ; çünkü if some commandaynı şeyi tek bir ifadeyle iki ayrı ifadeye sahip olmakla yapar. komut zaten uzunsa, üç karakter daha eklemek 'okunamazlığı' çok daha fazla 'okunamaz hale getirmez.
llua

Yanıtlar:


33

Tarihinden sonra, [diğerinden önce bir boşluk ekleyin ]:

function foo {
   (cd $FOOBAR;
   <some command>
   if [ $? -ne 0 ]
   then
      echo "Nope!"
   else
      echo "OK!"
   fi
   )
}

[Bir kabuk yerleşiğidir, bir komut gibi bulun echo, read, expr... kendinden sonra bir alana ihtiyacı ve eşleştirme gerektirir ].

Yazma [ $? -ne 0 ]aslında başlatıyordur [ve ona 4 parametre vererek: $?, -ne, 0, ve ].

Not: Bir hata mesajı [1: command not foundalıyorsanız bunun $?değeri olduğu anlamına gelir 1.


1
Linux VM'imde yanıtınızın doğru olduğunu yeni doğruladım.
samiam

[bağlantısıdır testyanı
Ricky Işın

2
@RickyBeam çoğu kabukta, [bir kabuk yerleşiktir ve /usr/bin/[nadiren kullanılır.
Patrick

20

Veya $?tamamen atlayabilirsiniz . Komutunuz cmdaşağıdaki gibidir:

function foo {
   (cd $FOOBAR;
   if cmd
   then
      echo "OK!"
   else
      echo "Nope!"
   fi
   )
}

6

Dönüş değerini kullanmadan önce bir değişkene atamak iyi bir uygulamadır

retval="$?"
if [ $retval -ne 0 ]

Dönüş değerini yeniden kullanmanızı sağlar. örneğin bir if ... elif ... başka ... ifadesinde.


-1: Sonra boşluk unuttun (boşluk [olmadan, sözdizimi hatası olur bash) Hatayı düzenleyip düzeltirseniz geri alır.
samiam

Evet, haklısın. Onardım.
Abdul

@samiam bu son yorum size yönelikti
terdon

4
:) Cevabınızı biraz genişletir misiniz? Neden iyi bir uygulama? Ne tür hatalar önlenebilir?
terdon

1
@terdon $?doğrudan kullanmak kötü bir uygulamadır, çünkü komut dosyasını daha sonra düzenlerken komut ile $?kontrol arasına bir satır koyarsanız bu kesilir .
samiam

3

$?Bir [komuta argüman olarak kullanmak istemenizin tek nedeni (bu [komutun bir ififadenin koşul kısmında çalıştırılıp çalıştırılmamış olması ), belirli bir dönüş durumunda ayrımcılık yapmak istemenizdir:

until
  cmd
  [ "$?" -gt 1 ]
do
  something
done

Herkes için sözdizimi if, while, until... ifadeleri ise

if cmd-list1
then cmd-list2
else cmd-list3
fi

Başarılı veya başka türlü cmd-list2çalışırsa hangisi çalışır .cmd-list1cmd-list3

[ "$?" -eq 0 ]Komut no-operasyon. $?0 ise $?0, $?sıfır değilse sıfır olarak ayarlar .

cmdBaşarısızsa bir şey çalıştırmak istiyorsanız :

if ! cmd
then ...
fi

Genel olarak, $?hangi değerin trueveya ne anlama geldiğini bilmenize izin vermenize gerek yoktur false. Belirli durumlar üzerinde ayrımcılık yapmanız gerekiyorsa veya daha sonra (örneğin, bir işlevin dönüş değeri olarak döndürmek için) kaydetmeniz gerekiyorsa, yukarıda belirtildiği gibi sadece durumlar:

f() {
  cmd; ret=$?
  some cleanup
  return "$ret"
}

Bir değişkeni tırnaksız bırakmanın split + glob operatörü olduğunu da unutmayın. Bu operatörü burada çağırmak mantıklı değil, bu yüzden:

[ "$?" -ne 0 ]

değil [ $? -ne 0 ], yalnız bırakın [$? -ne 0 ](bu sadece ilk karakterini içeriyorsa [komutu çağırır ).$IFS$?

Ayrıca Bourne işlevini tanımlamanın function-name()bir komutun önüne geçmektir. Yani hariç kabuğu gibi her Bourne durum bashve yash(ve son sürümlerinde poshyalnızca bileşik komutu (bileşik komutları olmanın izin) {...}veya (...)ya da benzeri şeyler for...done, if...fi...

function foo { ... }bir kshfonksiyon tanımlama sözdizimi. Burada kullanmak istemenizin bir nedeni yok.

Kodunuz taşınabilir (POSIXly) yazılabilir:

foo() (
  cd -P -- "$FOOBAR" || return # what if the cd failed!
  if
    <some command>
  then
    echo 'OK!'
  else
    echo 'Nope!'
  fi
)

Dikkat edilmesi gereken cdolmadan -Pçok özel bir anlam içermemelidir (kolları yolları vardır ..başka komutu farklı bileşenler), bu önlemek karışıklıklar komut dahil etmek daha iyidir bu yüzden.

( başarısız olursa bu işlev geri döner falseancak cdbaşarısız olmazsa döndürür <some command>).


1

Aşağıdaki komutun istediğiniz her şeyi tek bir satırda yapacağına inanıyorum.

(( verify = $?!=0?'Nope!':'OK!' ))
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.