我试图编写一个允许用户使用通配符传递目录路径的bash脚本。
例如,
bash show_files.sh *
在此目录中执行
drw-r--r-- 2 root root 4.0K Sep 18 11:33 dir_a
-rw-r--r-- 1 root root 223 Sep 18 11:33 file_b.txt
-rw-rw-r-- 1 root root 106 Oct 18 15:48 file_c.sql
会输出:
dir_a
file_b.txt
file_c.sql
现在的方式,它输出:
dir_a
show_files.sh
的内容:
#!/bin/bash
dirs="$1"
for dir in $dirs
do
echo $dir
done
答案 0 :(得分:46)
父shell(调用bash show_files.sh *
的父shell)会为您展开*
。
在您的脚本中,您需要使用:
for dir in "$@"
do
echo "$dir"
done
双引号可确保正确处理文件名中的多个空格等。
另见How to iterate over arguments in a shell script。bash
如果你确实想要让脚本扩展*
,你必须确保将*
传递给脚本(用引号括起来,就像在其他答案中一样) ),然后确保它在处理中的正确点扩展(这不是微不足道的)。那时,我会使用一个数组。
names=( $@ )
for file in "${names[@]}"
do
echo "$file"
done
我没有经常在没有双引号的情况下使用$@
,但这是一次或多或少是正确的事情。棘手的部分是它不能很好地处理带空格的外卡。
考虑:
$ > "double space.c"
$ > "double space.h"
$ echo double\ \ space.?
double space.c double space.h
$
工作正常。但是试着把它作为一张外卡传递到脚本中......好吧,我们只是说它在那时变得棘手。
如果您想单独提取$2
,则可以使用:
names=( $1 )
for file in "${names[@]}"
do
echo "$file"
done
# ... use $2 ...
答案 1 :(得分:9)
引用外卡:
bash show_files.sh '*'
或让你的脚本接受一个参数列表,而不只是一个:
for dir in "$@"
do
echo "$dir"
done
最好直接在"$@'
上进行迭代,而不是将其分配给另一个变量,以保持其保存自身包含空格的元素的特殊能力。