1

脚本目标很简单。

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

#!/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*”是我要运行命令的目录模式名称。感谢您指出问题。

4

3 回答 3

4

由于您想查找 $1 下的所有子目录,请像这样使用它:

for DIR in $(find $1 -type d)
于 2013-04-05T08:58:16.847 回答
3

问题

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

用类似的东西运行它:

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

于 2013-04-05T09:05:00.687 回答
1

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

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

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

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

my_script "*"
于 2013-04-05T09:36:45.900 回答