【发布时间】:2010-09-07 08:36:04
【问题描述】:
以下 shell 脚本采用参数列表,将 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”转换为制表符。
显然,shell 没有按照我想要的方式解析引号。如何避免这些错误?
编辑:“\t”正在通过两个间接级别进行扩展:首先,"$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 specification of echo)
【问题讨论】: