win-bash中的奇怪PATH行为

时间:2014-01-02 04:49:48

标签: bash .bash-profile

我在Windows 7上安装了win-bash,我遇到了以下奇怪的行为。

bash$ cat C:/Home/.bashrc
PATH="C:/Program\ Files/GnuWin32/bin:C:/Windows/system32"

bash$ . C:/Home/.bashrc

bash$ echo $PATH
C:/Program\ Files/GnuWin32/bin:C:/Windows/system32

bash$ which diff
which: no diff in (.;C;\Program\ Files\GnuWin32\bin;C:\Windows\system32)

bash$ which ls
which: no ls in (.;C;\Program\ Files\GnuWin32\bin;C:\Windows\system32)

为什么PATH值不同?

which返回的PATH值包含.:C;\Program\ Files\GnuWin32\bin

注意:

  • bash PATH值中不存在的“。:”开头。
  • “C;” (不是C :)包含分号而不是冒号。
  • which PATH值有反斜杠(\\)而不是正斜杠(/

which在哪里获取这些PATH值?
我在机器上的任何地方都找不到任何其他.bashrc或.profile或配置文件。

此外,

bash$ diff file-abc.txt file-xyz.txt
1c1
< abc
---
\> xyz

bash$ ls file-abc.txt
file-abc.txt

即使diff无法找到lswhich命令,diffls也会在命令行上运行。

diffls都位于C:/Program\ Files/GnuWin32/bin 但是which会返回C;\Program\ Files\GnuWin32\bin(注意C;而不是C :),这就是which无法找到lsdiff的原因。

同样,which在哪里获取这些PATH值?

在我的名为Try1.sh的bash脚本中,我有这些行。

\`diff $CURRENT_FILE $NEW_FILE\`
\`ls $CURRENT_FILE\`
The diff command fails with
Try1.sh: 21c21: command not found

ls命令成功。为什么呢?

diffls都位于同一个路径C:/Program\ Files/GnuWin32/bin

1 个答案:

答案 0 :(得分:1)

Windows对类UNIX系统有不同的搜索算法。在Windows上,要搜索的第一个目录是从中加载父程序(.exe)的目录,然后搜索当前目录,然后搜索C:/Windows/system32。这就是目录名称的来源。

path环境变量仅用作最后的手段!

有关此问题的完整讨论,请参阅MSDN entry for CreateProcess

which还将Windows路径目录分隔符显示为;,而不是类似UNIX的系统使用的:。此外,/\作为Windows路径中的目录分隔符有效,但只有/在UNIX上有效。

另请注意,环境变量(如path)在Windows上不区分大小写,但在UNIX上则是如此。

编辑:我一直试图找到win-bash的源代码,但找不到它。我在GNUUtils中找到了{em>一些源代码which,但不能确定它与您使用的版本相同。我看过的版本2.4,对Windows做出了一些不一定正确的假设。

下载win-bash的二进制文件后,我发现捆绑的which确实是版本2.4,看起来与我一直在查看的源代码相同。

它是一个单独的程序,没有与其他shell代码集成。要回答关于目录分隔符和路径分隔符的问题,它们是用于Windows(sys.h)的硬编码:

#define DIRSEP '\\'
#define PATHSEP ';'

使用getenv从环境变量中读取路径。

进一步编辑:

命令

\`diff $CURRENT_FILE $NEW_FILE\` 

无效。它正在捕获diff的输出,然后尝试执行它。 21c21diff的输出,当然没有21c21这样的程序。只需使用:

diff $CURRENT_FILE $NEW_FILE