如何定义具有可变数量参数的shell脚本?

时间:2012-04-24 23:12:15

标签: bash shell

我想通过shell脚本定义对gs(ghostscript)调用的简单缩写。第一个参数给出了应该合并的所有文件,最后一个给出了输出文件的名称。显然,以下内容不起作用(仅用于显示目标):

#!/bin/sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$last $1 $2 ...

如何做到这一点?

通常会通过myscript infile1.pdf infile2.pdf ... outfile.pdfmyscript *.pdf outfile.pdf调用此脚本。

3 个答案:

答案 0 :(得分:39)

bash变量$@$*扩展到命令行参数列表。通常,您需要使用"$@"(即$@用双引号括起来)。如果有人向你的脚本传递一个包含空格的参数,那么这将是正确的。

所以如果你的脚本中有这个:

outputfile=$1
shift
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$outputfile "$@"

你打电话给你的剧本:

myscript out.pdf foo.ps bar.ps "another file.ps"

这将扩展为:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=out.pdf foo.ps bar.ps "another file.ps"

阅读bash手册页的"Special Parameters"部分以获取更多信息。

答案 1 :(得分:19)

要将输出文件作为最后一个参数传递,请使用数组:

ARGS=("$@")
# Get the last argument
outputfile=${ARGS[-1]}
# Drop it from the array
unset ARGS[${#ARGS[@]}-1]

exec gs ... -sOUTPUTFILE=$outputfile "${ARGS[@]}"

在版本4之前,bash不允许在数组中使用负下标(并且在评论中产生了Marius报告的错误),所以如果你使用的是3.x,你需要使用更多的uglier < / p>

outputfile=${ARGS[${#ARGS[@]}-1]}

这也适用于bash 4.x。

答案 2 :(得分:7)

要访问最后一个参数,除了上面的Idelic的答案,你还可以这样做:

echo "${@: $#}"

这将读取所有参数并从最后一个开始打印它们。这样,您还可以访问N个最后一个参数,例如最后三个参数:

echo "${@: $#-2}"

$ ./script "what    does" "this  script" "do" "?"
this  script do ?