40

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

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

如何才能做到这一点?

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

4

3 回答 3

66

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获取更多信息。

于 2012-04-24T23:17:41.827 回答
21

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

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,则需要使用更丑陋的

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

这也适用于 bash 4.x。

于 2012-04-25T01:51:34.560 回答
9

要访问最后一个参数,除了上面 Idelic 的答案之外,您还可以执行以下操作:

echo "${@: $#}"

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

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

$ ./script "what    does" "this  script" "do" "?"
this  script do ?
于 2016-05-21T17:37:39.670 回答