10

Not realising I had caps-lock on, I typed CD into the command prompt on my mac. Surprisingly, it didn't error.

which CD shows me /usr/bin/CD. And if I examine that file, it looks like this:

#!/bin/sh
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
# This file is in the public domain.
builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"}

I guess it's something to do with translating upper to lower case, but ${0##*/} is completely opaque to me. man CD tells me "no manual entry". Can someone explain this command?

EDIT: Ok, I just noticed that OSX's filesystem is case-insensitive, so this file is actually /usr/bin/cd. But if I type cd normally, I of course get the builtin, so /usr/bin/cd only gets called when I get my case wrong. I'd still like to know what it does.

John Fouhy
  • 3,135
  • 2
  • 28
  • 29

2 Answers2

12

Seems it doesn't do much at all:

Apple mailing list link

"I'm going on some old memories here, so I cannot provide a very detailed explanation, but the reason /usr/bin/cd exists is due to a POSIX requirement that relates to aliases and being able to not use an alias via escaping. But /usr/bin/cd is a useless script since if you run cd within a shell script the directory change only applies to the subshell under which the script runs. cd cannot be a shell script.

Also, the script is a generic script in that it is used for a number of commands and not just cd.

I noticed that /usr/bin/cd has a hard link count of 15 on my 10.4 system [...]"

Further down in that thread:

"A friend of mine told me the "${0##*/}" means "take the command, but remove its path" (i.e., convert "/usr/bin/cd" to "cd")."

So it seems the script removes the path, converts the result to lower case and then appends the original arguments.

Giacomo1968
  • 53,069
  • 19
  • 162
  • 212
user12889
  • 1,863
  • 3
  • 18
  • 21
1

It's trying to do the right thing and translate your "cd" command to lowercase. Regrettably, that's pretty pointless as it runs in a subshell. The remainder has to do with understanding bash.

pbr
  • 1,335
  • 1
  • 7
  • 14
  • Well, if that's the case, then it doesn't work! If I type, e.g., `CD /`, it just does nothing. – John Fouhy Nov 13 '09 at 03:34
  • 1
    That's because it runs in a subshell; the subshell cd's to /, then exits, leaving *your* shell unmoved. – Gordon Davisson Nov 14 '09 at 07:37
  • As has been pointed out, this same script has a number of different filenames (hard links) - most if not all of them are UPPERCASE filenames. YES - in the case of CD it doesn't appear to work because cd has no effect when run in a subshell. That's why I wrote that it's "trying" to do the right thing. Indeed, it does not succeed. For SOME cases, this script will do the right thing; for example, if it's linked to LS, when you type "LS /USR/BIN" it will run "ls /usr/bin" – pbr Nov 19 '09 at 15:38
  • Also, those aren't regular expressions. They're Bash parameter expansions: http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion – Johann Feb 03 '14 at 20:24