When running a shell script via Cygwin64, I am getting an error (output below). The relevant portion of the script follows. What is interesting is that if I copy and paste the echoed command, it runs without complaint. So, what is it I am failing to do properly?
[worldwidewilly@SAL9000 resources]$ makebook MyBook
Generating dblatex PDF output via a2x
a2x -v -f pdf -L --asciidoc-opts='-a lang=en -v -b docbook -d book' --dblatex-opts='-V -T db2latex' MyBook.asciidoc
Usage: a2x [OPTIONS] SOURCE_FILE
a2x: error: option -d: invalid choice: "book'" (choose from 'article', 'manpage', 'book')
done.
Here is the script logic:
ASCIIDOC_OPTS="--asciidoc-opts='-a lang=en -v -b docbook -d book'"
DBLATEX_OPTS="--dblatex-opts='-V -T db2latex'"
echo "Generating dblatex PDF output via a2x"
cmd="a2x -v -f pdf -L ${ASCIIDOC_OPTS} ${DBLATEX_OPTS} $1.asciidoc"
echo $cmd
$cmd
echo "done."
The script has been saved as UTF-8 with *nix file endings. This is a fresh install of Cygwin64 running on Windows 7.
FWIW - I have something of a workaround. If I add a space after the word book and before the single apostrophe, it gets by the error above. However, then the -T in the DBLATEX_OPTS is flagged as in error.
[worldwidewilly@SAL9000 resources]$ makebook MyBook
Generating dblatex PDF output via a2x
a2x -v -f pdf -L --asciidoc-opts='-a lang=en -v -b docbook -d book ' --dblatex-opts='-V -T db2latex' MyBook.asciidoc
Usage: a2x [OPTIONS] SOURCE_FILE
a2x: error: no such option: -T
done.
And, again, if I copy the echoed command and run it from the command line, it works. This is all very confusing.
Variables are supposed to contain data, and bash treats them as data. This means that shell meta-characters like quotes are also treated as data.
See this article for a complete discussion on the topic.
The short answer is to use arrays instead:
ASCIIDOC_OPTS=( --asciidoc-opts='-a lang=en -v -b docbook -d book' )
DBLATEX_OPTS=( --dblatex-opts='-V -T db2latex' )
cmd=(a2x -v -f pdf -L "${ASCIIDOC_OPTS[@]}" "${DBLATEX_OPTS[@]}" "$1".asciidoc)
# Print command in pastable format:
printf '%q ' "${cmd[@]}"
printf '\n'
# Execute it
"${cmd[@]}"
Make sure not to use eval
:
eval "$cmd" #noooo
This will appear to work with your code as you posted it, but has caveats and security problems.