If you have control over the wrapper program, then make sure that it doesn't invoke a subshell. Deep down, an instruction to execute a program consists of the full path (absolute or relative to the current directory) to the executable, and a list of strings to pass as arguments. PATH lookup, whitespace separating arguments, quoting and control operators are all provided by the shell. No shell, no pain.
For example, with a Perl wrapper, use the list form of exec
or system
. In many languages, call one of the exec
or execXXX
functions (or unix.exec
or whatever it's called) rather than system
, or os.spawn
with shell=False
, or whatever it takes.
If the wrapper is a shell script, use "$@"
to pass down the arguments, e.g.
#!/bin/sh
mysim -preset-opt "$@"
If you have no choice and the wrapper program invokes a shell, you'll need to quote the arguments before passing them to the shell. The easy way to quote arguments is to do the following:
- In each argument, replace each occurrence of
'
(single quote) by the four-character string '\''
. (e.g. don't
becomes don'\''t
)
- Add
'
at the beginning of each argument and also at the end of each argument. (e.g. from don't
, don'\''t
becomes 'don'\''t'
)
- Concatenate the results with a space in between.
If you need to do this in a shell wrapper, here's a way.
arguments='-preset-opt'
for x; do
arguments="$arguments '"
while case $x in
*\'*) arguments="$arguments${x%%\'*}'\\''"; x=${x#*\'};;
*) false;; esac
do :; done
arguments="$arguments$x'"
done
(Unfortunately, bash's ${VAR//PATTERN/REPLACEMENT}
construct, which should come handy here, requires quirky quoting, and I don't think you can obtain '\''
as the replacement text.)
Best Answer
If the command is not very picky it should work with something like this:
This requires that you know the exact answers beforehand.