“for”循环在bash脚本中只运行一次

时间:2013-04-05 08:49:32

标签: linux bash shell for-loop

脚本目标很简单。

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

#!/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" \;

" *延迟*"是我想要运行命令的目录模式名称。 谢谢你指出了问题。

3 个答案:

答案 0 :(得分:4)

由于您要查找$ 1以下的所有子目录,请按以下方式使用:

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

答案 1 :(得分:2)

问题

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

运行类似:

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}}会在您的脚本中包含$1而不是*,这很可能是您希望脚本运行的方式。

答案 2 :(得分:1)

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

如果你想要通配符的shell扩展(例如*匹配除隐藏文件以外的所有文件),你可以简单地将扩展留给shell并使用结果,通过遍历所有参数,而不仅仅是第一个:

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

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

my_script "*"