Bindirme komutunu kullanarak hata nasıl tetiklenir


13

Ubuntu 12.04.2 kullanıyorum. Kabuk komut dosyasında anormal veya hata yakalamak için "tuzak" komutunu kullanmaya çalışıyorum ama aynı zamanda el ile "Hata" çıkış tetiklemeye çalışıyorum.

Çıkış 1'i denedim, ancak "Hata" sinyalini tetiklemeyecek.

#!/bin/bash

func()
{
    exit 1
}

trap "echo hi" INT TERM ERR
func

"Hata" çıkış sinyalini manuel olarak nasıl tetikleyeceğinizden emin değil misiniz?

Yanıtlar:


20

ERRtuzak kabuk kendisi sıfır olmayan bir hata kodu ile çıktığında kod çalıştırmak, bunlarla değilken herhangi bir komut bir parçası değildir kabuk tarafından çalışma durumuna (olduğu gibi if cmd..., veya cmd || ...olmayan bir sıfır ...) çıkışları çıkış durumu ( set -ekabuktan çıkmaya neden olanla aynı koşullar ).

Sıfır olmayan çıkış durumundaki kabuğun çıkışından sonra kodu çalıştırmak istiyorsanız, EXITbunun yerine bir tuzak eklemeli ve $?orada kontrol etmelisiniz :

trap '[ "$?" -eq 0 ] || echo hi' EXIT

Bununla birlikte, sıkışmış bir sinyalde, hem sinyal tuzağının hem de EXIT tuzağının çalışacağına dikkat edin, böylece bunu yapmak isteyebilirsiniz:

unset killed_by
trap 'killed_by=INT;exit' INT
trap 'killed_by=TERM;exit' TERM
trap '
  ret=$?
  if [ -n "$killed_by" ]; then
    echo >&2 "Ouch! Killed by $killed_by"
    exit 1
  elif [ "$ret" -ne 0 ]; then
    echo >&2 "Died with error code $ret"
  fi' EXIT

Veya $((signum + 128))sinyaller gibi çıkış durumunu kullanmak için :

for sig in INT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig")))" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"' EXIT

Bununla birlikte, ana işleminiz terminal kesintisinin bekleme ve birlikte çıkış işlemlerini bashuygulayan bir kabuk olduğunda, SIGINT veya SIGQUIT üzerinde normal olarak çıkmanın potansiyel can sıkıcı yan etkilere sahip olduğunu unutmayın . Bu nedenle, ebeveyninize gerçekten kesintiye uğradığınızı ve bir SIGINT / SIGQUIT aldıysa da çıkmayı düşünmesi için kendinizi aynı sinyalle öldürdüğünüzden emin olmak isteyebilirsiniz.

unset killed_by
for sig in INT QUIT TERM HUP; do
  trap "exit $((128 + $(kill -l "$sig"))); killed_by=$sig" "$sig"
done
trap '
  ret=$?
  [ "$ret" -eq 0 ] || echo >&2 "Bye: $ret"
  if [ -n "$killed_by" ]; then
    trap - "$killed_by" # reset handler
    # ulimit -c 0 # possibly disable core dumps
    kill -s "$killed_by" "$$"
  else
    exec "$ret"
  fi' EXIT

ERRTuzağın ateş etmesini istiyorsanız, falseveya gibi sıfır olmayan çıkış durumuna sahip bir komut çalıştırın test.


6

Kullanım dönüşü olmayan exit bir işlevinden çıkışta durumunu ayarlamak için (işlev düşüyor transparan eğer bir dönüş olmadan, durum son ifadenin yürütülen olmasıdır.) Eğer yerine ise returniçin exitSorunun örnekte, o kadar çalışacak Sanırım amaçladınız: tuzak ERR sözde sinyalinde tetiklenecek ve 'hi' basılacak. Dikkat edilecek diğer noktalar için şunu deneyin:

#!/bin/bash

func()
{
    echo 'in func'
    return 99
    echo 'still in func'
}

trap 'echo "done"' EXIT
trap 'status=$?; echo "error status is $status"; trap - EXIT; exit $status' ERR
func
echo 'returned from func'

0 döndürme, ERR tuzağını yorumlama, ERR işleyicisindeki EXIT tuzağını iptal etmeme, ERR işleyicisinden çıkmama veya dönüşü kaldırma ve fonkta falseson ifade olarak koyma gibi çeşitli değişiklikleri deneyebilirsiniz .

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.