递增一个变量触发EXIT在bash 4,而不是在bash 3 [英] Incrementing a variable triggers EXIT in bash 4, but not in bash 3

查看:196
本文介绍了递增一个变量触发EXIT在bash 4,而不是在bash 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个(示范)bash脚本:

Consider this (exemplary) bash script:

#!/bin/bash -e
errorExit() {
    echo "" >&2
    echo "ERROR (${var_scriptfilename}):" >&2
    echo "An unhandled error occurred." >&2
    intentionalExit 1
}
intentionalExit () {
    trap - EXIT # Unregister the EXIT trap
    exit $1
}
trap errorExit EXIT # Trap script errors
var_scriptfilename="$(basename "$0")"
# ==== START OF TEST ====
var_counter=0
((var_counter++))
echo "var_counter is $var_counter" >&2
# ===== END OF TEST =====
intentionalExit 0

如果我在Cygwin的bash中运行它产生预期的输出结果:

If I run it in Cygwin's bash it produces the intended output:

var_counter is 1

不过,如果我在我的Debian挤压盒,这是其预定目标运行它,我结束了在退出陷阱:

However, if I run it on my Debian Squeeze box, which is its intended destination, I end up in the EXIT trap:

ERROR (test.increment.sh):
An unhandled error occurred.

......这是为什么?

...Why is that?

如果我删除它可以在两个系统如预期-e选项,但我想保持-e在使用,效果显着。

If I remove the -e option it works as expected on both systems, but I want to keep -e in use, obviously.

在稍微繁琐万能的变体, var_counter = $(($ var_counter + 1)),作品有被-e两个壳设置,但我会preFER使用第一个符号(或类似的东西看的)读取code时,因为它显然是一个增量的操作伸出。

The slightly more cumbersome "universal" variant, var_counter=$(($var_counter+1)), works with -e being set on both shells, but I would prefer to use the first notation (or something similar-looking) since it clearly sticks out as an increment operation when reading the code.

的bash --version 在Cygwin的bash的说:

bash --version on the Cygwin bash says:

GNU bash, version 3.2.51(24)-release (i686-pc-cygwin)
Copyright (C) 2007 Free Software Foundation, Inc.

在Debian的,它是:

On Debian, it is:

GNU bash, Version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.

我好奇,为什么这是这样。有谁知道这种行为的原因是什么?

I am intrigued as to why this is that way. Does anybody know the cause of this behavior?

此外,没有任何人知道的外观类似的方式来增加在bash的变量,我可以用?

Also, does anybody know of a similar-looking way to increment a variable in bash that I could use?

推荐答案

从bash4手册页:

((expression))
    The expression is evaluated according  to  the  rules  described
    below  under ARITHMETIC EVALUATION.  If the value of the expres‐
    sion is non-zero, the return status is 0; otherwise  the  return
    status is 1.  This is exactly equivalent to let "expression".

和还...

-e      Exit  immediately  if a pipeline (which may consist of a
        single simple command),  a subshell command enclosed  in
        parentheses,  or one of the commands executed as part of
        a command list enclosed by  braces  (see  SHELL  GRAMMAR
        above) exits with a non-zero status.

所以发生的是((VAR ++))递增VAR从0到1,然后返回
0,导致总体前pression返回非零,这将触发
errexit

So what is happening is ((var++)) increments var from 0 to 1 and returns 0, causing the overall expression to return non-zero, which triggers errexit.

现在两个不同的bash版本之间的差异
((行为似乎4.0和4.1之间时有发生。在4.0 ((
显然没有引发errexit。看到这个新闻文件的详细信息。
你必须向下滚动到第135行左右。从源头上更新日志
分布似乎证实了这一点。

Now for the difference between the two different bash versions: this change in (( behavior seems to have occurred between 4.0 and 4.1. In 4.0 (( apparently did not trigger errexit. See this NEWS file for the details. You'll have to scroll down to line 135 or so. The Changelog from the source distribution seems to confirm this.

如果你只是想在不使用退出状态加一个变量,
有多种方法可以做到这一点。也许一些人可以给意见
上这是最好的,但一些可能性是:

If you just want a variable incremented without using the exit status, there's multiple ways to do it. Maybe some other people could give advice on which is the best, but some possibilities are:


  • VAR =$((VAR + 1)),便携式POSIX SH

  • ((VAR ++))||真正,迫使语句始终有一个零
    退出状态(仅庆典)

  • var="$((var+1))", the portable POSIX sh method
  • ((var++)) || true, forcing the statement to always have a zero exit status (bash only)

这篇关于递增一个变量触发EXIT在bash 4,而不是在bash 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆