Zsh
為 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。
"${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}"
(並且雙引號是強制性的)。