用于Windows的Git中的Bash:使用带有args的CMD.exe / C运行命令时的怪异

时间:2014-01-25 23:54:10

标签: windows git bash cmd git-bash

这更令人烦恼而不是问题,但我非常想了解这里的语义。

我想要做的就是在临时命令提示会话上运行一个任意命令,该会话本身在bash会话下运行。

我的成功率是50/50,因为某些命令按预期工作,而其他命令则没有那么多。

我认为问题可能存在于没有正确排列的参数(即缺失或合并的参数)

我会尝试通过一系列命令和响应解释怪异的含义。 (我正试图在屏幕上打印 test 这个词。)

我在 GNU bash,版本3.1.0(1)-release(i686-pc-msys)下运行这些与Git-1.8.4捆绑在一起

首次尝试:

$ cmd /c echo test
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
c:\>

第二次尝试:

$ cmd '/c echo test'
test"

第三次尝试:

$ cmd "/c echo test"
test"

第四次尝试:

$ cmd /c\ echo\ test
test"

第五次尝试:

$ cmd "/c echo" test
'echo" test' is not recognized as an internal or external command,
operable program or batch file.

我非常感谢上述行为的任何指示或见解,因为这对我来说是不合理的,让我疯狂!

修改another question看起来与此类似,但实际上并非如此,主要是因为它是关于通过CMD / C运行批处理文件而不需要任何参数。

它并没有真正回答我关于如何正确地为windows命令行应用程序提供参数的问题,即使这些示例是关于CMD / C的,这里的答案也可以应用于许多其他Windows命令行应用程序。

7 个答案:

答案 0 :(得分:35)

这实际上记录在ReleaseNotes文件中(在已安装的Git for Windows的顶级文件夹中)

  

另外,为了传递Windows程序的Windows路径,需要格外小心,因为他们对MSys样式的POSIX路径没有任何线索 - 你可以使用像$(cmd // c echo“$ POSIXPATH”)这样的东西。

如果您使用cmd //c echo test,则按预期工作。

$ cmd //c echo test
test

原因是尝试确保posix路径最终正确传递给git实用程序。出于这个原因,Git for Windows包含一个影响命令参数的修改过的MSYS层。您应该注意,Git for Windows提供的bash shell和工具不能用作Windows的通用unix工具。如果你想要一个通用的unix风格的工具集,那么你应该安装MSYS或cygwin。 Git Bash shell设置为使用git,有时显示。

答案 1 :(得分:6)

阅读本文后,我找到了适用于我的解决方案:

$ cat gvim.sh
cmd << EOD
gvim $@
EOD
$

Windows 8.1,Git(版本1.9.5-preview20141217),GNU bash,版本3.1.20(4)-release(i686-pc-msys)。

答案 2 :(得分:3)

我能够使用gnu bash for Windows重现问题。

我无法用第一种形式建立一个没有任何引号的模式。它似乎适用于Windows ECHO命令,但不适用于其他命令,如DIR。 编辑 - 事实证明,gnu bash在我的命令中添加了引号,因此echo test变为"echo" "test"。引号使cmd.exe查找外部命令而不是内部ECHO命令。我碰巧有“echo.exe”,所以它似乎运行。奇怪的是没有显示测试周围的引号。当我尝试运行DIR命令时,它完全失败,因为没有任何DIR.EXE。

带引号的后续表单(除了最后一个)或转义空格的工作方式与您看到的相同 - 命令中有一个不需要的尾随引号。

我无法想出一个干净的解决方案。但是,我有一个丑陋的黑客应该给你想要的结果。只需在命令末尾连接REM命令即可。 REM将注释掉不需要的尾随报价。重要的是REM之后有空格,否则REM"将不会被识别为有效命令。以下任何一项都应该有效。

$ cmd '/c echo test&rem '
$ cmd "/c echo test&rem "
$ cmd /c\ echo\ test\&rem\ 

请注意,最后一个命令在反斜杠后面有一个空格。

该技术应该适用于您可能希望通过CMD.EXE执行的任何命令字符串。

答案 3 :(得分:3)

正如我对here的解释,将现代Git用于Windows的bash时,还有另一种选择

MSYS_NO_PATHCONV=1 cmd /c echo test

每次尝试的解释

TL; DR

不幸的答案是在Windows中,有很多方法可以解析参数,并且您必须以bash格式格式化输出,以便Windows程序以 it的方式对其进行解析期望

第二,第三和第四次尝试实际上都是相同的

这与> cmd "/c echo test"(在cmd中)相同。 Windows cmd仅使用"引号,因此您在运行时之间的某个地方,({bash} $ cmd '/c echo test'将所有参数都转换为"/c echo test",这是parses

由于从bash的角度来看,第二次/第三次/第四次尝试都相同,所以它们都给出相同的响应。令人惊讶的"是由于Windows仅使用"而不是'进行解析的原因,因此它与> cmd "/c echo test"

相同

第五次尝试

$ cmd "/c echo" test> cmd /c echo" test相同。 (我猜:/c之后的空格是可选的,因此不会由于/c echo而使cmd混淆,因为第一引号是原义的空格。)因此,它正在尝试执行命令echo" test不存在。由于引用,空格被解释为文字。同样,如果您已完成$ cmd "/c echo "test,则将获得输出"test,因为该空格不再被视为文字,并且不再是命令echo的一部分

注意:> cmd "/c echo" test> cmd /c echo" test的错误相同。我的猜测是,cmd会自行解析/c之后的所有内容,因此初始"不会产生任何影响,因为解析会重新开始。将其粉笔化至特殊的cmd怪异之处。


实际上可以使用Windows的python复制此内容,这与msys / mingw / git / bash / glibc / etc无关...

python -c "import subprocess; subprocess.Popen(['cmd', '/c echo test'])"

答案 4 :(得分:2)

我注意到git-bash将/c参数视为C:驱动器:

C:\Windows\system32\cmd.exe C:/ echo test

添加dbenham found双引号。这个回声test"例如:

cmd /c\ echo\ test

我需要相同的行(脚本)才能在git-bash和Cygwin Bash中工作。唯一可行的方法是

cmd /c\ echo\ test\&rem\ 

(请注意,此行需要以空格结尾)和

cmd << EOC
echo test
EOC

在<{1}}和添加 /c 后的 之后逃离每个空间(包括尾随空格),或只是将命令包装在here document

所有这些可能取决于git-bash的版本和特定命令。 : - (

答案 5 :(得分:1)

因为您提到您正在使用Git for Windows捆绑软件,所以我想指出it includes winpty,这似乎很容易理解。

$ winpty echo test
test

$ site="Default Web Site"
$ winpty 'C:\Windows\System32\inetsrv\appcmd' list site "${site}" /text:ID
1

答案 6 :(得分:0)

这似乎适用于1.9.5.msysgit.1

!foo=`bar`
cmd //c \\\\unc-path\\with\\slashes -args \"Quoted Arguments $foo\"