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

Linux 如何将通配符参数传递给bash文件,linux,bash,parameters,wildcard,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 fi

我正在尝试编写一个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
显示文件的内容。sh

#!/bin/bash

dirs="$1"

for dir in $dirs
do
    echo $dir
done

父shell调用
bash show_files.sh*
,为您展开
*

在脚本中,您需要使用:

for dir in "$@"
do
    echo "$dir"
done
双引号确保正确处理文件名中的多个空格等

另见


可能令人困惑的附录 如果确实想让脚本展开
*
,则必须确保将
*
传递给脚本(与其他答案一样,用引号括起来),然后确保在处理过程中的正确点展开脚本(这不是小事)。在这一点上,我将使用数组

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 ...
引用通配符:

bash show_files.sh '*'
或者让脚本接受参数列表,而不仅仅是一个:

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

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

太好了!第二个选择是完美的。是否有一种方法可以允许多个参数。例如,
bash show_files.sh*second_参数
。这个应用程序实际上并不需要它。只是好奇,有点。您的脚本将收到数量可变的参数,您称之为“second_param”的参数实际上是最后一个参数
show_files.sh
从不查看
*
,只查看shell扩展到的文件列表。虽然
bash
有一些扩展使最后一个参数更容易获取,但是获取最后一个参数有点棘手
${@:-1}
(需要空格)将为您提供最后一个参数
${@:0:$#}
似乎只提供了最后一个,但使用偏移量0和
$@
(这是一个基于1的数组)似乎有点可疑,并且该表达式可能有缺陷。对我来说,第一个选项是完美的。我需要将一个参数传递给另一个单独处理通配符的脚本。太棒了!是否有一种方法可以允许多个参数。例如,
bash show_files.sh*second_参数
。这个应用程序实际上并不需要它。只是好奇。@eisaacson如果第二个参数排在第一位,你可以做
sparam=$1;转移
然后使用
$@
@jordanm您在这里的评论是一个很好的解决方案。谢谢,对不起;这不是我的本意。传递外卡不是一个好主意,部分原因是它让一切都变得非常混乱。让shell自然地处理它。在您的设计中,首先传递'second'参数,并保留'list of files/directory'作为其余参数。这是Unix的自然设计。如果可能的话,我建议你用它。如果唯一的目的是要扩展globs,那么您可能需要首先清除IFS,这样我们就不会进行字符串拆分,但是
names=($@)
在这种情况下是有意义的。引用通配符是可以的,但是您的脚本和下面的脚本的主要区别是$@而不是$1