git-bash 和 cygwin shell 可以做同样的事情吗?

git-bash 和 cygwin shell 可以做同样的事情吗?

在 Windows 10 上,git-bash 和 cygwin shell 可以做同样的事情吗?

一个人能做什么而另一个人不能做什么?

例如,

  1. 作为 shell,它们都能和 bash 一样工作吗?
  2. 哪些程序和命令可以在一个环境中运行,但不能在另一个环境中运行?

    例如,在 git-bash 中,我无法运行某些 Windows 命令:

    $  reg add "HKCU\Software\Microsoft\VisualStudio\14.0_Config\MSBuild" /v EnableOutOfProcBuild /t REG_DWORD /d 0 /f
    ERROR: Invalid syntax.
    Type "REG ADD /?" for usage.
    

    但在 Cygwin 中,它运行良好

    $  reg add "HKCU\Software\Microsoft\VisualStudio\14.0_Config\MSBuild" /v EnableOutOfProcBuild /t REG_DWORD /d 0 /f
    The operation completed successfully.
    

    本来以为git-bash和cygwin都可以在windows下运行程序,为什么git-bash不行,而cygwin可以呢?

谢谢。

答案1

不同之处在于 Cygwin 知道如何处理所谓的“Win32”路径名。粗略地说,它知道“\”是路径名分隔符,而不是像 Bash 中的 shell 转义字符。您显示的错误是 Bash 将“\”解释为转义字符。(编辑:您可以尝试用两个 \ 替换一个,从而转义反斜杠,以便 Bash 正确地将命令传递给 reg.exe。)

话虽如此,尽管 Cygwin 能够理解 Windows 路径名,但它并不喜欢这样做。文档警告您不要使用它们。当然,偶尔退缩一下也无妨。但是,虽然您可以在 Cygwin 中运行 Windows 程序,但出于卫生方面的考虑,您应该在 CMD.EXE 处理器中运行 Windows 程序,在 Cygwin 中运行 UNIX 程序,以保证您的长期健康。

答案2

两者之间有很多重叠之处。但归根结底,它们是 Bash shell 的不同实现。

Cygwin 有大量可选软件可供安装,包括多种不同的编程语言、编译器、各种网络工具等等。您还可以安装 X Window 系统和许多 X 应用程序。

使用 Git Bash,你得到的只是你想要的,而且安装其他工具会稍微困难一些。实际上,我的工作站上同时安装了这两种工具,因为有些事情我无法在 git bash 中完成。我也曾在 git bash 窗口调用 Cygwin 应用程序时取得了好坏参半的成功。

此外,Cygwin 是一个完整的 POSIX 环境,而不仅仅是 Bash,因此您通常可以在其中编译非分布式代码。例如,如果您找到了一个不错的 Linux 工具的源代码,您通常可以为 Cygwin 编译该工具。但对于 Git Bash 来说就没那么容易了。正如我上面提到的,即使您确实为 Cygwin 编译了它,它也可能无法在 Git Bash 中工作。

除此之外,它们大多非常相似。看到 Git Bash 包含用于转换 Windows 和 Posix 文件路径的命令有点有趣cygpath,因为据我所知,Git Bash 是基于 MinGW 的,而 MinGW 是与 Cygwin 截然不同的系统。

答案3

我刚刚发现了一个区别:我可以在 Git bash 中运行这个脚本,但不能在 Cygwin 中运行。

for file in *.xml; do
    echo "Processing file: $file"
    sed -r 's:<Autorizado>([0-9]+)</Autorizado>:<Autorizado>00013069</Autorizado>:' -i "$file"
    # ...
done

在 Git bash 中,它处理我的 xml 文件,但在 Cygwin 中,它给出错误:

Processing file: *.xml
sed: cannot read *.xml: No such file or directory

bash --version在 Git bash 中:

GNU bash, version 4.3.42(5)-release (x86_64-pc-msys)

在Cygwin中:

GNU bash, versión 4.3.46(7)-release (x86_64-unknown-cygwin)

答案4

尽管使用 cygwin git 的答案是可行的,但“git bash”版本已经改进了一些问题,尤其是与 Windows open-ssh 实现的集成。我可能错了,只是还没有充分研究 cygwin 实现来修复它。YMMV。我们仍然有从 cygwin 调用 Windows 可执行文件的一般问题。

在这种情况下有三个问题(我主要关注的是 Windows 原生 gvim 和 git bash)。

  1. 传递给外部(windows)命令的文件名参数的路径。

  2. 命令在查找配置文件(.vimrc/_vimrc/.gitconfig 等)时所处的环境。由于我们最感兴趣的 Windows 命令是 Unix 样式的,因此它们主要围绕 $HOME 变量来查找这些配置文件。在 cygwin shell 中,该变量将是“/home/yournameisSue”。但这些程序正在寻找“C:/users/yourname_001”或类似目录中的那个。

  3. PATH。这个比较棘手。我假设 Windows 程序无法启动 cygwin 程序,因此需要原始的 Windows 路径,而不是 cygwin 路径。我们在 $ORIGINAL_PATH 中提供了该路径。这很糟糕,因为您无法轻松做到这一点

    :!一些cygwin命令

来自 gvim,但是那似乎不起作用而且我今天不会解决这个问题。

我的解决方案:

首先设置一个带有完整路径 Windows 样式 HOME 的变量。您可以使用正斜杠来简化操作,因此命令“cygpath -m”可以做到这一点。我在我的 cygwin 环境中找到了一个具有正确目录名称的变量 - USERPROFILE。它具有“C:\Users\myname_001”值。我在 .bashrc 中设置了一个新变量来保存它:

WINHOME=$(cygpath -m "$USERPROFILE")
$ echo $WINHOME
C:/Users/myname_000

现在我可以像这样启动非 cygwin git(比如从 git bash)或本地安装的 gvim(假设它们在 PATH 中。如果没有,请使用 cygwin 可以理解的完整路径名版本!):

HOME=$WINHOME gvim $@ 2>&1 &

这至少让它读取了我在 Windows 主目录中的 _vimrc 文件。进步了。但是当涉及文件路径时,命令行参数处理是一个问题。当然,像当前目录中的文件这样的相对路径名可以正常工作。当 Windows 版本的 gvim 启动时,它会询问操作系统它在哪个目录中,并且不知道 cygwin 将其转换为 /cygwin/c 或其他什么。但是如果你有完整的路径,它就会变得混乱。

我创建了一个函数来处理路径的参数列表。它创建了一个名为 _pathargs 的新数组,我们将用它来代替 $@。

pathargs() {
    _pathargs=() # initialize empty array
    for a in $@
    do
        if [[ "$a" =~ ^- || ! ( -f "$a" || -d "$a" ) ]]; then 
            # starts with a dash or is not a file or directory
            _pathargs+=("$a")
        else # is a file or directory so give a full windows path name
            b=$(cygpath -m -a $a)
            _pathargs+=("$b")
        fi
    done
}

现在,我的启动 gvim(我将其命名为“v”)的函数和运行 git bash git 命令的函数如下。请注意在调用 Windows 可执行文件之前设置 HOME 和 PATH。此语法“导出”执行命令的环境变量,而不会触及在 shell 中运行的变量:

export WINHOME=$(cygpath -m "$USERPROFILE")
alias cdwh='cd $WINHOME' # convenience alias
v() {
    pathargs $@
    # set HOME var to one gvim understands for finding config files like .vimrc _vimrc
    HOME="$WINHOME" PATH="$ORIGINAL_PATH" gvim ${_pathargs[*]}  2>&1 &
}
git() {
    pathargs $@
    # function to have same name as executable, so use "command" to protect 
    # against recursive call of the function itself
    HOME="$WINHOME" PATH="$ORIGINAL_PATH" command git ${_pathargs[*]}
}

一切似乎都有效;但是,如果您已使用 cygwin 设置安装了“git”,它将在 git bash(windows)版本之前出现在您的路径中。在这种情况下,您需要在函数定义中提供 git 可执行文件的完整路径,而不是使用“命令 git”。请记住使用 cygwin 可以理解的变体。

高血压

相关内容