2015-01-06 18 views
12

fonksiyonları ile bash/-e set + e ayarlamak kullanma:Ben script'lerime böyle basit bir bash başlangıcı kullanarak oldum

#!/bin/bash 
set -e 

modülerliği ile birlikte/işlevlerini kullanarak bu bugün beni ısırdı.

Yani, İdeal, birden çok küçük dosya kullanabilmek için ister başka dosyalara işlevlerini kapsar ve sonra

set +e 
foo 
rc=$? 
set -e 
gibi bu işlevleri arayacağımı yere

foo() { 
    #edit: some error happens that make me want to exit the function and signal that to the caller 
    return 2 
} 

gibi bir işlevi olduğunu varsayalım

. Bu, tam olarak iki katman rutini için çalışır. Ancak, foo bunun gibi altyordamları da çağırıyorsa, dönüşten önceki son ayar set -e olacaktır. Bu, betiğin dönüşte çıkmasını sağlayacaktır - bunu çağrı işlevinde geçersiz kılamam. Peki, ne yapmak zorunda olduğunu bulurum

foo() { 
    #calling bar() in a shielded way like above 
    #..  

    set +e 
    return 2 
} 

çok gariptir (ve ayrıca istediğim gibi değil - Ne bazı bağlamlarda ben başka bağlamlarda iken, arızalara karşı koruyucu olmadan işlevini kullanmak istiyorsanız Temizlemeyi halletmek istiyorum?) Bunu işlemenin en iyi yolu nedir? Btw. Bunu OSX'de yapıyorum, bu davranışın Linux'ta farklı olup olmadığını test etmedim.

+0

Bekler misiniz? Bunu arayan kişiye ekledim mi? Kolon ne yapar? –

+0

Geri dönüşü nasıl kötüye kullandığımı genişletebilir misiniz? Nasıl bir işlev içinde hata sinyali vermeyi kastediyorum? (eğer yeterince açık olmasaydım - 'return 2' sadece bir hata durumunda yapılır. –

+1

Sen değilsin, ama sanıyordum. Benim kötü, pardon. – Carpetsmoker

cevap

13

Kabuk işlevleri gerçekten "çıkış değerleri" içermiyor, yalnızca kodlardan çıkılıyor. Sen arayana && : ekleyebilir

, bu "test" komutunu yapar ve bunu çıkmak olmaz:

foo() { 
    echo 'x' 
    return 42 
} 

out=$(foo && :) 
echo $out 

: "boş komutu" (yani o yapmaz olduğunu. şey). Bu durumda idam edilmez, çünkü sadece foo 0'a dönerse (ki o olmazsa) çalışır.

Bu çıkışlar:

x 

Bu tartışmalı biraz çirkin, ama sonra tekrar, kabuk komut dosyası hepsinden daha bu daha iyi açıklıyor FreeBSD gelen sh(1) aktaran

;-) çirkin biraz tartışmalı olduğunu bash'ın adam sayfası:

-e errexit 
     Exit immediately if any untested command fails in non-interactive 
     mode. The exit status of a command is considered to be explicitly 
     tested if the command is part of the list used to control an if, 
     elif, while, or until; if the command is the left hand operand of 
     an “&&” or “||” operator; or if the command is a pipeline preceded 
     by the ! operator. If a shell function is executed and its exit 
     status is explicitly tested, all commands of the function are con‐ 
     sidered to be tested as well. 
+0

(lanet, yorumlarda yeni satır yok;)). Teşekkürler dostum. Şimdi görüyorum. Bundan böyle, eğer 'test' işlevini yerine getirmek istersem, set + e foo &&: rc = $? set -e –

+1

@ MichelMüller 'set' ile bir şey yapmanıza gerek yok; sadece komut setinizde bunu etkinleştirmek için bir kez set -e' kullanın ve daha sonra olduğu gibi, '&&:' komutunu kullanın. – Carpetsmoker

+0

doğru, mantıklı. Teşekkürler. –

İlgili konular