The following shell script takes a list of arguments, turns Unix paths into WINE/Windows paths and invokes the given executable under WINE.
#! /bin/sh if [ '${1+set}' != 'set' ] then echo 'Usage; winewrap EXEC [ARGS...]' exit 1 fi EXEC='$1' shift ARGS='' for p in '$@'; do if [ -e '$p' ] then p=$(winepath -w $p) fi ARGS='$ARGS '$p'' done CMD='wine '$EXEC' $ARGS' echo $CMD $CMD
However, there’s something wrong with the quotation of command-line arguments.
$ winewrap '/home/chris/.wine/drive_c/Program Files/Microsoft Research/Z3-1.3.6/bin/z3.exe' -smt /tmp/smtlib3cee8b.smt Executing: wine '/home/chris/.wine/drive_c/Program Files/Microsoft Research/Z3-1.3.6/bin/z3.exe' '-smt' 'Z: mp\smtlib3cee8b.smt' wine: cannot find ''/home/chris/.wine/drive_c/Program'
Note that:
- The path to the executable is being chopped off at the first space, even though it is single-quoted.
- The literal ‘\t’ in the last path is being transformed into a tab character.
Obviously, the quotations aren’t being parsed the way I intended by the shell. How can I avoid these errors?
EDIT: The ‘\t’ is being expanded through two levels of indirection: first, '$p' (and/or '$ARGS') is being expanded into Z:\tmp\smtlib3cee8b.smt; then, \t is being expanded into the tab character. This is (seemingly) equivalent to
Y='y\ty' Z='z${Y}z' echo $Z
which yields
zy\tyz
and not
zy yz
UPDATE: eval '$CMD' does the trick. The ‘\t‘ problem seems to be echo’s fault: ‘If the first operand is -n, or if any of the operands contain a backslash ( ‘\’ ) character, the results are implementation-defined.’ (POSIX specification of echo)
I you do want to have the assignment to CMD you should use
eval $CMDinstead of just
$CMDin the last line of your script. This should solve your problem with spaces in the paths, I don’t know what to do about the ‘\t’ problem.