bash中是否有“goto”语句?我知道这被认为是不好的做法,但我需要特别“去”。
当前回答
它确实可能对一些调试或演示需求有用。
我发现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
其他回答
还有一种能力可以达到预期的结果:命令陷阱。例如,它可以用于清理目的。
对于创建类似“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
它确实可能对一些调试或演示需求有用。
我发现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
你可以在bash中使用case来模拟goto:
#!/bin/bash
case bar in
foo)
echo foo
;&
bar)
echo bar
;&
*)
echo star
;;
esac
生产:
bar
star
如果你使用它来跳过一个大型脚本的一部分进行调试(参见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线上的注释,但它必须是你能记住的东西,我怀疑这是非常依赖于程序员的。