运行bash与破折号

时间:2018-09-24 13:55:56

标签: bash shell dash-shell

以bash和dash运行程序时得到不同的输出

#!/bin/sh

echo $SHELL
n=1
a=$((++n))
echo $n

重击:

$ bash shell_test.sh
2

破折号:

$ dash shell_test.sh
1

2 个答案:

答案 0 :(得分:6)

dash Debian Almquist shell ,是/bin/sh的完全符合POSIX的shell实现的极轻量级版本,旨在尽可能地小创建更快的启动时间。

$((n++))$((--n))等类似的运算符是POSIX不需要的功能,因此未实现。

要查看破折号如何解释这些语句,请参见Chepner's answer

here是一个很好的页面,解释了如何使您的脚本符合POSIX。


  

2.6.4算术扩展:算术扩展提供了一种评估算术表达式并替换其值的机制。算术扩展的格式应如下:

$((expression))
     

除了不对表达式内的双引号进行特殊处理外,应将其视为双引号。外壳程序将扩展表达式中的所有标记,以进行参数扩展,命令替换和引用删除。

     

接下来,外壳程序应将此视为算术表达式并替换该表达式的值。算术表达式应按照Arithmetic Precision and Operations中给出的规则进行处理,但有以下例外:

     
      
  • 仅需要带符号的长整数算法。
  •   
  • 仅需要将ISO C标准第6.4.4.1节中指定的十进制常数,八进制常数和十六进制常数视为常量。
  •   
  • 不需要sizeof()运算符以及前缀和后缀++--运算符。
  •   
  • 不支持选择,迭代和跳转语句。
  •   
     

来源:POSIX IEEE Std 1003.1-2017

答案 1 :(得分:5)

POSIX不需要前缀++,而dash并没有实现它。而是将其解析为两个一元+运算符:

$ n=1
$ echo $((+(+n)))
1
$ echo $((++n))
1
$ echo $n
1