【问题标题】:Cygwin: Invoke batch file with argument, output redirection and complex windows pathsCygwin:使用参数、输出重定向和复杂的 Windows 路径调用批处理文件
【发布时间】:2019-04-29 08:25:01
【问题描述】:

如何在 Cygwin 下从 bash 脚本调用批处理文件,使用...

  • 批处理文件的绝对路径
  • 批处理文件参数表示绝对(Windows)路径
  • 输出重定向到绝对路径的文件中

在哪里...

  • 所有路径都可能包含空格和括号等特殊字符
  • 所有路径最初仅以 Unix 格式出现在 bash 脚本中?

我有一个 Windows 批处理脚本 C:\Program Files (x86)\bin\script.bat,它将输入文件的 (windows) 路径作为参数 - 示例:

@ECHO OFF
echo "This is script.bat. The value of the first argument is [%~1]"

我想将 script.bat 的输出重定向到另一个绝对路径的输出文件中。

在 windows 命令提示符 (cmd.exe) 上,我会像这样调用命令:

C:\> "C:\Program Files (x86)\bin\script.bat" "C:\Input Path\input.txt" > "C:\Output Path\output.txt"
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

如果我应用“批处理式转义”,我可以省略脚本和重定向目标周围的双引号,但这不适用于参数(出于某种原因):

C:\> C:\Program^ Files^ ^(x86^)\bin\script.bat "C:\Input Path\input.txt" > C:\Output^ Path\output.txt
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

...但是:

C:\> C:\Program^ Files^ ^(x86^)\bin\script.bat C:\Input^ Path\input.txt > C:\Output^ Path\output.txt
output.txt: This is script.bat. The value of the first argument is [C:\Input].

我还可以将命令包装到对 cmd.exe 的额外调用中,在整个术语周围使用额外的双引号:

C:\> cmd.exe /C ""C:\Program Files (x86)\bin\script.bat" "C:\Input Path\input.txt" > "C:\Output Path\output.txt""
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

C:\> cmd.exe /C "C:\Program^ Files^ ^(x86^)\bin\script.bat "C:\Input Path\input.txt" > C:\Output^ Path\output.txt"
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

我还可以将输出重定向应用到外部 cmd.exe 实例:

C:\> cmd.exe /C ""C:\Program Files (x86)\bin\script.bat" "C:\Input Path\input.txt"" > "C:\Output Path\output.txt"
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

C:\> cmd.exe /C "C:\Program^ Files^ ^(x86^)\bin\script.bat "C:\Input Path\input.txt"" > C:\Output^ Path\output.txt
output.txt: This is script.bat. The value of the first argument is [C:\Input Path\input.txt].

到目前为止一切顺利。但是如何从 Cygwin 下的 bash 脚本调用上述任何命令行呢?

所有路径最初仅以 Unix 格式存在:

#!/bin/sh
BIN_UNIX="/cygdrive/c/Program Files (x86)/bin/script.bat"
ARG_UNIX="/cygdrive/c/Input Path/input.txt"
OUT_UNIX="/cygdrive/c/Output Path/output.txt"

请注意,在调用脚本时文件 $OUT_UNIX 不存在(因此“cygpath --dos ...”不起作用)。

我尝试了几十种或多或少笨拙的 Unix/Windows 路径组合(用 cygpath 转换),无引号、单引号、双引号、无转义、“bash 样式”转义、“批处理样式”转义等。我能找到的唯一可行的解​​决方案取决于批处理脚本的 8.3 样式路径,它消除了空格和特殊字符:

#!/bin/sh
# [...]
BIN_DOS=$( cygpath --dos "${BIN_UNIX}" )
ARG_WIN=$( cygpath --windows "${ARG_UNIX}" )
cmd /C "${BIN_DOS}" "${ARG_WIN}" > "$OUT_UNIX"

但必须有一种更系统、更稳健的方法来做到这一点,对吧?


没有完全回答我的问题的相关问题:

Why is it that Cygwin can run .bat scripts?

Windows batches in Cygwin with spaces in path and arguments

correct quoting for cmd.exe for multiple arguments

How to Pass Command Line Parameters with space in Batch File

【问题讨论】:

  • 这里的批处理文件问题在哪里。你想要非 WINDOWS 答案。
  • @Noodles 棘手的一点是从 bash 到批处理的转换,引用/转义可能非常令人兴奋。我花了很多时间来检查类似的问题

标签: bash batch-file cygwin


【解决方案1】:

你可以使用

BIN_WIN=$( cygpath --windows "${BIN_UNIX}" )
ARG_WIN=$( cygpath --windows "${ARG_UNIX}" )
OUT_WIN=$( cygpath --windows "${OUT_UNIX}" )
cmd /c CALL "$BIN_WIN" "${ARG_WIN}" > "$OUT_WIN"

重要的一点是你的命令前面的CALL

cmd /c 无法启动包含空格的命令,因为即使周围有引号,它也会拆分命令。

cmd /c 也可以在没有CALL 的情况下使用,但需要额外的括起来的引号。

cmd /c "  "C:\Program Files (x86)\bin\script.bat" "args"   "

但是从cygwin把原始引号转成cmd.exe好像是不可能的,因为cygwin把引号翻译成\",所以表达式变成了

cmd /c \"  "C:\Program Files (x86)\bin\script.bat" "args"   \"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2010-09-12
    • 2017-12-31
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多