bash 如何定义具有可变数量参数的shell脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10307280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to define a shell script with variable number of arguments?
提问by Marius Hofert
I would like to define a simple abbreviation of a call to gs
(ghostscript) via a shell script. The first argument(s) give all the files that should be merged, the last one gives the name of the output file. Obviously, the following does not work (it's just for showing the goal):
我想定义一个gs
通过 shell 脚本调用(ghostscript)的简单缩写。第一个参数给出应该合并的所有文件,最后一个给出输出文件的名称。显然,以下不起作用(仅用于显示目标):
#!/bin/sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$last ...
How can this be done?
如何才能做到这一点?
One would typically call this script via myscript infile1.pdf infile2.pdf ... outfile.pdf
or myscript *.pdf outfile.pdf
.
人们通常会通过myscript infile1.pdf infile2.pdf ... outfile.pdf
或调用此脚本myscript *.pdf outfile.pdf
。
回答by larsks
The bash variables $@
and $*
expand into the list of command line arguments. Generally, you will want to use "$@"
(that is, $@
surrounded by double quotes). This will do the right thing if someone passes your script an argument containing whitespace.
bash 变量$@
并$*
扩展为命令行参数列表。通常,您会想要使用"$@"
(即$@
用双引号括起来)。如果有人将包含空格的参数传递给您的脚本,这将是正确的。
So if you had this in your script:
所以如果你的脚本中有这个:
outputfile=
shift
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$outputfile "$@"
And you called your script like this:
你这样调用你的脚本:
myscript out.pdf foo.ps bar.ps "another file.ps"
This would expand to:
这将扩展为:
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=out.pdf foo.ps bar.ps "another file.ps"
Read the "Special Parameters"section of the bash
man page for more information.
阅读手册页的“特殊参数”部分以bash
获取更多信息。
回答by Idelic
To pass the output file as the last argument, use an array:
要将输出文件作为最后一个参数传递,请使用数组:
ARGS=("$@")
# Get the last argument
outputfile=${ARGS[-1]}
# Drop it from the array
unset ARGS[${#ARGS[@]}-1]
exec gs ... -sOUTPUTFILE=$outputfile "${ARGS[@]}"
Before version 4, bash
didn't allow negative subscripts in arrays (and produced the error reported by Marius in the comments), so if you're using 3.x you need to use the much uglier
在第 4 版之前bash
,数组中不允许使用负下标(并在评论中产生了 Marius 报告的错误),因此如果您使用的是 3.x,则需要使用更丑陋的
outputfile=${ARGS[${#ARGS[@]}-1]}
This works for bash 4.x as well.
这也适用于 bash 4.x。
回答by Ran Lottem
To access the last argument, in addition to Idelic's answer above, you can also do:
要访问最后一个参数,除了上面的 Idelic 的答案,您还可以执行以下操作:
echo "${@: $#}"
This reads all of the arguments and prints them starting from the last one. This way, you can also access the N last arguments, for example for the last three arguments:
这将读取所有参数并从最后一个开始打印它们。这样,您还可以访问 N 个最后一个参数,例如最后三个参数:
echo "${@: $#-2}"
$ ./script "what does" "this script" "do" "?"
this script do ?