对 Ghostscript 选项/标志使用变量会导致错误

对 Ghostscript 选项/标志使用变量会导致错误

我正在编写 PDF 文件的创建/操作脚本,因此我使用gs(Ghostscript)。我遇到的问题是,如果我使用变量作为选项,gs则会出错。

我正在使用的有效命令是:

gs -sDEVICE=pdfwrite -dCompatabilityLevel=1.4 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile="${ofile}" "${tfile}"

为了使事情更容易(至少对我来说)根据需要查看和编辑,我将这些选项分配给一个变量

local gsOPTS="-sDEVICE=pdfwrite -dCompatabilityLevel=1.4 -dPDFSETTINGS=/printer"
local gsFLAGS="-dNOPAUSE -dQUIET -dBATCH" 

gs "${gsOPTS}" "${gsFLAGS}" -sOutputFile="${ofile}" "${tfile}"

当我这样做时,gs会出现错误Unknown device: pdfwrite -dCompatabilityLevel=1.4 -dPDFSETTINGS=/printer

我尝试过将变量括在引号中,但不加引号;不用找了。当我不使用变量时,它工作得很好。我一直使用这种技术(即使用 FFMPEG),没有任何问题。是否有特定的原因gs导致此问题?

我运行的是 macOS 10.15.6、Zsh 版本 5.7.1 和gs版本 9.52。

答案1

"${gsOPTS}"将 的值gsOPTS作为单个参数传递。但gsOPTS不包含单个参数:它包含一个参数列表,并用空格连接。

${gsOPTS}也好不到哪儿去。在 sh 和 bash 等 shell 中,它恰好适用于您的情况,因为该值将在空格处分割,并且没有其他重要的特殊字符。但 zsh${gsOPTS}不会经历这样的分裂。

由于gsOPTS包含参数列表而不是单个参数,因此它应该是字符串列表,而不是字符串。这在 zsh 中很容易做到:列表称为数组,字符串数组很容易操纵。

local gsOPTS=(-sDEVICE=pdfwrite -dCompatabilityLevel=1.4 -dPDFSETTINGS=/printer)
local gsFLAGS=(-dNOPAUSE -dQUIET -dBATCH)

gs ${gsOPTS} ${gsFLAGS} -sOutputFile="${ofile}" "${tfile}"

从技术上讲${gsOPTS}(或${gsOPTS}等效的)并不意味着“拼接数组的元素”,而是“拼接数组的非空元素”。这在这里可能并不重要,但要保留空元素,您需要

gs "${(@)gsOPTS}" "${(@)gsFLAGS}" -sOutputFile="${ofile}" "${tfile}"

或者

gs "${gsOPTS[@]}" "${gsFLAGS[@]}" -sOutputFile="${ofile}" "${tfile}"

或者

gs "$gsOPTS[@]" "$gsFLAGS[@]" -sOutputFile="${ofile}" "${tfile}"

(并且双引号是强制性的)。

相关内容