Bash 中断循环的函数
Bash function that breaks loop
我制作了一个 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
}
}
每当我需要优雅地结束其他 bash
函数中的 loop
时,我只是调用击键。我不能再这样做了,因为 bash
v4.4.0 说:
-bash: break: only meaningful in a `for', `while', or `until' loop
我怎样才能解决这个问题而不一遍又一遍地复制相同的代码超过 10 倍?
对于你应该使用的函数 return
:
keystroke() {
...
return
}
可选择添加一个整数(0 到 127 之间)作为 return 值,例如:
keystroke() {
...
return 1
}
注意,否则最后一个命令的退出状态将被用作return值。
确实,从 Bash 4.4 开始,break
关键字不再允许在 for
、while
或 until
循环之外使用。
我用 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. Fixed a bug that could allow break' or
continue' executed from shell
functions to affect loops running outside of the function.
所以现在您不能再在函数中使用 break
关键字来中断父循环。解决方案是 return 状态代码,并在父循环中检查该代码:
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. In POSIX mode, break' and
continue' do not complain and return success
if called when the shell is not executing a loop.
因此,如果启用 POSIX-模式,您似乎可以保留旧行为。
$ shenv shell bash-4.4
$ bash --posix -c 'b() { break; }; for i in 1; do echo $i; b; done'
1
我制作了一个 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
}
}
每当我需要优雅地结束其他 bash
函数中的 loop
时,我只是调用击键。我不能再这样做了,因为 bash
v4.4.0 说:
-bash: break: only meaningful in a `for', `while', or `until' loop
我怎样才能解决这个问题而不一遍又一遍地复制相同的代码超过 10 倍?
对于你应该使用的函数 return
:
keystroke() {
...
return
}
可选择添加一个整数(0 到 127 之间)作为 return 值,例如:
keystroke() {
...
return 1
}
注意,否则最后一个命令的退出状态将被用作return值。
确实,从 Bash 4.4 开始,break
关键字不再允许在 for
、while
或 until
循环之外使用。
我用 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. Fixed a bug that could allow
break' or
continue' executed from shell functions to affect loops running outside of the function.
所以现在您不能再在函数中使用 break
关键字来中断父循环。解决方案是 return 状态代码,并在父循环中检查该代码:
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. In POSIX mode,
break' and
continue' do not complain and return success if called when the shell is not executing a loop.
因此,如果启用 POSIX-模式,您似乎可以保留旧行为。
$ shenv shell bash-4.4
$ bash --posix -c 'b() { break; }; for i in 1; do echo $i; b; done'
1