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

Posted

技术标签:

【中文标题】为啥我的 Linux bash 中这个简单的 FOR LOOP 不起作用?【英文标题】:why is this simple FOR LOOP in my Linux bash not working?为什么我的 Linux bash 中这个简单的 FOR LOOP 不起作用? 【发布时间】:2014-02-17 15:41:49 【问题描述】:

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

这是我的脚本:

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

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

Welcome 1 times
Welcome 2 times
Welcome 3 times

...但我明白了...

Welcome 1..3 times

我做错了什么?

【问题讨论】:

你没有在 bash 中运行它。 有一个 setopt 可以像这样启用/禁用卷曲扩展:set -o braceexpand @IgnacioVazquez-Abrams 我很确定; 'ps -p $$' 显示了一个名为 'bash' 的进程。 @bishop Thx,我可以在 for 语句之前添加到 shell 脚本中,还是必须在脚本运行之前运行它? 您可以在for之前添加它,或者将它放在您的.bashrc中。让我知道这是否解决了您的问题,如果是,我会正确回答。 【参考方案1】:

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

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

在 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

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

【讨论】:

见 OP 的评论。这似乎不太可能是正确的答案,除非 OP 使用 sh 运行它(如果他从脚本内部运行 ps -p $$ 绝对不是正确的答案) @BroSlow 虽然你可能是对的,但他并没有说他“从脚本内部”运行了ps -p $$,并且有强烈的迹象表明他没有。 这是一个很好的提醒,当bash 作为“sh”调用时,静默进入兼容模式。 @pushpen.paul 如果您想以./welcome.sh 调用shell 脚本,最好在脚本的第一行添加一个shebang 行,例如#!/bin/bash,它指定您希望哪个 shell(或其他程序)执行脚本。如果您想以./welcome.sh 执行,还需要在脚本中设置execute 位:chmod +x ./welcome.sh【参考方案2】:

您的脚本没有遇到任何类型的错误。我遇到了同样的问题,简单的解决方案是您没有授予它执行权限,因此您可以这样做:

chmod +x nameofyourscript.sh

然后像这样运行它

./nameofyourscript.sh

【讨论】:

【参考方案3】:

将我的评论移至正式答案:

set -o braceexpand

这启用了x..y 样式(以及其他类型的)扩展。如果您想要永久使用它,请将其添加到您的.bashrc。如果你暂时需要它,你可以“括号”你的代码:

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

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

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

【讨论】:

【参考方案4】:

尝试几件事:

以 bash 作为前缀运行您的脚本。 bash myscript.sh 而不是简单的 myscript.sh。这将保证您在 BASH 下运行。 运行set -o 并查看braceexpansion 是否设置为on。如果没有,请运行 set -o braceexpand 看看是否能解决您的问题。

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

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

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

【讨论】:

以上是关于为啥我的 Linux bash 中这个简单的 FOR LOOP 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

linux下.bashrc为啥每次打开终端都要source一下才有效,如何才能永远生效?

11.17linux学习第六天

为啥linux 的 source命令在linux的脚本中没有作用 我使用了#!/bin/sh以及#!/bin/bash 都不好用

为啥我的 bash 脚本无法识别 date 命令中的变量?

为啥要声明“此字段是必需的”。在我的网页中保留显示

为啥在从 C# 创建的进程中运行 bash 命令时我的 $PATH 不同?