Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Enable 'cd' into directory aliases from the Terminal UNIX
I use the command line often and have been frustrated by the second-class-status that file system aliases have in the command shell. It would be nice if Apple would have the BSD system calls treat aliases the same as soft links, but alas, as of 10.4.2, they have not done so.

Also, file system aliases have some nice features which are not available to soft links, like labels, which cannot be used at all with soft links (well for a couple of seconds, it looks like you can, but they don't stick.) Another difference is that in 10.3, comments also don't stick, though they appear to do so in 10.4 (as a result of being Spotlight comments, probably). And of course, it is possible to create a file system alias using drag and drop. But one problem with using file system aliases instead of soft links is that you can't change your working directory (cd) to an alias of a directory.

So I created a command line executable to return the name of the Original file (in Finder parlence), including following soft links to aliases, and added a function to my .bashrc file to use that executable to get the name, and finally, to use that as the argument to the cd command. If there is no argument, the program calls the built-in cd routine, which changes to the user's home directory. If the argument tests as a directory (including soft link), the built-in cd is called with the given argument, because the system will use the name of the soft link in the path rather than the pointed-to directory. If the argument is a file or a soft link other than a directory, the true name is used as the argument to cd. Finally, if it is some other type of file, that argument is passed to the built-in cd, so the user gets the expected error message.

Here is the bash function I include in .bashrc. Note that the second elif requires double brackets for the test, because it include the logical operator or (||):
function cd {
  if [ ${#1} == 0 ]; then
    builtin cd
  elif [ -d "${1}" ]; then
    builtin cd "${1}"
  elif [[ -f "${1}" || -L "${1}" ]]; then
    path=$(getTrueName "$1")
    builtin cd "$path"
  else
    builtin cd "${1}"
  fi
}
And here's the C source code for getTrueName.

[robg adds: I tested this one, and it works perfectly (and very quickly in practice). You'll need to have the Developer Tools installed to compile the source, of course. Just copy and paste the source into a new file named getTrueName.c, then follow the build instructions included with the code. Once the executable is built, add the bash function to your .bashrc (or .bash_profile), and you're set -- you'll be able to cd into aliased directories from the command line. Very handy!]
    •    
  • Currently 2.67 / 5
  You rated: 5 / 5 (6 votes cast)
 
[21,539 views]  

Enable 'cd' into directory aliases from the Terminal | 10 comments | Create New Account
Click here to return to the 'Enable 'cd' into directory aliases from the Terminal' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Enable 'cd' into directory aliases from the Terminal
Authored by: googoo on Sep 01, '05 11:51:54AM
Some time ago I submitted this hint that uses an osascript (AppleScript) call to do the same thing as the getTrueName function. (If you want to try out the script in that hint, be sure to read the comments. The Mac OS X Hints community cleaned up the script a lot!)

There is always a different way to do it.

-Mark

[ Reply to This | # ]

Enable 'cd' into directory aliases from the Terminal
Authored by: eagle on Sep 01, '05 12:00:31PM

Along these lines, what I'd really like is the ability to work with Smart Folders from the command line. I would want to be able to ls them, cd into them, and cp from them.



[ Reply to This | # ]
Enable 'cd' into directory aliases from the Terminal
Authored by: gidds on Sep 01, '05 04:56:54PM
It's a good aim. But how far do you go?

Do you want Unix programs to be able to follow them? Do you want 'find' and all the others to be able to read files with an alias in the path you give? Do you want 'zip' to be able to store and recreate them? And so on.

The only way to handle aliases properly would be to build them in at the filesystem level, and provide versions of all the standard IO library calls which could follow or not follow them, as appropriate -- the same as has already been done for symbolic links. That's a big, big change. And anything short of that is going to cause strange behaviour at some points, where the aliases fail to work.

---
Andy/

[ Reply to This | # ]

Enable 'cd' into directory aliases from the Terminal
Authored by: bkuestner on Sep 01, '05 03:18:40PM

On July 22 I submitted treating aliases of directories like symbolic links to directories in the Terminal as a request to Apple on their Webradar site for ADC members.

The case was closed on August 20. "This enhancement request has been forwarded to the appropriate engineering team for review and consideration."

I can only hope that this engineer finds a nice way to make this default behavior for the Terminal in OS X.



[ Reply to This | # ]
Enable 'cd' into directory aliases from the Terminal
Authored by: blm on Sep 01, '05 08:51:25PM
add the bash function to your .bashrc (or .bash_profile)

Unless Tiger's bash is different than every other bash I've used, the bit in parens is incorrect. Functions aren't passed to subshells, and .bash_profile isn't run by subshells, only .bashrc is. So if you put the function declaration in your .bash_profile, it won't work, for example, if you drop into a subshell from vi using the :sh command. The function won't be defined, so you'll get the regular old cd.

The hint itself is great, just put it in your .bashrc, not your .bash_profile.

[ Reply to This | # ]

Enable 'cd' into directory aliases from the Terminal
Authored by: kaltree on Sep 02, '05 12:04:50PM
I think an easy fix to this issue is to create the shotcut via the built-in shell application called ln.

Suppose I have a folder:
Users -> John -> Documents -> School Files -> Archives -> stuff

I want a shortcut in:
Users -> John -> Shortcut File

The desired behavior is to open a terminal, and cd into the link 'Shortcut File', taking me to 'stuff' without having to drill down through all the layers...

You would type the following to create this shortcut (symbolic link):

ln -s "/Users/John/Documents/School Files/Archives/stuff" "/Users/John/Shortcut File"
You can open this folder just as you would in the finder. Infact, it shows up as a regular shortcut. The main advantage here is you can also enter this directory via the shell (either local, or SSH). I guess it just makes sense to me that if you need access to the folder via the shell, why not just create the shortcut through the shell?

Seems like a defect to be submitted via RADAR though. A shortcut should have non-ambiguous behavior.

[ Reply to This | # ]
Enable 'cd' into directory aliases from the Terminal
Authored by: Anonymous on Sep 05, '05 08:47:09AM
It might be worth trying SymbolicLinker 1.1v3 by Nick Zitzmann. It works in Tiger. The only issue is that the links it creates are to absolute paths, not relative. It hasn't been updated for two years, so I don't know what its status is.

[ Reply to This | # ]
Missing the point of this hint
Authored by: klktrk on Dec 01, '06 11:00:32AM

The point of this hint is not to replace aliases with symbolic links. obviously you could just make a choice to never make aliases and always create symbolic links instead, in which case this hint would be moot.

The author is trying to address the more common scenario where you are working in the shell on a machine where aliases are already existing (likely in any Mac OS X environment where the finder is being used).

Sure you can just try to never use the alias functionality of the Finder (though it is in fact in many ways superior to symbolic links), but if you want to use aliases AND be able to navigate them in the shell, what do you do? This is the issue the hint is trying to address, and does so quite well.



[ Reply to This | # ]
Enable 'cd' into directory aliases from the Terminal
Authored by: smccandlish on Mar 05, '06 10:22:07AM

How would one do this in tcsh? Not everyone is a bash fan. :-)

---
--
Stanton McCandlish
Director, Technology Standards
Integrity Incorporated



[ Reply to This | # ]
Enable 'cd' into directory aliases from the Terminal
Authored by: klktrk on Dec 01, '06 10:56:52AM

This is a great hint. Thanks for this.

I wanted to modify this so i could run it on any mac i encounter whether I have been able to install the c-code above or not, so I decided to use a related hint* to replace the getTruePath portion of the code.


# teach shell to treat aliases like symbolic links rather than files
function cd {
	if [ ${#1} == 0 ]; then
		builtin cd
	elif [[ -d "${1}" || -L "${1}" ]]; then	# regular link or directory
		builtin cd "${1}"
	elif [ -f "${1}" ]; then	# file: is it an alias?
		# Redirect stderr to dev null to suppress OSA environment errors
		exec 6>&2 # Link file descriptor 6 with stderr so we can restore stderr later
		exec 2>/dev/null # stderr replaced by /dev/null
		path=$(osascript << EOF
tell application "Finder"
set theItem to (POSIX file "${1}") as alias
if the kind of theItem is "alias" then
get the posix path of ((original item of theItem) as text)
end if
end tell
EOF
)
		exec 2>&6 6>&-      # Restore stderr and close file descriptor #6.
		
		if [ "$path" == '' ];then # probably not an alias, but regular file
			builtin cd "${1}"	# will trigger regular shell error about cd to regular file
		else	# is alias, so use the returned path of the alias
			builtin cd "$path"
		fi
	else	# should never get here, but just in case.
		builtin cd "${1}"
	fi
}

I put this in my .bash_profile, which I have checked in to a CVS repository. Then, from any Mac that I am working on, I simply check out my bash environment and either source it or overwrite the current .bash_profile. This gives me instant access from anywhere to all the modification I make to my bash environment.

Thanks to the original authors and developers of the hint(s) this is based on. I hope someone finds this useful.

(Unfortunately, using it at first was triggering these messages:
CFLog (21): dyld returns 2 when trying to load /Library/ScriptingAdditions/QXPScriptingAdditions.osax/Contents/MacOS/QXPScriptingAdditions
so that's why I had to supress the errors.)

____________________
* A script to reveal alias paths in the Terminal



[ Reply to This | # ]