shell 脚本中的 for 循环语法

shell 脚本中的 for 循环语法

我运行以下脚本:

for (( i=1; i <= 5; i++ ))    
do
    echo "Random number $i: $RANDOM"
done

我收到以下错误:

Syntax error: Bad for loop variable

为什么这个语法不起作用?

答案1

正如 heemayl 的回答所指出的那样,您的构造是一种 bashism。执行您想要的操作的标准方式是:

for i in 1 2 3 4 5
do
  echo "Random number $i: $RANDOM"
done

或者,更容易扩展:

for i in $(seq 1 5)
do
  echo "Random number $i: $RANDOM"
done

man seq更多详情请参阅)。

答案2

您的原始脚本(( i=1; i <= 5; i++ ))for循环中构造一个,这是一个 bashism,因此无法被理解dash

在 Ubuntu 中sh是 的符号链接dash,因此当您运行

sh ./script.sh

你基本上是在跑步

dash ./script.sh

正如我之前提到的,dash不理解类似 C 的for循环结构,它显示了错误。

要使用 运行脚本bash,您可以:

  • 将其作为参数运行(例如,bashbash script.sh不需要使脚本可执行)

  • 使脚本可执行并从bashshell 运行(从包含脚本的目录):

    ./script.sh 
    
  • 最可移植的方法是使用 shebang(#!/bin/bash或最好#!/usr/bin/env bash)作为脚本的第一行。这样,您可以通过从任何 shell 运行脚本./script.sh,该脚本将被解释为bash脚本,因此将相应地执行。

答案3

我想我应该为讨论做出一点贡献。

已经提到过,脚本中使用的语法是 bashism,因此不可移植,尽管这是 C 类的,并且熟悉 java 和 C 的人都能很好地理解。从问我自己的问题在 unix.stackexchange.com 上,我还了解到诸如先生for i in $(seq 1 5)成一组数字然后进行迭代之类的语法,如果您有一组非常大的数字,这可能会造成浪费。

模拟可移植的类 C 行为的更好方法是使用while循环,并使用可以递增的变量。例如,

#!/bin/sh
number=0
while [ "$number" -lt 10 ]
do
        printf "\t%d" "$number"
        number=`expr $number + 1 `
done

这适用于 bash、dash、zsh、ksh、mksh ......或基本上任何与 Bourne Shell 相关的 Shell。事实上,我有一本 1995 年出版的 Unix System V 书,我已经测试了它们的 Bourne Shell 示例,它仍然有效。其行为也类似于 C 语言的 for 循环:您有初始条件、内部测试条件while [ . . .]和末尾的更新条件。

csh 和 tcsh语法更接近 C 语言,但它不能移植到其他 shell,而且它们不建议用于脚本编写。

添加

关于$RANDOM的可移植性,根据这一页在 ubuntu wiki 上,使用 dash 随机数生成应该依赖于使用/dev/urandom

相关内容