打破循环的Bash函数

时间:2017-01-08 12:14:35

标签: linux bash function loops break

我制作了bash function,看起来像这样:

keystroke()
{
    read -s -n1 -t0.1 key     #Read a single keystroke for 0.1 seconds
    [ "$key" = $'\e' ] &&     #If the pressed key is escape
    {
        echo Aborted by user  #Display message
        break                 #Break parent loop
    }
}

每当我需要在其他loop函数中优雅地结束bash时,我只需要调用按键。我不再能够这样做,因为bash v4.4.0说:

-bash: break: only meaningful in a `for', `while', or `until' loop

如果不反复复制相同的代码超过10倍,我该如何解决这个问题呢?

2 个答案:

答案 0 :(得分:1)

对于函数,您应该使用agenda.schedule('2017-01-07 7:27', 'beerRun', []);

return

可选择添加一个整数(介于0和127之间)作为返回值,例如:

keystroke() {
    ...
    return
}

请注意,否则最后一个命令的退出状态将用作返回值。

答案 1 :(得分:0)

实际上,从Bash 4.4开始,break关键字在forwhileuntil循环之外不再被允许。

我使用shenv和以下代码段对此进行了验证。使用Bash 4.3.30:

$ shenv shell bash-4.3.30
$ bash -c 'b() { break; }; for i in 1; do echo $i; b; done'
1

使用Bash 4.4:

$ shenv shell bash-4.4
$ bash -c 'b() { break; }; for i in 1; do echo $i; b; done'
1
environment: line 0: break: only meaningful in a `for', `while', or `until' loop

更改日志中的行:https://github.com/samuelcolvin/bash/blob/a0c0a00fc419b7bc08202a79134fcd5bc0427071/CHANGES#L677

  

xx。修复了可能允许从外壳执行break' or继续'的错误   函数影响在函数外部运行的循环。

因此,现在您不能再在函数中使用break关键字来中断父循环。解决方案是返回状态代码,然后在父循环中检查该代码:

keystroke()
{
    read -s -n1 -t0.1 key
    [ "$key" = $'\e' ] &&
    {
        echo Aborted by user
        return 1
    }
}

while true; do
    ...
    keystroke || break
    ...
done

但是,我们可以在变更日志中看到另一个有趣的信息: https://github.com/samuelcolvin/bash/blob/a0c0a00fc419b7bc08202a79134fcd5bc0427071/CHANGES#L5954

  

i。在POSIX模式下,break' and continue'不会抱怨并返回成功   如果在外壳不执行循环时调用。

因此,如果启用POSIX模式,似乎可以保留旧的行为。

$ shenv shell bash-4.4
$ bash --posix -c 'b() { break; }; for i in 1; do echo $i; b; done'
1