Bir komutun başarılı olup olmadığını nasıl kontrol edebilirim?


234

Bir komutun yürütülmesinde bir hata olup olmadığını kontrol etmenin bir yolu var mı?

Örnek :

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

Bunu zaten denedim ama işe yaramadı gibi görünüyor. Bunu nasıl yapmam?


9
Tercih $ (foo) ters tırnakların üzerinde `foo` sen Nest çünkü yapabilirim, ve kesme ayırt etmek kolaydır.
kullanıcı bilinmeyen,

1
BTW, validçağırmadan önce bir işlev ( ) tanımlamanız gerekir.
wjandrea,

Yanıtlar:


344

Dönüş değeri saklanır $?. 0 başarıyı, diğerleri hatayı gösterir.

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

Diğer herhangi bir metinsel değer gibi, gelecekteki karşılaştırma için bir değişkende saklayabilirsiniz:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

Muhtemel karşılaştırma operatörleri için bkz man test.


Bu güzel ... çıktı hatasını tutabilir miyim ?? !! , çünkü bu durumda 2 hata var: komut hatası "metin" ex, dosya bulunamadı ve benim hata "metin" Bu durumda olan örneğin başarısız oldu
moata_u 7:11

@ moata_u: değeri cevabımda gösterildiği gibi bir değişkende saklayabilirsiniz.
Lekensteyn

@moata_u: Bir koymak gerekir ;önce elseve fi; `eğer ...: sonra ...; Başka ...; fi
Lekensteyn


1
@Blauhirn [ $? ](veya eşdeğeri test $?) çalışmaz , çünkü $?boş olmayan bir sayıya (0, 1 vb.) Göre değerlendirilir. Bkz için dokümanlartest : "İFADE atlanırsa, 'test' false döndürür İFADE tek argüman, 'test' argümanı aksi geçersiz ve doğruysa yanlış döndürür.."
Lekensteyn

87

Yalnızca komutun başarılı veya başarısız olduğunu bilmeniz gerekiyorsa, testi zahmet etmeyin $?, sadece doğrudan komutu test edin. Örneğin:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

Ve çıktıyı bir değişkene atamak dönüş değerini değiştirmez (peki, stdout elbette bir terminal olmadığında farklı davranmazsa).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionalsif daha ayrıntılı olarak açıklar .


Dallanmadan başka bir şey yapmak istiyorsanız, başarısız olup olmadığına dair booleni saklamak gibi bir şey. Öyleyse çıkış değişkeniniz bunu yapmaz, ancak $?yapar, bu nedenle komutu doğrudan sınamanızın kesinlikle daha iyi olduğunu söylerken yanlışsınız.
Timothy Swan

Bir kullandığında bir değişkene çıkış atama dönüş değeri değişebilir local, yani komutu local foo=$(false); echo $?;üreten 0çıkış. Ancak local, yalnızca bash işlevlerinin içinde geçerlidir.
Cromax

26
command && echo OK || echo Failed

Ekranda commandhata verirse , nasıl gizlenir?
Sigur

Eğer commandstderr'e dışarı hataları yazar, formu kullanabilirsiniz command 2> /dev/null && echo OK || echo Failed. 2> /dev/nullYönlendirmeleri çıktı stderr /dev/null. Bununla birlikte, bazı yardımcı programlar stdout'a hatalar yazacaktır (bu kötü bir uygulama olsa da). Bu durumda 2 yönlendirmesini atlayabilirsiniz, ancak komuttaki tüm çıktıları kaybedersiniz. Başarıyı kontrol etmenin bu yöntemi basit üçlü mantık için iyidir ancak daha karmaşık davranış $?için komut başarısını kontrol etmek veya if@ geirha'nın cevabında belirtilen blok yöntemini kullanmak en iyisidir.
En Büyük Bender

17

, $? önceki komutun çıkış durumunu içermelidir, hata yapılmadan sıfır olmalıdır.

Yani, gibi bir şey;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

Çoğu durumda, & & construct'ı birbirine bağlı olması gereken komutları zincirlemek için kullanmak daha kolaydır. Yani cd /nonexistant && echo success!olur değil && önce komut sonları çünkü başarıyı yankı. Bunun sonucu olarak ||, cd başarısız olduğu cd /nonexistant || echo fail için yankı başarısız olur. (bu, önceki komut başarısız olursa betiği sonlandıracak || exit gibi bir şey kullanırsanız işe yarar.)


Bu güzel ... çıktı hatasını tutabilir miyim ?? !! , çünkü bu durumda 2 hata var: komut hatası "metin" ex, dosya bulunamadı ve benim hata "metin" Bu durumda olan örneğin başarısız oldu
moata_u 7:11


5
command && echo $? || echo $?

Demek command; echo $?istiyorsun
Javier Buzzi

Hayır, satırım doğru, başarılı veya başarısız olursa olsun gerçek sonuç kodunu bir sayı olarak verir.
modrobert

1
Tamam, lütfen bunların farklılıklarını bana açıklayın: true && echo $? || echo $?/ true; echo $?ve false && echo $? || echo $?/ false; echo $?- bulursun, aynısını yaparlar: D
Javier Buzzi

Evet, aynı sonuç ancak şartsız. Asıl soru, "Bir komutun başarılı olup olmadığını nasıl kontrol edebilirim?" Diye sormak, önceki cevaplara dayanıyordu. Sanırım daha iyi bir örnek olacaktır:command && echo "success: $?" || echo "fail: $?"
modrobert

5

Bu unutulmamalıdır if...then...five &&/ ||biz (başarısına 0) test etmek istiyorum komutu tarafından döndürülen çıkış durumu ile yaklaşım fırsatlar tipi; bununla birlikte, bazı komutlar, komut başarısız olursa veya girişle baş edemediğinde sıfır olmayan bir çıkış durumu döndürmez. Bu, olağan ifve &&/ ||yaklaşımların bu belirli komutlar için işe yaramayacağı anlamına gelir .

Örneğin, Linux'ta GNU fileargüman olarak mevcut olmayan bir dosya aldıysa ve findbelirtilen dosya kullanıcısını bulamadıysa hala 0 ile çıkar .

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

Bu gibi durumlarda, durumu ele alabilmemizin olası bir yolu , örn. Komutla döndürülenler veya komutun çıktısını ayrıştırma gibi , stderr/ stdinmesaj okumaktır . Bu amaçla, ifade kullanılabilir.filefindcase

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(Bu, unix.stackexchange.com adresindeki ilgili soruya verilen cevabımın bir kopyasıdır )


1

Birçok diğer yanıtlar belirtildiği gibi, basit bir deney $?böyle, yapacak

if [ $? -eq 0 ]; then something; fi

Komutun başarısız olup olmadığını test etmek istiyorsanız bash, aşağıdaki gibi daha kısa bir versiyon kullanabilirsiniz (ama belki fazladan).

if (($?)); then something; fi

Bu, (( ))aritmetik modu kullanarak çalışır , bu nedenle eğer komut geri dönerse success, yani $? = 0test ((0))hangi testlerin yapıldığını değerlendirir false, aksi takdirde döner true.

Başarıyı test etmek için şunları kullanabilirsiniz:

if ! (($?)); then something; fi

ama zaten ilk örnekten daha kısa değil.


1
yapıcı eleştiri?
afuna,


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.