2012-03-09 699 views
121

当我在shell脚本中使用exit命令时,脚本将终止终端(提示)。有什么方法可以终止脚本,然后留在终端中?任何方式退出bash脚本,但不退出终端

我的脚本run.sh预计将通过直接来源或来自另一个脚本来执行。

编辑: 更具体地讲,有两个脚本run2.sh作为

... 
. run.sh 
echo "place A" 
... 

run.sh作为

... 
exit 
... 

,当我通过. run2.sh运行它,如果它击中exit代码行中run.sh ,我希望它停在码头并留在那里。但使用exit,整个终端被关闭。

PS:我曾尝试使用return,但echo代码行仍会被执行....

+3

我真的,真的,真的不得不问:你为什么在源代码中使用exit? – 2012-03-09 20:44:45

+3

exit命令不应该终止您的终端会话/登录。如果使用'exit 0'在成功后终止脚本,当您运行脚本例如'。/ test.sh'时,您应该看到输出,但控制台将保持打开状态。 – 2012-03-09 20:45:18

+0

您可以使用'shell'命令,这实际上是一个shell终端。然而,我自己的经验是,'exit'不会发生这种情况。通常退出将控制返回到父脚本。 – 2012-03-09 20:45:21

回答

173

“问题”的确是您正在采购并且未执行脚本。在源文件时,其内容将在当前shell中执行,而不是产生一个子shell。所以包括exit在内的所有内容都会影响当前的shell。

而不是使用exit的,你会想用return

+1

下面是我发现的另一个解释:http://askubuntu.com/a/53179/148337 – 3cheesewheel 2013-07-26 19:51:20

+0

虽然正确,但这不是一个好的答案。它忽略了调用脚本可能会声明调用脚本需要访问的变量或函数。最好解释一下如何设置返回码,然后在'runs.sh'中处理@ruakh对这个问题有更好的答案。 – MikeSchinkel 2016-08-28 17:08:18

+3

如果该函数是嵌套调用,该怎么办?即呼叫b,b呼叫c,c想要立即退出a和b。 – Michael 2016-09-08 22:00:46

-2

1)退出0会来的剧本,如果它是成功的。

2)如果出现故障,退出1将从脚本中退出。

你可以根据你的需求尝试以上两点。

29

是;您可以使用return而不是exit。它的主要用途是从shell函数返回,但如果在source -d脚本中使用它,它将从该脚本返回。

由于§4.1 "Bourne Shell Builtins" of the Bash Reference Manual所言:

 return [n] 

原因shell函数与返回值ñ退出。 如果没有提供n,则返回值是该函数中执行的最后一条命令的退出状态。 这也可以用于终止正在执行 一个脚本的执行与.(或source)内置,返回任一Ñ或 作为脚本的退出 状态在脚本中最后执行的命令的退出状态。 在执行功能或脚本之后执行之前,执行与RETURN陷阱相关的任何命令 。 返回状态是非零值,如果是return ,而不是由.source执行的脚本的过程中使用的功能之外。

2

这就像你在脚本run2.sh中放置了一个运行函数一样。 您在运行时使用退出代码,同时在bash tty中输入您的run2.sh文件。 如果让run函数有权退出您的脚本,并给run2.sh 它的权力来退出终止符。 然后cuz运行功能有权退出您的终结者。

#! /bin/sh 
    # use . run2.sh 

    run() 
    { 
     echo "this is run" 
     #return 0 
     exit 0 
    } 

    echo "this is begin" 
    run 
    echo "this is end" 

无论如何,我批准与Kaz这是一个设计问题。

0

,如果你的终端模拟器没有-hold你可以清理一个执行的脚本,并与终端:

#!/bin/sh 
sed "s/exit/return/g" script >/tmp/script 
. /tmp/script 
read 

否则,你可以使用$TERM -hold -e script

2

我认为,这是因为你正在运行它源模式 用点

. myscript.sh 

您应该运行在一个子shell:

/full/path/to/script/myscript.sh 

'源' http://ss64.com/bash/source.html

+0

如果''不需要脚本的完整路径。 myscript.sh'工程。至多,你可能需要'。/ myscript.sh'。 – 2014-08-12 11:05:19

0

还要确保与预期的返回值返回。否则,如果在遇到退出时使用exit,它将退出基本shell,因为source不会创建另一个进程(实例)。

9

而不是使用. run2.sh您可以运行使用sh run2.shbash run2.sh
一个新的实例将被打开运行脚本,然后它会在剧本留下打开另一个壳的年底前关闭脚本运行的代码。 `

+0

如果是这样,那么为什么第二个参数'sh“。” run2.sh'? – H0WARD 2015-11-04 17:01:11

+0

@ H0WARD你是对的,我忘了删除点。我现在编辑了答案。 – 2015-11-04 19:43:18

+0

OP显式声明源为需求。 – 2016-12-15 22:32:46

0

正如其他人已经注意到的,源代码与执行脚本使用returnexit保持同一会话不变是正确的。

下面是一个相关的提示,如果你想要一个脚本,应该保持会话打开,不管它是否来源。

以下示例可以直接运行,如foo.sh或采购,如. foo.sh/source foo.sh。无论哪种方式,它会保持会议“退出”后开放。传递[email protected]字符串以便该函数可以访问外部脚本的参数。

#!/bin/sh 
foo(){ 
    read -p "Would you like to XYZ? (Y/N): " response; 
    [ $response != 'y' ] && return 1; 
    echo "XYZ complete (args [email protected])."; 
    return 0; 
    echo "This line will never execute."; 
} 
foo "[email protected]"; 

终端结果:

$ foo.sh
$你想XYZ? (是/否):n
$。 foo.sh
$您想要XYZ吗?(是/否):n
$ |
(终端窗口保持打开状态,并接受额外的输入)

这可以是在一个单一的终端快速测试脚本的变化,同时保持了一堆废代码的主要exit/return下而你的工作是有用的。从某种意义上说,它也可以使代码更具可移植性(如果有大量的脚本可能会或可能不会以不同的方式调用),但在适当的情况下仅使用returnexit就不那么笨拙了。