2010-08-12 27 views
1

我有一个bash函数(略微简化的解释)如何编写一个对传递参数动态的bash脚本函数?

copy_to() { 
    cp $1 $2 $3 
} 

这工作得很好:

copy_to -f /demo/example1.xml new_demo/ 

但是比方说,我想复制所有的XML文件,下面的代码会有问题:

copy_to -f /demo/*.xml new_demo/ 

很显然,我可以只写cp -f /demo/*.xml new_demo/,但反正是有得到copy_to功能的文件列表的工作(这传递的不仅仅是3个参数)以及单个文件?

+0

$ @是吗?也许... – jtbandes 2010-08-12 07:09:20

回答

5

[email protected]$*其中包含所有参数的列表。你应该使用[email protected],因为它在双引号内工作。否则,包含空格的文件名会破坏您的代码。

copy_to() { 
    cp "[email protected]" 
} 

如果参数之一是特殊的,你可以使用shift命令从参数列表中删除它,就像这样:

example() { 
    destination="$1" 
    shift 
    echo "copying [email protected] to $destination" 
} 

shift从列表中移除的第一个参数,因此您必须先将其保存在其他位置。拨打shift后,$1的内容将为$2,$2将包含的内容为$3等等。 [email protected]扩展为所有参数(不包括那些被shift删除的参数)。

请注意,您不能从参数列表的仅从一开始就移除参数。

+0

当然,你可以抓住最后一个元素,然后取消它,这基本上和结束时一样。 – Cascabel 2010-08-12 12:54:33

+0

虽然这样做比较复杂。你会怎么做?是否还有POSIX兼容的方式来做到这一点? (是的,我知道这个问题说的是“bash”,但大多数人不知道它们的区别,只写一个shell是不好的。) – scy 2010-08-12 13:12:35

+0

在Bash中,除了最后一个参数外,你可以像这样访问所有的参数:'$ {@:0:$(($ {#@} - 1))}'(减去2以省略最后两个等)。仅为单一shell编写并不总是很糟糕 - 为什么其他shell如果你要使用的是POSIX(或原始的Bourne)子集? – 2010-08-12 15:13:29

2

由于Scytale表示$ @和$ *包含所有参数的列表。 $#包含参数计数。

您可以考虑使用getopts command进行参数解析。

问候

+0

@Jefromi我编辑$ 0到$ @。 – dlamblin 2015-03-22 19:59:08

+0

谢谢@Jefromi – sourcerebels 2015-03-23 08:40:47