如何将通配符参数传递给bash文件

时间:2013-10-18 20:02:06

标签: linux bash parameters wildcard

我试图编写一个允许用户使用通配符传递目录路径的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

2 个答案:

答案 0 :(得分:46)

父shell(调用bash show_files.sh *的父shell)会为您展开*

在您的脚本中,您需要使用:

for dir in "$@"
do
    echo "$dir"
done

双引号可确保正确处理文件名中的多个空格等。

另见How to iterate over arguments in a bash shell script


潜在混淆的附录

如果你确实想要让脚本扩展*,你必须确保将*传递给脚本(用引号括起来,就像在其他答案中一样) ),然后确保它在处理中的正确点扩展(这不是微不足道的)。那时,我会使用一个数组。

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

最好直接在"$@'上进行迭代,而不是将其分配给另一个变量,以保持其保存自身包含空格的元素的特殊能力。