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

Mar*_*ert 29 bash shell

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

#!/bin/sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$last $1 $2 ...
Run Code Online (Sandbox Code Playgroud)

如何才能做到这一点?

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

lar*_*sks 46

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

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

outputfile=$1
shift
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$outputfile "$@"
Run Code Online (Sandbox Code Playgroud)

你打电话给你的脚本是这样的:

myscript out.pdf foo.ps bar.ps "another file.ps"
Run Code Online (Sandbox Code Playgroud)

这将扩展到:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=out.pdf foo.ps bar.ps "another file.ps"
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请阅读手册页的"特殊参数"部分bash.

  • Marius Hofert:您不能轻易地移开最后一个元素,所以有些棘手。这样的东西:`outputfile = $ {@:-1}; args =(“ $ {@:1:$(($ {#@}-1))}”)`)。您应该接受这个幼虫的回答。 (3认同)

Ide*_*lic 19

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

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

exec gs ... -sOUTPUTFILE=$outputfile "${ARGS[@]}"
Run Code Online (Sandbox Code Playgroud)

4版本之前,bash不允许负标在阵列(和生产马吕斯在评论报告错误),所以如果你使用3.x的,你需要使用更恶心

outputfile=${ARGS[${#ARGS[@]}-1]}
Run Code Online (Sandbox Code Playgroud)

这也适用于bash 4.x.


Ran*_*tem 8

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

echo "${@: $#}"
Run Code Online (Sandbox Code Playgroud)

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

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

$ ./script "what    does" "this  script" "do" "?"
this  script do ?
Run Code Online (Sandbox Code Playgroud)