【问题标题】:"For" loop in bash script only run oncebash 脚本中的“for”循环只运行一次
【发布时间】:2013-04-05 08:49:31
【问题描述】:

脚本目标很简单。

我有很多目录,其中包含一些捕获的流量文件。 我想为每个目录运行一个命令。所以我想出了一个脚本。但我不知道为什么脚本只在第一个匹配时运行。

#!/bin/bash
# Collect throughput from a group of directory containing capture files
# Group of directory can be specify by pattern
# Usage: ./collectThroughputList [regex]
#       [regex] is the name pattern of the group of directory

for DIR in $( ls -d $1 ); do
   if test -d "$DIR"; then
       echo Collecting throughputs from directory: "$DIR"
       ( sh collectThroughput.sh $DIR > $DIR.txt )
   fi
done
   echo Done\!

我试试:

for DIR in $1; do

或

for DIR in `ls -d $1`; do

或

for DIR in $( ls -d "$1" ); do

或

for DIR in $( ls -d $1 ); do

但结果是一样的。 for 循环只运行一次。

最后我找到了这个并做了一些技巧让它工作。但是,我想知道为什么我的第一个脚本不起作用。

find *Delay50ms* -type d -exec bash -c "cd '{}' && echo enter '{}' && ../collectThroughput.sh ../'{}' > ../'{}'.txt" \;

"*Delay*" 是我要运行命令的目录模式名称。 感谢您指出问题。

【问题讨论】:

标签: linux bash shell for-loop


【解决方案1】:

问题

您遇到的问题很可能是由于您尝试使用某种模式(例如 *)作为脚本的参数。

用类似的东西运行它:

my_script *

这里发生的是,shell 将在调用您的脚本之前扩展 *。 因此,在您的脚本中执行分词后$1 将仅引用ls 返回的第一个条目。

示例

给定以下目录布局:

 directory_a
 directory_b
 directory_c

调用my_script * 将导致:

my_script directory_a  directory_b directory_c

因此被调用的循环只是在 $(ls -d directory_a) 上进行迭代,实际上只是 directory_a 而已。

解决方案

要使用$1=* 运行程序,您必须在调用脚本之前转义*。

尝试运行:

my_script \*

要看到它有效地完成了它打算做的事情。这样,您的脚本中的$1 将包含* 而不是directory_a,这很可能是您希望脚本工作的方式。

【讨论】:

  • 感谢您指出问题。但是,我不喜欢这个解决方案,因为我们必须对脚本的使用做一些技巧。它稍后会给关注该项目的人带来问题。
【解决方案2】:

既然要查找$1下的所有子目录,可以这样使用:

for DIR in $(find $1 -type d)

【讨论】:

  • 为什么这会得到支持? 1.这不等于OP的方法(它递归搜索)2.Thou shalt not do this either。 3. 未引用$1.
  • 我撤回了 1。(抱歉,看的不够仔细),但 2 和 3 仍然站立。
【解决方案3】:

正如 mikyra 所指出的,在将参数 * 传递给脚本之前,shell 会将您的参数 * 扩展到您目录中的所有条目。

如果您希望对通配符进行 shell 扩展(例如,* 匹配除隐藏文件之外的所有文件),您可以简单地将扩展留给 shell 并使用结果,通过迭代所有参数,而不仅仅是第一个参数:

for DIR in $@; do
   # ...
done

如果你想自己进行扩展(例如,因为模式应该只应用于预过滤列表或不同目录中的文件,或者因为你想要正则表达式扩展而不是 shell globbing),你必须使用反斜杠表示法(如 mikyra 的 \*)或使用引号(通常更易于使用)来保护参数不被 shell 扩展:

my_script "*"

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2014-12-07
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多