脚本目标很简单。
我有很多目录,其中包含一些捕获的流量文件。 我想为每个目录运行一个命令。所以我提出了一个脚本。但我不知道为什么脚本只在第一场比赛中运行。
#!/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" \;
" *延迟*"是我想要运行命令的目录模式名称。 谢谢你指出了问题。
答案 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 "*"