Cygwin:调用带有参数、输出重定向和复杂 windows 路径的批处理文件
Cygwin: Invoke batch file with argument, output redirection and complex windows paths
如何从 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].
如果我应用 "batch-style escaping",我可以省略脚本和重定向目标周围的双引号,但这对参数不起作用(出于某种原因):
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-style"转义, "batch-style" 转义等。我能找到的唯一可行解决方案取决于批处理脚本的 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
你可以使用
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" \"
如何从 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].
如果我应用 "batch-style escaping",我可以省略脚本和重定向目标周围的双引号,但这对参数不起作用(出于某种原因):
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-style"转义, "batch-style" 转义等。我能找到的唯一可行解决方案取决于批处理脚本的 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
你可以使用
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" \"