以下 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'

注意:

  1. 可执行文件的路径在第一个空格处被截断,即使它是单引号的。
  2. 最后一个路径中的文字“ ”将被转换为制表符。

显然,shell 并没有按照我想要的方式解析引号。我怎样才能避免这些错误?

编辑:“ ”通过两个间接级别进行扩展:第一的, "$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)

有帮助吗?

解决方案

我确实想将 CMD 分配给您,您应该使用

eval $CMD

而不是仅仅 $CMD 在脚本的最后一行。这应该可以解决路径中空格的问题,我不知道如何处理“ ”问题。

其他提示

  • bash 的数组不可移植,但却是在 shell 中处理参数列表的唯一明智的方法
  • 参数的数量在 ${#} 中
  • 如果当前目录中存在以破折号开头的文件名,您的脚本将会发生不好的事情
  • 如果脚本的最后一行只是运行一个程序,并且退出时没有陷阱,则应该执行它

考虑到这一点

#! /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[@]}"

将 $CMD 中的最后一行替换为

葡萄酒“$EXEC”$ARGS

您会注意到错误是“/home/chris/.wine/drive_c/Program”而不是“/home/chris/.wine/drive_c/Program”

单引号未正确插入,并且字符串被空格分隔。

您可以尝试在空格前面加上 \ ,如下所示:

/home/chris/.wine/drive_c/Program Files/Microsoft\ Research/Z3-1.3.6/bin/z3.exe

您也可以对 问题执行相同的操作 - 将其替换为 \ 。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top