What does the command CD do?

10

1

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

Posted 2009-11-13T03:19:59.820

Reputation: 2 995

Answers

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.

user12889

Posted 2009-11-13T03:19:59.820

Reputation: 1 743

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

Posted 2009-11-13T03:19:59.820

Reputation: 1 285

Well, if that's the case, then it doesn't work! If I type, e.g., CD /, it just does nothing. – John Fouhy – 2009-11-13T03:34:01.180

1That's because it runs in a subshell; the subshell cd's to /, then exits, leaving your shell unmoved. – Gordon Davisson – 2009-11-14T07:37:10.613

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 – 2009-11-19T15:38:58.663

Also, those aren't regular expressions. They're Bash parameter expansions: http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

– Johann – 2014-02-03T20:24:11.750