bash中是否有“goto”语句?我知道这被认为是不好的做法,但我需要特别“去”。


当前回答

还有一种能力可以达到预期的结果:命令陷阱。例如,它可以用于清理目的。

其他回答

如果你使用它来跳过一个大型脚本的一部分进行调试(参见Karl Nicoll的评论),那么If false可能是一个很好的选择(不确定“false”是否总是可用,对我来说它在/bin/false中):

# ... Code I want to run here ...

if false; then

# ... Code I want to skip here ...

fi

# ... I want to resume here ...

当需要提取调试代码时,困难就出现了。“if false”结构是相当直接和容易记住的,但你如何找到匹配的fi?如果您的编辑器允许您阻止缩进,那么您可以缩进被跳过的块(然后当您完成时,您将希望将其放回)。或者fi线上的注释,但它必须是你能记住的东西,我怀疑这是非常依赖于程序员的。

一个简单的可搜索的goto,用于在调试时注释掉代码块。

GOTO=false
if ${GOTO}; then
    echo "GOTO failed"
    ...
fi # End of GOTO
echo "GOTO done"

结果是-> GOTO done

还有一种能力可以达到预期的结果:命令陷阱。例如,它可以用于清理目的。

它确实可能对一些调试或演示需求有用。

我发现Bob Copeland解决方案http://bobcopeland.com/blog/2012/10/goto-in-bash/优雅:

#!/bin/bash
# include this boilerplate
function jumpto
{
    label=$1
    cmd=$(sed -n "/$label:/{:a;n;p;ba};" $0 | grep -v ':$')
    eval "$cmd"
    exit
}

start=${1:-"start"}

jumpto $start

start:
# your script goes here...
x=100
jumpto foo

mid:
x=101
echo "This is not printed!"

foo:
x=${x:-10}
echo x is $x

结果:

$ ./test.sh
x is 100
$ ./test.sh foo
x is 10
$ ./test.sh mid
This is not printed!
x is 101

这是Hubbbitus对Judy Schmidt剧本的一个小修正。

在脚本中放置未转义的标签会导致机器崩溃。这很容易通过添加#来转义标签来解决。感谢Alexej Magura和access_granting的建议。

#!/bin/bash
# include this boilerplate
function goto {  
label=$1
cmd=$(sed -n "/$#label#:/{:a;n;p;ba};" $0 | grep -v ':$')
eval "$cmd"
exit
}

start=${1:-"start"}

goto $start

#start#
echo "start"
goto bing

#boom#
echo boom
goto eof

#bang#
echo bang
goto boom

#bing#
echo bing
goto bang

#eof#
echo "the end mother-hugger..."