2012-06-21 42 views
26

我正在編寫腳本,然後遇到了一個奇怪的問題。如果我編寫一個腳本,其中包含一些可能調用輸出字符串然後退出的錯誤函數的函數,它將退出我的shell。我知道它爲什麼這樣做。這是因爲一個函數調用與調用者位於同一個進程空間(至少它在bash中),所以函數中的退出會使用提供的退出代碼來終止當前進程。例如:退出函數堆棧而不退出shell

error() 
{ 
    echo $1 
    exit 1 
} 

fn() 
{ 
    if [ $# == 0 ]; then 
    error "Insufficient parameters." 
    fi 
    # do stuff 
} 

$ fn 
Insufficient parameters. 
[shell terminates] 

所以我的問題是,我可以退出的函數棧的所有功能,而不終止當前的shell,沒有產生一個新的子shell?

感謝

回答

30

要退出函數堆棧而不退出殼可以使用命令:

kill -INT $$ 

作爲pizza所述,這就像按下Ctrl-C,這將停止當前腳本運行並將您拖放到命令提示符處。

 

 


注:我沒有選擇pizza的回答是,因爲這被安葬在他/她的回答並沒有直接回答的唯一原因。

+0

看起來好像下面的「return」:這是爲了這個目的而內置在shell中的功能。殺殼是不雅的。 – JPGConnolly

+2

@JPGConnolly你是什麼意思'下面的「返回」是可取的,似乎'?如果你的意思是使用內建的'return'語句,那麼你沒有看到這個問題,因爲沒有簡單的方法來使用它,這樣它就會從一個稱爲幾個函數的函數內跳回到基本shell,而不是必須詢問每個函數調用的返回值,這在某些情況下不可行或不可行。在這種情況下,執行'kill -INT $$'比使用'return'更優雅。 – Adrian

+0

$的值是多少?源函數的調用者看到了嗎?還是它也終止了? – Michael

2

使用return語句,但你需要調用錯誤

+1

函數返回時不需要返回語句。 –

+1

但OP希望函數立即終止,而不是當它到達函數體的底部。 –

+0

我希望堆棧上的所有函數都可以終止。 「但是在if; before do stuff」是什麼意思? – Adrian

1

的外殼並沒有真正有一個例外機制,通過多種功能復卷後添加回電話一次。你必須檢查返回值並手動返回。

+0

我正在檢查下路。只想在不退出shell的情況下退出當前正在運行的所有函數。 – Adrian

+1

這意味着你使用'return'而不是'exit'。但我一直以來的意思是,你必須在每個函數內部做一個單獨的'return',而不是隻在最裏面。 –

+1

這不幸的是沒有用,我想做的事情。 – Adrian

5

您需要將return語句添加到您的每個函數中,以檢查它們依次調用的任何函數的返回值。源文件就像是將代碼剪切並粘貼到當前的上下文中,除了諸如$BASH_SOURCE之類的變量之外。

或者,您可以將fn定義爲shell腳本,以便exit能夠按照您的要求進行操作(除非叉子太貴)。

+1

檢查所有函數退出值是沒有用的。目前,爲了解決這個問題,我讓shell腳本調用其中的各個函數。因此退出它不會退出我的shell。 – Adrian

+0

你不需要檢查所有的退出值 - 只要檢查它是否成功 - '如果my_function' - 或退出代碼是否非零 - 'my_function;如果[$?一個0]'。 – l0b0

+0

將函數定義爲shell腳本是一個很好的解決方案,但是在該函數中使用「exit」將退出shell。 你是正確的使用「返回」來停止函數而不退出shell。 – JPGConnolly

7

你可以做你生成一個

exit() { return $1;} 

然後

source ./your_script 

在回答持懷疑態度,這不僅影響當前的shell,它不會影響炮彈。

的更多信息的形式可以是

exit() { 
    local ans 
    local line 
    read -p "You really want to exit this? " line 
    ans=$(echo $line) 
    case "$ans" in 
      Y);; 
      y);; 
      *)kill -INT $$;; 
    esac 
    unset -f exit 
    exit $1 
} 
+4

隱藏/覆蓋builtins從來不是一個好主意。 – glglgl

+0

這不是有效的Bash語法。 –

+0

它是有效的語法。 – pizza