关于linux:bash脚本 – 无法获得循环工作

bash script - can't get for loop working

背景信息:

我正试图遵循这里发布的示例:http://www.cyberciti.biz/faq/bash-for-loop/我想使用一个名为"i"的控制变量循环9次。

问题描述

我的代码如下:

1
2
3
4
5
6
for i in {0..8..1}
do
  echo"i is $i"
  tmpdate=$(date -d"$i days""+%b %d")
  echo $tmpdate
done

运行此代码时,调试打印显示:

1
                "i is {0..8..1}"

而不是介于0和8之间的值。

到目前为止我检查过的:

我试图检查我的bash版本,以确保它支持这种类型的语法。我正在运行版本4、2、25(1)

我还尝试使用类似C的语法,在这里您可以使用(i=0;i<=8;i++),但这也不起作用。

任何建议都将不胜感激。

谢谢。

编辑1

我还尝试了以下代码:

1
2
3
4
5
6
for i in {0..8};
do
  echo"i is $i"
  tmpdate=$(date -d"$i days""+%b %d")
  echo $tmpdate
done

还有…

1
2
3
4
5
6
for i in {0..8}
do
  echo"i is $i"
  tmpdate=$(date -d"$i days""+%b %d")
  echo $tmpdate
done

他们都以同样的结果失败了。

我也尝试过:

1
2
3
4
5
6
7
8
#!/bin/bash

for ((i=0;i<9;i++));
do
  echo"i is $i"
  tmpdate=$(date -d"$i days""+%b %d")
  echo $tmpdate
done

这给了我一个错误:

test.sh:4:test.sh:语法错误:循环变量错误

FYI。我在Ubuntu 12上跑步

编辑2

好啊。。。所以我认为韦伯里克向我透露了这个问题…为了执行脚本,我运行了"sh test.sh"在代码中,我将它定义为bash脚本!我的错!

但事情是这样的。最后,我需要它同时在bash和sh中工作。所以现在我要小心确保以正确的方式调用脚本…我注意到以下结果:

  • 当定义为bash脚本并使用bash执行时,C样式的版本可以工作!
  • 当定义为sh脚本并使用sh执行时,C样式版本失败

    me@devbox:~/tmp/test$sh测试.shtest.sh:5:test.sh:语法错误:循环变量错误

  • 当定义为sh脚本并使用sh(非c样式版本)执行时(也就是在n..x中的i),我得到"i is 0..8"输出。

  • 附言:"如果你在下一行做了什么,就没什么区别了……仅供参考。"


    Ubuntu的默认shell是dash,它不能识别您尝试的bashims(brace expansion,c-style for loop)。尝试使用bash显式运行脚本:

    1
    bash myscript.sh

    或者将shebang设置为#!/bin/bash。确保不要使用sh myscript.sh运行脚本。

    如果使用seq,dash应该可以工作:

    1
    2
    3
    for i in $(seq 0 1 8); do
        echo"$i"
    done

    只有{0..8}bash中工作,默认增量为1。如果要在bash中使用C样式的for循环:

    1
    2
    3
    for ((i=0;i<9;i++)); do
        echo"$i"
    done


    我相信

    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/bash

    for ((i=0;i<9;i++))
    do
      echo"i is $i"
      tmpdate=$(date -d"$i days""+%b %d")
      echo $tmpdate
    done

    在Ubuntu 12.04上工作

    如果仍有错误,请尝试运行

    1
    chmod +x test.sh

    然后

    1
    ./test.sh

    结果是

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    i is 0
    Apr 04
    i is 1
    Apr 05
    i is 2
    Apr 06
    i is 3
    Apr 07
    i is 4
    Apr 08
    i is 5
    Apr 09
    i is 6
    Apr 10
    i is 7
    Apr 11
    i is 8
    Apr 12


    我不是巴什的专家,但根据TDLP,你需要一个;在声明之后。有很多方法可以到达一个范围。这是其中之一。

    1
    2
    3
    4
        #!/bin/bash
        for i in `seq 1 8`; do
            echo $i
        done


    你引用的网站说

    Bash v4.0+ has inbuilt support for setting up a step value using {START..END..INCREMENT} syntax:

    因此,当bash版本大于4.0时,您可以使用{0..8..1},我想不是这样(在您的终端中尝试bash --version)。您也可以使用{0..8},而不是{0..8..1}

    如果您有一个旧版本,那么可以在for循环中使用命令$(seq START INCREMENT END),而不是{START..END..INCREMENT}