Bir komut için set -e nasıl devre dışı bırakılır?


36

Set -e komutu, herhangi bir komut sıfır olmayan bir çıkış kodu döndürdüğünde hemen bash betiğinin başarısız olmasına neden olur.

  1. Bir betiğin içindeki tek bir komut için bu davranışı devre dışı bırakmanın kolay ve zarif bir yolu var mı?

  2. Bu işlev hangi yerlerde Bash Reference Manual'de ( http://www.gnu.org/software/bash/manual/bashref.html ) belgelenmiştir ?

Yanıtlar:


29
  1. Bunun gibi bir şey:

    #!/usr/bin/env bash
    
    set -e
    echo hi
    
    # disable exitting on error temporarily
    set +e
    aoeuidhtn
    echo next line
    
    # bring it back
    set -e
    ao
    
    echo next line

    Koşmak:

    $ ./test.sh
    hi
    ./test.sh: line 7: aoeuidhtn: command not found
    next line
    ./test.sh: line 11: ao: command not found
  2. setYerleşik yardımda açıklanmıştır :

    $ type set
    set is a shell builtin
    $ help set
    (...)
    Using + rather than - causes these flags to be turned off.

Aynı burada belgelenmiştir: https://www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin .


Teşekkürler! Başka bir olasılık buldum: #! / Bin / bash set -e # Set -e efektini görmek için bir sonraki satır: #blubb if blubb; sonra yankı "Komut blubb başarılı oldu." else echo "Komut blubb başarısız oldu. Çıkış kodu: $?" fi echo normal komut dosyası çıkışı
Gustave

22

Kefaleti hatalı olarak belirlemeye bir alternatif, ne olursa olsun bir başarıyı zorlamak olacaktır. Böyle bir şey yapabilirsiniz:

cmd_to_run || true

Bu 0 (doğru) döndürür, bu nedenle set -e tetiklenmemelidir


3
faulty_cmd || :bunun için başka bir popüler deyimdir. (Bu :eşanlamlı bir komuttur true).
ulidtko

3
@ ulidtko - ilginç. Bu bulmak için tavşan deliğine götürdü stackoverflow.com/questions/3224878/... gerçek vs. geçmişini almak için:
Ernie

12

Dönüş / hata kodunu (işlev veya çatal) yakalamaya çalışıyorsanız, bu işe yarar:

function xyz {
    return 2
}

xyz && RC=$? || RC=$?

8

"Hemen kabuk çık" seçeneği geçerliyse veya yoksayılırsa, yürütülen komutun içeriğine bağlıdır ( Setin Yerinde bulunan Bash Referans El Kitabı bölümüne bakın - Arkadiusz Drabczyk sayesinde).

Özellikle, eğer bir komut if ifadesinde testin bir parçasıysa, seçenek yoksayılır. Bu nedenle, bir komut yürütmek ve şöyle bir if ifadesi kullanarak bir "hemen bağlamdan çıkmak" içindeki başarısını veya başarısızlığını kontrol etmek mümkündür:

#!/bin/bash

set -e

# Uncomment next line to see set -e effect:
#blubb

if blubb; then
  echo "Command blubb was succesful."
else 
  echo "Command blubb failed. Exit code: $?"
fi
echo "Script exited normally."

"Then" ifadesini atlamak ve daha az satır kullanmak mümkündür:

if blubb; then :;
else echo "Command blubb failed. Exit code: $?"; fi

2

Oldukça basit bulduğum bir başka yaklaşım (ve setek olarak diğer seçeneklere de uygulanıyor -e):

$-Ayarları geri yüklemek için kullan .

Örneğin:

oldopt=$-
set +e
# now '-e' is definitely disabled.
# do some stuff...

# Restore things back to how they were
set -$oldopt

İçin olsa -eözellikle seçenekler diğerleri (mentined gelmiş || trueveya "içeriden koymak if") daha deyimsel olabilir.


0

Aslında son zamanlarda benzer bir sorum vardı (her ne kadar yayınlamamıştım, etrafına dolaştım), ve görebildiğim kadarıyla, komuttan önce set + e kullanmak ve sonradan en zarif şekilde çalışmak gibi görünüyor. İşte bir örnek, komutun cevabını kapmak ve hatanın atmasına izin vermemek.

#!/bin/sh

args=""
for argcol in $*
do
    args="${args} ${argcol}"
done
fortunevar=""
fortfail=""
{
    set +e
    fortunevar=`fortune $args`
    fortfail=$?
    set -e
} &> /dev/null
if [ $fortfail == 0 ]
then
    echo ${fortunevar}
    say ${fortunevar}
else
    echo misfortune: an illegal option was detected!
    echo misfortune: usage: misfortune [-afilosw] [-m pattern][ [#%] file/directory/all]
fi

Bu, “servet” in çıktısını alır, çıkış durumunu kontrol eder ve yankılanır ve söyler. Sanırım istediğin bu mu, yoksa en azından benzer bir şey mi? Neyse, umarım bu yardımcı olur.


Açıklığa kavuşturmak için, kıvırcık parantez içindeki / dev / null'a yönlendirilen bit, peşinde olduğunuz şeydir, inanıyorum. Komutun çıkış yok olmasını sağlar ve programdan çıkmadan hata durumunu kontrol eder.
Addison Crump,

0

Geçici olarak bir şeyi değiştirmek istiyorsanız alt kabuğu başlatmak istiyorum. Altındaki komut, ilk bad_command'ın yoksayıldığını ve ikincisinin yürütmeyi durdurduğunu gösterir.

bash -c 'set -e ;\
( set +e; bad_command ; echo still here ) ;\
echo even here ; \
bad_command ; \
echo but not here;'
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.