1

I am scripting the creation/manipulation of PDF files so I am using gs (Ghostscript). The problem I am having is that if I use a variable for the the options, gs errors out.

The command that I am using which works is:

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

To make things a little easier (for me at least) to view and edit as needed, I assigned these options to a variable as such

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

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

When I do this, gs errors out with Unknown device: pdfwrite -dCompatabilityLevel=1.4 -dPDFSETTINGS=/printer

I've tried enclosing the variables in quotes and without; no change. When I don't use the variables, it works fine. I use this technique all the time (i.e. with FFMPEG) with no issue. Is there something specific to gs that is causing this problem?

I'm running macOS 10.15.6, Zsh version 5.7.1 and gs version 9.52.

1

1 Answer 1

4

"${gsOPTS}" passes the value of gsOPTS as a single argument. But gsOPTS doesn't contain a single argument: it contains a list of arguments, joined with spaces.

${gsOPTS} isn't any better. In shells such as sh and bash, it would happen to work in your case because the value would be split at whitespace and there are no other special characters that would matter. But zsh, ${gsOPTS} doesn't undergo such splitting.

Since gsOPTS contains a list of arguments and not a single argument, it should be a list of strings, not a string. This is easy to do in zsh: a list is called an array and arrays of strings are easy to manipulate.

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

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

Technically ${gsOPTS} (or ${gsOPTS} which is equivalent) doesn't mean “splice the elements of the array” but “splice the non-empty elements of the array”. This probably doesn't matter here, but to preserve the empty elements, you would need

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

or

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

or

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

(and the double quotes are mandatory).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .