Why is this?

When I do this

CD ~/Desktop

It doesn't take me to the Desktop. But this:

echo "foo
bar" | GREP bar

gives me:

  • 4
    Check if alias GREP or which GREP output anything.
    – chepner
    Oct 28 '14 at 20:26
  • 1
    There you go. You have a command named GREP, which is distinct from grep. (True, it may just be a hard link or symbolic link to /usr/bin/grep, but from the shell's standpoint, it's a separate command.)
    – chepner
    Oct 28 '14 at 20:28
  • 12
    Wait: you're on Mac OS X, aren't you? HFS+ is case-preserving by default, which means that if case matters when you create a file, but once the file exists, lookups are case-insensitive. That is, bash might ask for a file named GREP, but the file system considers grep a match.
    – chepner
    Oct 28 '14 at 20:35
  • 1
    Yes, because it is Unix. Oct 30 '14 at 10:53
  • 4
    File systems are independent of the operating system. You can use other file systems with Mac OS X, and you can (in theory) use HFS+ with other operating systems. Also, you can make HFS+ case-sensitive; the case-preserving behavior is just the default for historical reasons.
    – chepner
    Oct 30 '14 at 12:48

From your other questions I take it you're using OS X. The default HFS+ filesystem on OS X is case-insensitive: you can't have two files called "abc" and "ABC" in the same directory, and trying to access either name will get to the same file. The same thing can happen under Cygwin, or with case-insensitive filesystems (like FAT32 or ciopfs) anywhere.

Because grep is a real executable, it's looked up on the filesystem (in the directories of PATH). When your shell looks in /usr/bin for either grep or GREP it will find the grep executable.

Shell builtins are not looked up on the filesystem: because they're built in, they are accessed through (case-sensitive) string comparisons inside the shell itself.

What you're encountering is an interesting case. While cd is a builtin, accessed case-sensitively, CD is found as an executable /usr/bin/cd. The cd executable is pretty useless: because cd affects the current shell execution environment, it is always provided as a shell regular built-in, but there is a cd executable for POSIX's sake anyway, which changes directory for itself and then immediately terminates, leaving the surrounding shell where it started.

You can try these out with the type builtin:

$ type cd
cd is a shell builtin
$ type CD
CD is /usr/bin/CD

type tells you what the shell will do when you run that command. When you run cd you access the builtin, but CD finds the executable. For other builtins, the builtin and the executable will be reasonably compatible (try echo), but for cd that isn't possible.

  • 1
    good answer. I was about to say cygwin, which would have the same effect.
    – Joshua
    Oct 29 '14 at 16:52
  • @Joshua The OP's problem is solved, but I think for further readers of the question, a cygwin based answer would be at least as useful as the existing one; Maybe you can make this a separate answer, even if short, and deferring to the existing one for details? Oct 29 '14 at 23:15
  • 1
    Why would posix require a useless command like cd, and why doesn't osx's internal cd not qualify?
    – John
    Oct 30 '14 at 1:59
  • 2
    51 upvotes! I should have just posted an answer, instead of a comment :)
    – chepner
    Oct 30 '14 at 12:49
  • 1
    /usr/bin/cd has a purpose. the syntax is /usr/bin/cd directory program arguments
    – Joshua
    Oct 30 '14 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.