次のシェルスクリプトは、引数のリストを取得し、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」は、2つのレベルの間接参照によって拡張されています。最初に、"$p"
(および/または)が;"$ARGS"
に拡張されています。Z:\tmp\smtlib3cee8b.smt
次に、\t
タブ文字に展開されます。これは(一見)同等です
Y='y\ty'
Z="z${Y}z"
echo $Z
これは
zy\tyz
ではなく
zy yz
更新:eval "$CMD"
トリックを行います。" \t
"問題はechoの障害のようです: "最初のオペランドが-nの場合、またはいずれかのオペランドに円記号('\')文字が含まれている場合、結果は実装定義です。" (のPOSIX仕様echo
)