我运行以下脚本:
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
,您可以:
将其作为参数运行(例如,
bash
您bash script.sh
不需要使脚本可执行)使脚本可执行并从
bash
shell 运行(从包含脚本的目录):./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