为什么我的Linux bash中的这个简单的FOR LOOP不起作用?

时间:2022-12-01 16:50:31

I'm trying to do a simple for loop in a UNIX script (bash).

我正在尝试在UNIX脚本(bash)中进行简单的for循环。

Here's my script:

这是我的脚本:

for i in {1..3}
do
   echo "Welcome $i times"
done

I was expecting this for output ...

我期待这个输出......

Welcome 1 times
Welcome 2 times
Welcome 3 times

... but I get this ...

......但是我明白了......

Welcome {1..3} times

What am I doing wrong?

我究竟做错了什么?

3 个解决方案

#1


11  

You didn't mention how you were executing your script and that can make a difference. Suppose we have a script:

你没有提到你是如何执行你的脚本的,这可能会有所作为。假设我们有一个脚本:

$ cat welcome.sh
for i in {1..3}
do
   echo "Welcome $i times"
done

Observe the following three invocations of welcome.sh from a bash shell:

从bash shell中观察以下三个welcome.sh调用:

$ ps -p $$
  PID TTY          TIME CMD
11509 pts/25   00:00:00 bash
$ source welcome.sh
Welcome 1 times
Welcome 2 times
Welcome 3 times
$ bash welcome.sh
Welcome 1 times
Welcome 2 times
Welcome 3 times
$ sh welcome.sh
Welcome {1..3} times

The last one fails because, on my system, sh defaults to dash, not bash. This is true, for example, for any modern Debian/Ubuntu-derived system.

最后一个失败,因为在我的系统上,sh默认为破折号,而不是bash。例如,对于任何现代的Debian / Ubuntu派生系统都是如此。

#2


2  

Several things to try:

有几件事要尝试:

  • Run your script with bash as a prefix. bash myscript.sh instead of simply myscript.sh. This will guarantee you're running under BASH.
  • 使用bash作为前缀运行脚本。 bash myscript.sh而不仅仅是myscript.sh。这将保证您在BASH下运行。

  • Run set -o and see if braceexpansion is set to on. If not, run set -o braceexpand and see if that fixes your problem.
  • 运行set -o并查看braceexpansion是否设置为on。如果没有,请运行set -o braceexpand并查看是否可以解决您的问题。

You can test for whether braceexpand is on or off with the -o test.

您可以使用-o test测试braceexpand是打开还是关闭。

if [[ -o braceexpand ]]
then
    echo "Brace expand is on"
else
    echo "It is off"
fi

You can use this to test the state of braceexpand, so you can return it to its previous state.

您可以使用它来测试braceexpand的状态,以便您可以将其返回到先前的状态。

#3


1  

Moving my comment to formal answer:

将我的评论转移到正式答案:

set -o braceexpand

That enables {x..y} style (amongst other kinds of) expansion. If you want it permanently, add it to your .bashrc. If you want it temporarily, you can "bracket" your code:

这使得{x..y}样式(以及其他类型)扩展。如果您想永久使用它,请将其添加到.bashrc中。如果您想暂时使用它,可以“包含”您的代码:

set -o braceexpand  # enable brace expansion
echo {1..3}         # or whatever your command is
set +o braceexpand  # disable it

Frankly I think the code overhead of that on/off approach isn't worth it, and I always add brace expansion to my .bashrc.

坦率地说,我认为开/关方法的代码开销不值得,我总是在我的.bashrc中添加大括号扩展。

Finally, here's an excellent discussion of brace expansion ins and outs.

最后,这里是对支撑扩展进出口的一个很好的讨论。

#1


11  

You didn't mention how you were executing your script and that can make a difference. Suppose we have a script:

你没有提到你是如何执行你的脚本的,这可能会有所作为。假设我们有一个脚本:

$ cat welcome.sh
for i in {1..3}
do
   echo "Welcome $i times"
done

Observe the following three invocations of welcome.sh from a bash shell:

从bash shell中观察以下三个welcome.sh调用:

$ ps -p $$
  PID TTY          TIME CMD
11509 pts/25   00:00:00 bash
$ source welcome.sh
Welcome 1 times
Welcome 2 times
Welcome 3 times
$ bash welcome.sh
Welcome 1 times
Welcome 2 times
Welcome 3 times
$ sh welcome.sh
Welcome {1..3} times

The last one fails because, on my system, sh defaults to dash, not bash. This is true, for example, for any modern Debian/Ubuntu-derived system.

最后一个失败,因为在我的系统上,sh默认为破折号,而不是bash。例如,对于任何现代的Debian / Ubuntu派生系统都是如此。

#2


2  

Several things to try:

有几件事要尝试:

  • Run your script with bash as a prefix. bash myscript.sh instead of simply myscript.sh. This will guarantee you're running under BASH.
  • 使用bash作为前缀运行脚本。 bash myscript.sh而不仅仅是myscript.sh。这将保证您在BASH下运行。

  • Run set -o and see if braceexpansion is set to on. If not, run set -o braceexpand and see if that fixes your problem.
  • 运行set -o并查看braceexpansion是否设置为on。如果没有,请运行set -o braceexpand并查看是否可以解决您的问题。

You can test for whether braceexpand is on or off with the -o test.

您可以使用-o test测试braceexpand是打开还是关闭。

if [[ -o braceexpand ]]
then
    echo "Brace expand is on"
else
    echo "It is off"
fi

You can use this to test the state of braceexpand, so you can return it to its previous state.

您可以使用它来测试braceexpand的状态,以便您可以将其返回到先前的状态。

#3


1  

Moving my comment to formal answer:

将我的评论转移到正式答案:

set -o braceexpand

That enables {x..y} style (amongst other kinds of) expansion. If you want it permanently, add it to your .bashrc. If you want it temporarily, you can "bracket" your code:

这使得{x..y}样式(以及其他类型)扩展。如果您想永久使用它,请将其添加到.bashrc中。如果您想暂时使用它,可以“包含”您的代码:

set -o braceexpand  # enable brace expansion
echo {1..3}         # or whatever your command is
set +o braceexpand  # disable it

Frankly I think the code overhead of that on/off approach isn't worth it, and I always add brace expansion to my .bashrc.

坦率地说,我认为开/关方法的代码开销不值得,我总是在我的.bashrc中添加大括号扩展。

Finally, here's an excellent discussion of brace expansion ins and outs.

最后,这里是对支撑扩展进出口的一个很好的讨论。