【问题标题】:Exit entire program from a function call in shell?从shell中的函数调用退出整个程序?
【发布时间】:2009-11-29 21:23:36
【问题描述】:

我有一个在我的 shell 脚本中使用的函数,并且基于某个条件,我想在该函数中调用“exit 0”,以便整个脚本退出。但是由于某种原因,在函数中调用 exit 0 后程序仍然运行。为什么?

check()
{
    printf "Would you like to try again?\n"
    read S
    if [ "$S" = "y" ]
    then 
        ./myprog
    else    
        exit 0  
    fi
}

我这样称呼它:

if test $WRONG -eq 7
then
    printf "Sorry\n"
    check
fi

【问题讨论】:

  • 如果您发布包含退出的脚本部分会有所帮助。
  • 调用check的测试代码和check shell过程在同一个实际的shell源文件中吗?
  • 是的,在同一个脚本里有,并且函数是在测试执行前定义的。

标签: shell unix


【解决方案1】:

你有什么对我有用:

$ cat test-shell-exit
#!/bin/sh
check()
{
    printf "Would you like to try again?\n"
    read S
    if [ "$S" = "y" ]
    then
        echo Try again
    else
        echo Done
        exit 0
    fi
}
echo Before
check
echo After

$ ./test-shell-exit 
Before
Would you like to try again?
y
Try again
After

$ ./test-shell-exit 
Before
Would you like to try again?
n
Done

您能否尝试这个测试用例并根据与它的任何差异更新您的答案?您遇到的问题似乎是由您未提及的事情引起的。


更新:使用循环而不是再次调用程序的示例:

$ cat test-shell-exit 
#!/bin/sh
check()
{
    printf "Would you like to try again?\n"
    read S
    if [ "$S" = "y" ]
    then
        echo Try again
    else
        echo Done
        exit 0
    fi
}
while true; do
    echo Before
    check
    echo After
done

$ ./test-shell-exit 
Before
Would you like to try again?
y
Try again
After
Before
Would you like to try again?
y
Try again
After
Before
Would you like to try again?
n
Done

【讨论】:

  • 您的脚本运行良好。但是我注意到别的东西。我的主脚本的初始运行之一也可以。但是,如果在第一次运行期间我为问题选择“y”并且我的程序通过调用“./myprog”再次调用自身并且我在该运行中遇到该问题然后退出失败。
  • 啊,你又调用了同一个程序,这意味着你确实调用了一个子shell,并且退出它不会影响“外部”shell。不要那样做。将您的程序编写为一个循环,并通过检查确定是继续还是退出该循环。您也可以使用exec 作为尾递归的有限形式,但我不确定这是否会产生不必要的副作用。 (可能取决于您的程序。)
  • 所以没有办法强制退出任何级别的子shell?
  • 您不能强制父进程退出。您可以要求它退出(通过某种形式的通信)或要求操作系统终止它(KILL 信号,这与父级退出不同——您也绝对不希望这里出现这种情况)。然而,似乎这个问题最好用一个简单的循环来解决,而不是任何一个。
  • 呵呵,我通过在调用“./myprog”后加上“break”来修复它,感谢您的帮助!
【解决方案2】:

如果没有任何代码可以通过,我猜你的函数正在调用一个子 shell,它是那个正在退出()的子 shell,而不是运行主脚本的父 shell。

【讨论】:

  • 对,看起来这就是正在发生的事情。我怎样才能退出主脚本呢?
  • 我没有看到任何会创建子外壳的东西。
  • 对“./myprog”的调用怎么样,因为当这不起作用时。它总是在程序第一次运行时起作用,但在其他任何时候都不起作用。
【解决方案3】:

我原以为您的代码会退出子 shell,但我看不出有任何原因,代码看起来不错,而且它似乎按我的预期运行。

所以我的猜测是,要么你没有阅读 y,而你认为​​你没有阅读,要么你真的在阅读 exit 0,只是在你的测试结果中没有注意到它。

当您说“程序仍在运行”时,您的意思是“shell 程序在调用check 过程后仍然运行”吗?

【讨论】:

    【解决方案4】:

    我同意 digitalross 的观点,即您向我们展示的内容之外的东西导致了这种行为。 exit 0 将退出当前进程。所以以某种方式 check() 正在退出的单独子进程中运行。您是否有调用此调用之外的代码?

    顺便说一句,您正在运行哪个操作系统和 shell?

    您可以通过类似的方式强制父母退出(语法取决于您的 shell)

    check() || exit $?
    

    比尔

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2023-03-16
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      相关资源
      最近更新 更多