6

I'm looking for an easy way to navigate to directories spanning multiple hard drives and want to set something equivalent to a shortcut within the terminal.

In Windows I would accomplish this with mklink and create either symbolic links to jump to the directory, or junctions to append the location to the end of the current file path.

Since this is really just about navigation, it also needn't be a link or anything, maybe there is some environmental variable I could set so that I can cd $myDir (preferable).

Is such a thing possible, or do I just really need to learn my directories better?

user1695505
  • 163
  • 1
  • 1
  • 4

4 Answers4

10

Becoming familiar with your file system layout is all part of becoming a competent user - any time you spend with that aim in mind is not time wasted. However, with that said, you can indeed make it easier to move around the file system. Note that in Linux/UNIX, the file system is presented as a single tree, no matter how many devices make up your storage, unlike in Windows where each "drive" (physical or logical, depending on your configuration) is represented, in the default configuration, by an independent tree.

There are numerous ways you can approach this problem. It is certainly possible to set up a bunch of shell variables that each point to a different directory. Issuing cd $SomeDir will cause the shell to expand the variable $SomeDir and substitute it in the command line, so that when it finally runs, cd receives the name of the directory stored in the variable. This is probably the simplest approach, and if you populate your shell variables with absolute paths, it should work from anywhere in the file system.

You could also use symbolic links to target directories (hard links to directories are not supported in most UNIXs). However, for this to be effective, you'd still need to give sufficient information in the path argument to allow the kernel to resolve the symlink. That is, you'd need to provide the absolute path to the symlink, or enough of a relative path to allow the kernel to find the link, so it could then follow it.

A further approach, which may or not be available, depending on your shell, is to use the shell's cdpath feature. This is supported in bash, zsh, tcsh and undoudtedly others. With this technique, you set the environment variable CDPATH to a colon-separated list of directory names, which is searched when you run cd. If one of the directories on $CDPATH contains a subdirectory whose name matches that passed to cd, the shell changes its current working directory. For example, if CDPATH contains /usr/local, and if your system has a directory /usr/local/www, issuing cd www will look up the contents of $CDPATH, try to find a subirectory of /usr/local called www, and if it exists, will change its current working directory to /usr/local/www. Note that the shell searches the directories in $CDPATH in the order they are specified, so if $CDPATH contains multiple directories that contain the subdirectory you pass as argument to cd, the first match wins. This has caught me out often enough that I no longer us cdpath.

D_Bye
  • 13,977
  • 3
  • 44
  • 31
  • dang, I didn't even see this when I posted my own here - and I even deleted mine when I first realized you covered it so well, but I think there are enough differences between them that I undeleted it. You definitely got my vote though. – mikeserv Dec 28 '14 at 00:26
5

You could just set up some alias', like:

$ alias abc="cd /home/user/Desktop/Folder"

To store these for the longer term add them to your .bashrc file.

This will work if it's just navigation you're looking for - however the 'abc' above won't be any use if you want to script anything.

I personally think it might be as easy in the long run to learn and remember [the relevant parts of ] your directory structure. Too many aliases just give you more things to remember, and they won't work on different computers you may have to use in time.

Jack
  • 147
  • 10
4

I would like to recommend the z utility - https://github.com/rupa/z (which is inspired by another utility named j).

What z does is override your shell's cd function to add a side-effect of logging all the directories you visit. These directories are stored in the file ~/.z in a descending order of "frecency", such that a directory would appear higher if it was accessed more times and more recently.

Then, after you have used cd for a while to build up this index, you can use the new z $DIR command to jump to the directory containing the substring $DIR which appears highest in ~/.z.

yoniLavi
  • 151
0

There is $CDPATH:

mkdir -p ./1/2/3/4/dir ./3/2/1/dir ./12/dir
CDPATH=":$HOME/1/2/3/4:$HOME/3/2/1:$HOME/12:"
cd dir

If you put a list of frequently visited hub paths in its value, you can then cd to any of their child paths without specifying the full path. cd will put you in the first match it finds. And it will print your location to stdout when it does:

OUTPUT:

/home/mikeserv/1/2/3/4/dir

The values are :colon delimited - just like $PATH - so if you have crazy dirnames you might have issues. But it can be very useful. And it's POSIX specified - should work in any modern shell, I expect:

 cd ..; rm -rf dir; cd dir

OUTPUT:

/home/mikeserv/3/2/1/dir

Be sure you open its value with a :colon though - in most shells it is $CDPATH that enables you to cd to a child directory of the current directory without a leading ./ - that's what the leading : null-field denotes.

It is for this reason though that you needn't worry about it putting you were you don't want to go either - if you do use a qualified path (basically any arg to cd which begins with either a . or a /) cd does not interpret it at all.

mikeserv
  • 58,310