我正在编写 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}"
(并且双引号是强制性的)。