Bash脚本:扩展参数不使用$ @或$ *

使用$@你可以在bash文件列表中做些事情。 例:

script.sh:

 #!/bin/bash list=$@ for file in $list; do _commands_; done 

然后我可以用这个程序来调用

 ~/path/to/./script dir1/{subdir1/*.dat,subdir2/*} 

这个参数将扩展为一些variables$list的参数。 但现在我想要其他的参数,比如说$ 1,$ 2,这个列表是$ 3。 所以我想扩展dir1/{subdir1/*.dat,subdir2/*}在脚本内部发生,而不是成为许多参数。 在命令行上,你可以这样做:

 find dir1/{subdir1/*.dat,subdir2/*} 

并获得所需的输出,即列表如果文件。 所以我尝试了这样的事情:

 arg1=$1 arg2=$2 list=$(find $3) for file in $list; do _commands_; done ... 

电话:

 ~/path/to/./script arg_1 arg_2 'dir1/{subdir1/*.dat,subdir2/*}' 

但没有成功。 一些帮助如何使这个列表展开成一个variables内的脚本将不胜感激!:)

编辑:所以下面的答案给了使用这些命令的解决scheme:

 arg1="$1" arg2="$2" shift 2 for f in "$@"; do echo "processing $f"; done; 

但出于好奇,是否仍然可以在脚本内部将stringdir1/{subdir1/*.dat,subdir2/*}传递给find命令(或者以相同的结尾为准),而不使用$@那个名单呢? 这可能是有用的,例如,如果最好将列表作为第一个或最后一个参数,或者在某些其他情况下,即使它需要转义字符或引用参数。

您可以在脚本中使用此代码:

 arg1="$1" arg2="$2" shift 2 for f in "$@"; do echo "processing $f"; done; 

然后将其称为:

 ~/path/to/script arg_1 arg_2 dir1/{subdir1/*.dat,subdir2/*} 

使用shift 2将移动位置参数2个位置,从而使得$3$1$4$2等。然后可以直接调用$@来迭代其余的参数。

根据help shift

 shift: shift [n] Shift positional parameters. Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is 

在你的脚本被调用之前,shell的扩展是由shell执行的。 这意味着你将不得不引用/转义参数。 在脚本中,您可以使用eval来执行扩展。

 #!/bin/bash arg1="$1" ; shift arg2="$2" ; shift eval "list=($@)" for q in "${list[@]}" ; do echo "$q" ; done 

 $ ./a 123 456 'a{b,c}' 'd*' ab ac d.pl docs 

在您的示例中,我没有看到在脚本中进行扩展的意义。

 #!/bin/bash arg1="$1" ; shift arg2="$2" ; shift list=("$@") for q in "${list[@]}" ; do echo "$q" ; done 

要不就

 #!/bin/bash arg1="$1" ; shift arg2="$2" ; shift for q in "$@" ; do echo "$q" ; done 

 $ ./a 123 456 a{b,c} d* ab ac d.pl docs