Reputation: 75
I installed win-bash on Windows 7 and I'm getting the following strange behavior.
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)
Why are the PATH values different?
The PATH value returned by which
contains .:C;\Program\ Files\GnuWin32\bin
Note:
which
PATH value has back slashes (\\
) instead of forward slashes (/
)Where is which
sourcing these PATH values?
I can not find any other .bashrc or .profile or profile files anywhere on the machine.
In addition,
bash$ diff file-abc.txt file-xyz.txt
1c1
< abc
---
\> xyz
bash$ ls file-abc.txt
file-abc.txt
Both diff
and ls
work on the command line even though which
can not find the diff
or ls
commands.
Both diff
and ls
are located in C:/Program\ Files/GnuWin32/bin
But which
returns C;\Program\ Files\GnuWin32\bin
(note C; not C:) which is why which
can not find ls
or diff
.
Again, where is which
sourcing these PATH values?
In my bash script named Try1.sh I have these lines.
\`diff $CURRENT_FILE $NEW_FILE\`
\`ls $CURRENT_FILE\`
The diff command fails with
Try1.sh: 21c21: command not found
The ls
command succeeds. Why?
Both diff
and ls
live in the same PATH location C:/Program\ Files/GnuWin32/bin
.
Upvotes: 2
Views: 788
Reputation: 44354
Windows has a different search algorithm to UNIX-like systems. On Windows the first directory to be searched is the directory which the parent program (.exe) was loaded from, then the current directory, then C:/Windows/system32
is searched. That's where the directory names are coming from.
The path
environment variable is only used as a last resort!
For a full discussion on this, see MSDN entry for CreateProcess
which
is also showing the Windows path directory separator as ;
, rather than :
which UNIX-like systems use. Also, /
or \
are valid as a directory separator in a Windows path, but only /
is valid on UNIX.
Also note that environment variables (like path
) are not case sensitive on Windows, but on UNIX they are.
EDIT: I have been trying to track down the source code for win-bash but can't find it. I found some source code for which
in GNUUtils, but can't be sure that it is the same version as you are using. The version I looked at, 2.4, makes assumptions about Windows which are not necessarily correct.
After downloading the binary for win-bash, I found that the bundled which
is indeed version 2.4, and looks the same as the source code I have been looking at.
It is a separate program and not integrated with the rest of the shell code. To answer the question on directory separators and path separators, they are hard-coded for Windows (sys.h):
#define DIRSEP '\\'
#define PATHSEP ';'
The path is read from the environment variable using getenv
.
Further edit:
The command
\`diff $CURRENT_FILE $NEW_FILE\`
is invalid. It is capturing the output from diff
and then trying to execute it. 21c21
is the output from diff
, and of course there is no such program as 21c21
. Just use:
diff $CURRENT_FILE $NEW_FILE
Upvotes: 1