test -e cannot distinguish between foo and foo.exe

Eric Blake ericblake@comcast.net
Mon Dec 19 15:30:00 GMT 2005

> I noticed the following behaviour: (found by my favorite testcase ;) )
> $ rm -rf foo* ; touch foo.exe
> $ test -e foo && echo found foo
> found foo
> $ test -e foo.exe && echo found foo.exe
> found foo.exe
> Hmm, how can I test if foo exists without also looking at foo.exe?
> Does this count as a bug in test?

It is a feature, not a bug, caused by cygwin's .exe magic.  Bash
cannot[1] distinguish between foo and foo.exe because stat(2)
does not distinguish.  On non-managed mount, checking for
'foo.' is a good workaround.  Another workaround that works
for both managed and non-managed mounts is to rely on
globbing (it uses readdir, so it bypasses .exe magic), as in:

$ rm -rf foo*; touch foo.exe
$ test -e fo[o] || echo foo not found
foo not found

[1] Actually, bash could tell the difference, if I were to patch it.  I
have made similar patches to mv(1), cp(1), ln(1), and so forth in
the coreutils package, but the patch is rather expensive (it
involves calling stat multiple times to differentiate between foo
and foo.exe) to undo .exe magic, and should only be needed in
the rare cases such as the coreutils that I have actually patched.
Most cygwin programs, including bash, use .exe magic as a
feature and should not be patched to work around it.

Eric Blake
volunteer cygwin bash maintainer

Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

More information about the Cygwin mailing list