Следующий скрипт оболочки принимает список аргументов, превращает пути Unix в пути WINE / Windows и вызывает указанный исполняемый файл под 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
Однако что-то не так с цитатой аргументов командной строки.
$ 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'
Обратите внимание, что:
- Путь к исполняемому файлу обрезается в первом пробеле, даже если он заключен в одинарные кавычки.
- Буква "\ t" в последнем пути преобразуется в символ табуляции.
Очевидно, что цитаты разбираются не так, как я предполагал оболочкой. Как я могу избежать этих ошибок?
РЕДАКТИРОВАТЬ: "\ t" расширяется через два уровня косвенности: во-первых, "$p"
(и / или "$ARGS"
) расширяется до Z:\tmp\smtlib3cee8b.smt
; затем \t
расширяется до символа табуляции. Это (на первый взгляд) эквивалентно
Y='y\ty'
Z="z${Y}z"
echo $Z
что дает
zy\tyz
и не
zy yz
ОБНОВЛЕНИЕ: eval "$CMD"
делает свое дело. Проблема «\t
», похоже, является ошибкой эха: «Если первый операнд -n или любой из операндов содержит символ обратной косой черты ('\'), результаты определяются реализацией». ( POSIX спецификация echo
)