cd, but better
A replacement for the default bash/zsh
cd command. It can mount FUSE
filesystems on-demand, jump down multiple levels of directories, etc.
always prefers real directories to special commands; so if you had a directory
cd foo: would just cd into
foo:, not try to mount
$ cd machine-name:[path] # automounts machine-name:path with sshfs $ cd /dev/sdb1 # create a mountpoint, then sudo-mount it $ cd **x # cd's to the first descendant dir matching /x/ $ cd ..5 # cd's up five directories $ cd ..foo # cd's up to the nearest dir matching /foo/ $ cd x.tar # mounts x.tar with archivemount $ cd hdfs://namenode:9000 # mounts namenode with hadoop-fuse-dfs $ cd ^ # history: go back one directory $ cd ^^ # history: go back two directories $ cd ^10 # history: go back ten directories $ cd -10 # history: go back ten directories $ cd ^foo # history: go back to last dir matching /foo/ $ cd git:/path/to/repo # mounts git commits as directories $ cd nfs:machine:/woot # mounts NFS directories $ cd enc:/path/to/encrypted # mounts an encfs directory $ cd loop:image.iso # mounts a loopback image $ cd au:/usr:/var # AUFS union mount
Fuse and root-mounted directories are unmounted automatically when you
cd also supports symlinks to virtual directories. For example:
$ ln -s machine-name:/foo/bar my-symlink $ cd my-symlink # same as cd machine-name:/foo/bar
If you want
cd to virtualize the destination of a symlink, the symlink must
not point to a real directory.
Using with zsh
cd works just fine with zsh, but you'll need to make sure of a few things.
First, make sure
KSH_ARRAYS is unset when you load the script; otherwise
cd will be in bash-compatible mode and will break under zsh. Second,
BASH_REMATCH and assumes that you'll leave it set (sorry). So if you
cd will start having problems.
cd will nuke any existing
zsh_exit you have defined. If you care
about this, ping me and I'll make it non-clobbering.
$ cd --history # prints $PWD history, most recent first $ cd --mounts # lists probably-active FUSE mount points $ cd --patterns # all patterns that 'cd' is looking for $ cd --clean # attempts to unmount and remove all mounts $ cd --which enc:x # indicates which delegate is used for enc:x
--clean option is good for cases where FUSE mountpoints are left in an
inconsistent state; for instance, when you suspend a machine with an open SSHFS
connection. It will unmount and remove all mountpoints that aren't in use.
To enable it (this can also be done from
$ . cd # enables extensible cd $ . cd-traverse # enables descendant/ancestor traversal $ . cd-history # ^, ^^, ^n, -n, ^regexp $ . cd-ssh # does nothing unless you have sshfs $ . cd-archive # does nothing unless you have archivemount $ . cd-hdfs # does nothing unless you have hadoop-fuse-dfs $ . cd-git # does nothing unless you have yagfs $ . cd-nfs # does nothing unless you have mount.nfs $ . cd-encfs # does nothing unless you have encfs $ . cd-dev # enables automounting for /dev/ entries $ . cd-loop # enables mounting for loopback files $ . cd-missing-mkdir # mkdir -p if you cd someplace nonexistent
$ CD_EXTENSIONS=(traverse history ssh archive hdfs git encfs dev loop) $ . cd
$ CD_EXTENSIONS=all $ . cd
You can see the patterns that are handled by running
cd --patterns. (This can
be useful if you want to find out which ones are ignored due to unmet
dependencies.) Anything that isn't a pattern is treated like a regular
Be sure to initialize this script after RVM. RVM redefines
any existing redefinitions. This script, on the other hand, preserves RVM's
cd redefinition while adding behavior of its own.
cd's extensions store state and/or create temporary mountpoints in
~/.cd, which it automatically creates.
$ . cd-missing-mkdir
Sourcing this script causes
cd to create directories that don't exist. Any
leaf directory created by
cd will be removed upon leaving if it is empty and
no process is using it. So, for example:
$ ls foo bar $ cd BOOYAH $ cd .. $ ls foo bar $
At this point
cd will create but not delete parent directories:
$ ls foo bar $ cd bif/baz/bok $ cd ../../.. $ ls foo bar bif $ ls bif baz $ ls bif/baz $
YaGFS doesn't have an Ubuntu package, but it should be easy to install from its
source repository. You'll need to
yagfs script into your
cd to know to use it.