以下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'
请注意:
显然,引用没有按照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
)
答案 0 :(得分:3)
考虑到这一点
#! /bin/bash
# push ARRAY arg1 arg2 ...
# adds arg1, arg2, ... to the end of ARRAY
function push() {
local ARRAY_NAME="${1}"
shift
for ARG in "${@}"; do
eval "${ARRAY_NAME}[\${#${ARRAY_NAME}[@]}]=\${ARG}"
done
}
PROG="$(basename -- "${0}")"
if (( ${#} < 1 )); then
# Error messages should state the program name and go to stderr
echo "${PROG}: Usage: winewrap EXEC [ARGS...]" 1>&2
exit 1
fi
EXEC=("${1}")
shift
for p in "${@}"; do
if [ -e "${p}" ]; then
p="$(winepath -w -- "${p}")"
fi
push EXEC "${p}"
done
exec "${EXEC[@]}"
答案 1 :(得分:1)
我确实想要使用
来分配给CMD eval $CMD
而不仅仅是脚本最后一行的$CMD
。这应该可以解决路径中空格的问题,我不知道如何处理“\ t”问题。
答案 2 :(得分:0)
您可以尝试在空格前面加上\ like:
/home/chris/.wine/drive_c/Program Files/Microsoft\ Research/Z3-1.3.6/bin/z3.exe
你也可以对你的问题做同样的事情 - 用\\ t替换它。
答案 3 :(得分:0)
将最后一行从$ CMD替换为
wine'$ EXEC'$ ARGS
你会注意到错误是'/home/chris/.wine/drive_c/Program'而不是'/home/chris/.wine/drive_c/Program'
单引号未正确插值,字符串按空格分割。