$ Kullanmak için en iyi uygulama? bash?


10

Bu cevabı $ hakkında okuduğumda ? başka bir soru akla geliyor.

$ Kullanımı için en iyi uygulama var mı? bash?


Bir örnek verelim:

Doğrusal bir senaryomuz var ve tüm komutun tamam olduğunu bilmek istiyorum. Hata kodunu kontrol etmek ve eğer değilse kırmak için küçük bir fonksiyon çağırmanın (buna "did_it_work" diyelim) uygun olduğunu düşünüyor musunuz?

#!/bin/bash 

function did_it_work {
    code=$1
    if [ "$code" -ne "0" ]
    then
        echo "Error failure: code $code "
        exit 1
    fi
}

dir=some/path

mkdir -p $dir
did_it_work $? 

cd $dir
did_it_work $? 

run_some_command
did_it_work $? 

Tabii ki bu yaklaşım, eğer varsa, sorunu manuel olarak çözmem ve senaryoyu tekrar çalıştırmam gerektiği anlamına gelir.

Bunun iyi bir fikir olduğunu düşünüyor musunuz yoksa bunu yapmak için başka iyi uygulamalar var mı?

/Teşekkürler

Yanıtlar:


15

Ortak bir yol:

die() {
    IFS=' ' # make sure "$*" is joined with spaces

    # output the arguments if any on stderr:
    [ "$#" -eq 0 ] || printf '%s\n' "$*" 1>&2
    exit 1
}

o zaman böyle kullanın:

mkdir -p some/path || die "mkdir failed with status $?"

Veya çıkış durumunu içermesini istiyorsanız şu şekilde değiştirebilirsiniz:

die() {
    last_exit_status=$?
    IFS=' '
    printf '%s\n' "FATAL ERROR: $* (status $last_exit_status)" 1>&2
    exit 1
}

ve sonra kullanmak biraz daha kolay:

mkdir -p some/path || die "mkdir failed"

Başarısız olduğunda, mkdirbüyük olasılıkla zaten bir hata mesajı yayınlamış olur, böylece ikincisi gereksiz olarak görülebilir ve şunları yapabilirsiniz:

mkdir -p some/path || exit   # with the same (failing) exit status as mkdir's
mkdir -p some/path || exit 1 # with exit status 1 always

(veya dieyukarıdaki ilk değişkeni bağımsız değişken olmadan kullanın )

Daha command1 || command2önce görmemeniz command1durumunda çalışır ve command1başarısız olursa çalışır command2.

Böylece "dizini oluştur veya öl" gibi okuyabilirsiniz.

Örneğiniz şöyle görünecektir:

mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"

Ya diesda ana kodun daha açık olması için sağdaki daha fazla hizalayabilirsiniz .

mkdir -p some/path         || die "mkdir failed"
cd some/path               || die "cd failed"
some_command               || die "some_command failed"

Veya komut satırları uzun olduğunda aşağıdaki satırda:

mkdir -p some/path ||
  die "mkdir failed"

cd some/path ||
  die "cd failed"

some_command ||
  die "some_command failed"

Ayrıca, adı some/pathbirden çok kez kullanacaksanız, yazmaya devam etmek zorunda kalmamanız için bir değişkende saklayın ve gerekirse kolayca değiştirebilirsiniz. Değişken argümanlarını komutlara --iletirken, argüman ile başlarsa argümanın bir seçenek olarak alınmaması için seçenek sınırlayıcıyı kullandığınızdan emin olun -.

dir=some/path
mkdir -p -- "$dir"         || die "Cannot make $dir"
cd -P -- "$dir"            || die "Cannot cd to $dir"
some_command               || die "Cannot run some_command"

9

Kodunuzu şu şekilde yeniden yazabilirsiniz:

#!/bin/bash
function try {
    "$@"
    code=$?
    if [ $code -ne 0 ]
    then
        echo "$1 did not work: exit status $code"
        exit 1
    fi
}

try mkdir -p some/path
try cd some/path
try run_some_command

Hata kodunu gerçekten günlüğe kaydetmeniz gerekmiyorsa, ancak komutun başarılı olup olmadığı konusunda try()daha fazla kısaltabilirsiniz :

function try {
    if ! "$@"
    then
        echo "$1 did not work"
        exit 1
    fi
}

Kodu bu biçimde de kullanabilirsiniz. <pre> işlevini deneyin {
BillThor

Bu işlevselliği yerinde kullanırsanız ve gerçek taraftan geri dönmek istemezseniz yerleşik return $?ile değiştirebilirsiniz :.
BillThor

8

Gerçekten exitbir hata yapmak istiyorsanız ve Bash kullanıyorsanız, dikkate almalısınız set -e. Gönderen help set:

-e Bir komut sıfır dışında bir durumla çıkarsa hemen çıkın.

Bu elbette size did_it_work () işlevinin esnekliğini sağlamaz, ancak bash betiğinizin yeni işlevinize çok fazla çağrı eklemeden bir hata üzerinde durduğundan emin olmanın kolay bir yoludur.


set -ekullanışlı. Normal koşullar altında sıfır dışında dönen bazı komutlar vardır (örneğin, diff). Sıfır olmayan bir dönüş beklediğim bir komut dosyasında set -e'yi kullanırken, yapıyorum command || true.
Shawn J. Goff

2
Ayrıca, kullansanız bile set -e, tüm hataları yakalamak için bir "istisna işleyici" ayarlayabilirsiniz trap did_it_work EXIT.
Gilles 'SO- kötü olmayı kes'

1
Bu POSIX'in bir parçasıdır, bash'a özgü bir özellik değildir. Kullanın ama bazı tuzaklardan haberdar olun mywiki.wooledge.org/BashFAQ/105
kmkaplan

@ ShawnJ.Goff Yapmayı tercih ederim command && true. Bunun gibi dönüş değeri olan değil değişti.
kmkaplan

@kmkaplan Son yorumun benim için bir anlam ifade etmiyor. Amacı, sıfırdan farklı olmayan bir çıkış kodu döndürürse komut dosyasından çıkmayı command || trueönlemektir . Çıkış kodunu değiştiriyor, çünkü ihtiyacımız var. Tek komut `başarılı olursa (sıfır çıkış kodu döndürürse) çalıştırılır (sıfır çıkış kodu döndürür) - tam bir işlem yapılmaz. set -ecommandcommand && truetrue
Üçlü
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.