2016-09-29 54 views
1

我對bash腳本相當陌生。我有4個嵌套的bash腳本,並且我無法適當地從第4個腳本中傳播錯誤。例如:如何從源bash腳本返回錯誤

script1.sh: 
    source script2.sh 
    <check for error and display appropriate message> 
script2.sh: 
    source script3.sh param_1 
    <return to script1 on error> 
    source script3.sh param_2 
    <return to script1 on error> 
    source script3.sh param_n 
    <return to script1 on error> 
script3.sh 
    <some processing> 
    script4.sh 
    echo "this statement is not reached" 
    return $? 
script4.sh 
    <some processing> 
    exit $? 

我的要求是:

  1. 我需要定義在SCRIPT1關聯數組,其被填充在SCRIPT2和script3的範圍可用。我認爲,要做到這一點的唯一方法是源SCRIPT2和script3
  2. script4執行不採購,因爲這個腳本也可以independantly這些父腳本

thread談到使用return語句返回的執行從源bash腳本,但腳本4執行我需要退出。我不明白爲什麼script4中的exit語句會導致原始shell和子shell都終止?當然,它只應該退出子殼?

我需要看信號和陷阱嗎?

感謝所有幫助

+0

你說的是正確的:在一個子shell的'exit'應該只能退出該子shell。也許在執行之前在shell中設置-x,並研究跟蹤輸出。 – gilez

+1

源文件本身並不創建一個子shell,它所做的只是讀取並執行源文件,就好像它在主腳本中一樣。 'return'從源文件返回,是一種特殊情況。 'exit'終止這個過程。也許「sub-shell」這個詞讓你感到困惑?子shell是執行當前shell的副本的子進程,通常通過將命令放在括號'()'中來創建。我在代碼中看不到任何子shell。 – cdarke

+0

你是否在任何地方使用'set -e'? –

回答

0

你可以繼續啓用set -e如果你想。然後,你必須更加小心調用,你知道的退出狀態可能是非零的腳本:

script3.sh 
    <some processing> 
    if script4.sh; then 
    rc=0 
    else 
    rc=$? 
    fi 
    echo "script4 complete" 
    return $rc 

https://www.gnu.org/software/bash/manual/bashref.html#index-set

IMO,使用set -e是合適的,如果你真的想放棄你的程序出現任何錯誤。在這裏,你想要<check for error and display appropriate message>的地方,情況顯然不是這樣。

0

最好的做法是明確的。如果你的代碼總是要進行採購,從而return將是有效的,只是::

source foo || return 

return使用前立即命令,它的默認值的退出狀態,所以沒有需要捕捉,然後通過它。


如果你不知道你是否會採購或執行,這變得更加複雜一點:

source foo || { rc=$?; return "$rc" 2>/dev/null || exit "$rc" }