while语句中的差异(Bash vs sh)

时间:2018-08-28 10:39:26

标签: linux bash sh

我正在学习shell脚本(比bash shell更加关注sh shell),并且编写了一个简单的脚本来测试 sh shell中的while语句。

但是当我运行它时,出现此错误...

test.sh: 8: test.sh: 10: not found
10

但是,当我使用bash执行脚本时,它运行得没有问题(即使脚本上带有#!/bin/sh)。有人可以解释为什么吗?两个外壳上的while语句是否不同?

一些注意事项:

  1. 通过调试脚本发现了运行脚本的“解决方案”:

    bash -x test.sh
    
  2. 我的用户的权限为rwx,其他所有用户的权限为r

  3. #!/bin/sh更改为/bash,但并没有真正改变(仍然使用sh运行它,我知道这是非常愚蠢的,但是有时有些愚蠢的事情可以工作)。

  4. 代码非常简单明了,它只是一个变量和一个while语句,并带有对该变量的回显,所以我猜没有语法错误(因为它在Bash shell中运行)。

    < / li>
  5. 我正在使用Ubuntu 18.04.1 LTS(x86_64)。

  6. 脚本所在的目录包含在$PATH中。

  7. 尝试过sudo,但是同样的事情,可以在 Bash 上运行,在 sh 上无法运行。

编辑:

#!/bin/sh

var=10
while [ $var -gt 0 ]
do
        echo $var
        var=$[ $var - 1 ]
done

2 个答案:

答案 0 :(得分:3)

要使用bash语法的$[...]的维护者来引用bug-bash discussion

  

它可以追溯到1990年的Posix(1003.2d9,我丢失了其中的论文   复制)。我是在伯克利人(主要是马克)之后实施的   Teitelbaum,将其放入Posix。最终得到了青睐   ksh $((...))扩展的开始,此时每个人都弃用了   旧的$[...]。稍后我将其从手册中删除,但仍然   照常运作。


$[...]是已弃用的语法,仍然在bash中有效,但在dash中无效(根据评论,/bin/sh指向系统上的位置)

dash(符合POSIX)支持$((...))语法:

var=10
while [ "$var" -gt 0 ]; do
   echo "$var"
   var=$((var-1))
done

答案 1 :(得分:-1)

请注意,#!/bin/sh仅在您拥有./test.sh(执行)脚本的许可并用x执行脚本时有效。

此外,bash test.sh意味着您调用了bash,bash读取了test.sh的行,然后在bash的子进程中执行它们,顶部的#!/bin/sh将作为注释而忽略。

因此,您应先执行./test.sh,然后再执行chmod 755 test.sh,以确保您具有执行该命令的权限。

然后,请向我们显示代码...

更新 (请阅读注释)/bin/sh可能只是链接您正在使用的实际shell。调用readlink -f /bin/sh找出它(当前)指向哪个外壳。