user3145909
user3145909

Reputation: 75

Strange PATH behavior in win-bash

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:

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

Answers (1)

cdarke
cdarke

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

Related Questions