Making the Mac OS X bash shell alias and symlink agnostic
5 Comments Published December 1st, 2006 Tagged with: alias × bash × finder × macosx × shell × symlinkConvoluted title, eh? After many years of intermittently being miffed when I couldn’t just type cd /NameofAlias and have the bash shell transport me into the directory the alias pointed to, I finally decided to do something about it.
First stop: Mac OS X Hints, where I looked at these two hints:
Enable ‘cd’ into directory aliases from the Terminal
A script to reveal alias paths in the Terminal
From the insight gained there, I cobbled together my one-step solution to the problem…
I wanted to be able to do this on any Mac i encounter without having to install anything additional. So I simply added the below code to my .bash_profile
# 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.
Once it’s been loaded in your .bash_profile, any time you start a new session, the built-in ‘cd’ function has been replaced with the above. You should be able to use it just as before, the only exception being that now aliases will resolve as well as symlinks and regular directories.
Thanks to the original authors and developers of the hint(s) this is based on. I hope someone finds this useful.
NOTES:
1) 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.
2) I have only tested this on 10.4.x
Brilliant!
Under my Leopard, I replaced
if the kind of theItem is “alias” then
get the posix path of ((original item of theItem) as text)
end if
with only
get the posix path of ((original item of theItem) as text)
and everything began to work
[Thanks! If I ever upgrade to Leopard, I'll be sure to post an updated version of the script. Thanks for your help. --Kristofer]
Now all I need is a command-line method of creating a Finder alias. Any ideas?
Ah, the power of Google:
How to create a Finder alias from shell script?
http://forums.macosxhints.com/showthread.php?p=464423
[Hey, looks like you answered your own question. Thanks for coming back and posting.
--Kristofer]