bash中是否有“goto”语句?我知道这被认为是不好的做法,但我需要特别“去”。
当前回答
这是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..."
其他回答
一个简单的可搜索的goto,用于在调试时注释掉代码块。
GOTO=false
if ${GOTO}; then
echo "GOTO failed"
...
fi # End of GOTO
echo "GOTO done"
结果是-> GOTO done
我找到了一种使用函数的方法。
例如,您有3个选择:A、B和C。A和Bexecute一个命令,但是C给您更多信息,并再次将您带到原始提示符。这可以使用函数来完成。
请注意,由于包含demoFunction函数的那一行只是设置了函数,因此需要在脚本之后调用demoFunction,以便函数能够实际运行。
您可以通过编写多个其他函数并在需要“GOTO”shell脚本中的其他位置时调用它们来轻松地适应这一点。
function demoFunction {
read -n1 -p "Pick a letter to run a command [A, B, or C for more info] " runCommand
case $runCommand in
a|A) printf "\n\tpwd being executed...\n" && pwd;;
b|B) printf "\n\tls being executed...\n" && ls;;
c|C) printf "\n\toption A runs pwd, option B runs ls\n" && demoFunction;;
esac
}
demoFunction
还有一种能力可以达到预期的结果:命令陷阱。例如,它可以用于清理目的。
尽管其他人已经澄清了bash中没有直接的goto等价(并提供了最接近的替代方法,如函数、循环和break),但我想说明如何使用循环加break来模拟特定类型的goto语句。
我发现这种方法最有用的情况是,如果某些条件不满足,我需要返回到一段代码的开头。在下面的例子中,while循环将一直运行,直到ping停止向测试IP发送数据包。
#!/bin/bash
TestIP="8.8.8.8"
# Loop forever (until break is issued)
while true; do
# Do a simple test for Internet connectivity
PacketLoss=$(ping "$TestIP" -c 2 | grep -Eo "[0-9]+% packet loss" | grep -Eo "^[0-9]")
# Exit the loop if ping is no longer dropping packets
if [ "$PacketLoss" == 0 ]; then
echo "Connection restored"
break
else
echo "No connectivity"
fi
done
对于创建类似“goto”的东西,我的想法是使用带大小写的select并赋值一个变量,然后在if语句中检查该变量。不完美,但在某些情况下可能有帮助
例子:
#!/usr/bin/env bash
select goto in Ubuntu Debian Quit ; do
case $goto in
Ubuntu) { CHOICE="Ubuntu" ; break ; } ;;
Debian) { CHOICE="Debian" ; break ; } ;;
Quit) { echo "Bye" ; exit ; } ;;
*) { echo "Invalid selection, please try again..." ; } ;;
esac
done
if [ "$CHOICE" == "Ubuntu" ]; then
echo "I'm in Ubuntu"
fi
if [ "$CHOICE" == "Debian" ]; then
echo "I'm in Debian"
fi