Bir bash işlevinden değer döndürme


10

Sayı geçerli bir on basamaklı sayı ise 1 döndüren bir işlevi var:

valNum()
{
    flag=1
    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=0
    fi
    return $flag
}

Tarafından çağrılıyor:

if [[ $(valNum $num) -eq 1 ]]; then
      #do something
fi

Sayı geçerliyse işlev iyi çalışıyor ancak geçersiz bir sayı girilirse sözdizimi hatası gösteriyor.

Yanıtlar:


14

@ choroba'nın cevabı doğrudur, ancak bu örnek daha açık olabilir:

valNum $num
valNumResult=$? # '$?' is the return value of the previous command
if [[ $valNumResult -eq 1 ]]
then
  : # do something
fi

Bu örnek biraz daha uzundur ( $valNumResulto değeri ayarlamak ve sonra sorgulamak), ancak daha açık bir şekilde ne olduğunu açıklar: bu valNum()bir değer döndürür ve bu değer sorgulanabilir ve test edilebilir.

PS Lütfen kendinize bir iyilik yapın ve 0için trueve sıfır olmayan için geri dönün false. Bu şekilde, geri dönüş değerini, hata durumunda "neden başarısız olduğumuzu" belirtmek için kullanabilirsiniz.


8

Bash içindeki işlevler yalnızca çıkış kodlarını döndürebilir. Buna karşılık komut ikamesi, bir komutun veya fonksiyonun standart çıktısını almak için kullanılır. Bu nedenle, iade edilen bayrağı kontrol etmek için değiştirmeye ihtiyacınız yoktur:

if valNum "$num" ; then
    # ...
fi

Ancak, çalışması için, sayı geçerliyse 0, değilse 1 döndürmelisiniz (çıkış kodu 0 hata yok demektir).


Anlamıyorum. Tldp.org/LDP/abs/html/complexfunct.html'deki örnek 24.7'de işlev çıkış kodunu değil, maksimum değeri döndürüyor. Öneriniz çalışıyor olsa da neden çalıştığını anlayamıyorum
user2179293

1
testiniz, girişin geçerli 10 basamaklı bir tam sayı olup olmadığını, yani doğru veya yanlış olduğunu bulmak olduğundan işlev 0 veya 1 değerini döndürür. choroba'nın örneği çalışır if valnum "$num", if valnum "$num" = 0yani "doğru ise" eşdeğeridir . sh komut dosyasında temel kural 0 = true / başarı, sıfır olmayan = false / hata.
cas

2
BTW, "Gelişmiş Bash-Scripting Kılavuzu" çok iyi bir rehber değil - birçok şey hakkında yanlış ve bazı kötü komut dosyası uygulamalarını teşvik ediyor. mywiki.wooledge.org/BashFAQ adresindeki Bash SSS'si çok daha iyi bir kaynaktır.
cas


"Geçersiz Sayı" dizesini yankıladığı için işleviniz başarısız oluyor ve ardından bu dize ile 1 sayısı arasındaif [[ $(valNum $num) -eq 1 ]]
cas

5

Kabuk işlevinden rastgele bir sonuç döndüremezsiniz. Yalnızca 0 ile 255 arasında bir tamsayı olan bir durum kodu döndürebilirsiniz. (Daha büyük bir değeri iletebilmenize returnrağmen, modulo 256 kesilir.) Değerin başarıyı belirtmek için 0, başarısızlığı göstermek için farklı bir değer olması gerekir; kural olarak, daha yüksek değerlerin özel bir anlamı olduğu için (125 ve 127 için kötü harici komut, daha yüksek değerler için bir sinyal tarafından öldürüldü) 1 ile 125 arasındaki hata kodlarına bağlı kalmalısınız.

Burada evet ya da hayır sonucunu döndürdüğünüz için bir durum kodu uygundur. Yana flagbir başarı veya başarısızlık belirtmek görünüyor, başarısız (Yazdıklarınız tersi) için başarı için 0 ile 1 arasında geleneksel değerlerini kullanmalıdır. Daha sonra işlevinizi doğrudan bir if ifadesinde kullanabilirsiniz.

valNum ()
{
  local flag=0
  if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
    echo 1>&2 "Invalid Number"
    flag=1
  fi
  return $flag
}
if valNum "$num"; then
  #do something
fi

Hata kodları arasında ayrım yapmanız gerekirse, işlevi doğrudan arayın. Geri döndükten hemen sonra, hata kodu şurada kullanılabilir $?. Daha sonra bunu bir vaka bildirimi ile kontrol edebilirsiniz:

valNum "$num"
case $? in 

Durum kodunu daha sonra kullanmanız gerekirse $?, bir sonraki komutun üzerine yazılmadan önce başka bir değişkene kaydedin .

valNum "$num"
valNum_status=$?

Yazdığınız şey işe yaramadı çünkü komut ikamesi $(…), kodunuzda hata mesajı veya boş olan işlevin çıktısına genişler, asla 1.

Kabuk işlevlerinden bir durum kodunun izin verdiğinden daha fazla bilgi iletmeniz gerekiyorsa, iki olasılığınız vardır:

  • Standart çıktıya bazı metinler yazdırın ve işlevi komut yerine kullanıldığında çağırın: $(valNum "$num")
  • İşlev içindeki bir veya daha fazla değişkene atayın ve bu değişkenleri daha sonra okuyun.

2

Bu alanda kendimde çelişkili sonuçlar yaşadım. İşte benim ampirik deneylerimin sonuçları. İlk olarak, bash veya * nix komutlarıyla ilgili bazı ' teori ':

  • BAŞARI == 0 ... viz. hata durum kodu yok)
  • FAIL! = 0 ...... bazı durum kodu

Misal:

if  ls -lt /nonexistantdir
then 
    echo "found"
else
    echo "FAIL"
fi
#
echo
ls -lt /nonexistantdir; echo "status = $?"
echo "status = $?"

Çıktı:

ls: cannot access '/nonexistantdir': No such file or directory
FAIL... 

ls: cannot access '/nonexistantdir': No such file or directory
status = 2

Gösterildiği gibi, lskomut durum kodu = 2 değerini döndürür. Geçerli bir dizini denediğinizde durum sıfırdır ( 0 ). Hemen hemen tüm diğer dillerle aynı değil.

kural # 1 - Marka ...

  • DOĞRU == 0
  • YANLIŞ! = 0

Hata kodlarını bir Bash ifadesinde test ettiğimizi hatırlamalıyız if. Sabitleri ayarladım veya kabuk trueveya falsekomutları kullanabilirsiniz .

TRUE=0
FALSE=1

#  valid number function
#
valNum()
{
    flag=$TRUE

    if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then
        echo "Invalid Number"
        flag=$FALSE
    fi
    return $flag
}

#    later on ...
#
if validNum Abc 
then
    echo "Lucky number"
else
    echo "Not lucky."
fi

ve çıktı:

Invalid Number
Not lucky.

Bununla birlikte, herhangi bir ' yukarı oy ' @Gilles vermenizi öneririm çünkü cevabı doğru. Ben sadece ePaper basit tarafı aşağı almak istedim.

Bir şey daha var, testkomut. Bu şuna benzer:

[[ some-expression ]]; 

Çoğu zaman. Örneğin:

$ test 1
$ echo "result = $?"
result = 0
$ test 0
$ echo "result = $?"
result = 0

Sıfır (0) doğrudur . Neden? Man sayfası, NULL DEĞİL olduğunda tek bir argümanın ' true ' olduğunu söyler .

Referanslar:

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.