25

I'd like to create a desktop shortcut to a specific folder, buried deep within ~/Library/. Library is Hidden by default in Lion, and I'd like to keep it that way, for a variety of reasons. Is there a one-step, command line action I can use, to create a desktop shortcut to a given path? I'd like to avoid solutions that involve unhiding the Library, creating the Alias using Finder, and rehiding it. I know how to do that, but for my purposes, a single line that can be pasted into Terminal and be done with it would be preferable.

5 Answers 5

13

Try this on Terminal:

cd ~/Desktop
ln -s ~/Library/path/to/folder
7
  • 5
    I think you meant ln -s ~/Library/path/to/folder folder. One minor disadvantage to this method (ie symlinking) is that the link will be broken if the "original" (ie the target) is moved or renamed.
    – Kelvin
    Commented May 20, 2012 at 2:32
  • 2
    The second argument folder is not required. If you omit it, ln creates a link named the same as the original folder.
    – Boj
    Commented May 20, 2012 at 3:31
  • Ah, you're right. I got an error before, but I must've mistyped something.
    – Kelvin
    Commented May 20, 2012 at 3:48
  • 1
    I know what it was - you can't have a trailing slash!
    – Kelvin
    Commented May 20, 2012 at 3:50
  • 14
    OSX aliases are not symbolic links. See stackoverflow.com/questions/11165799/…
    – bfontaine
    Commented Jul 1, 2015 at 12:06
17

It's possible to do it in one line of Terminal. Let's say you want to alias to the file "/Users/me/Library/Preferences/org.herf.Flux.plist".

osascript -e 'tell application "Finder"' -e 'make new alias to file (posix file "/Users/me/Library/Preferences/org.herf.Flux.plist") at desktop' -e 'end tell'

You should replace to file with to folder if you have a folder.

Here's a shell script that allows you pass in a file or folder path to create the alias:

#!/bin/bash

if [[ -f "$1" ]]; then
  type="file"
else
  if [[ -d "$1" ]]; then 
    type="folder"
  else
    echo "Invalid path or unsupported type"
    exit 1
  fi
fi

osascript <<END_SCRIPT
tell application "Finder"
   make new alias to $type (posix file "$1") at desktop
end tell
END_SCRIPT

If you name this script make-alias.sh, chmod u+x make-alias.sh and put it in /usr/local/bin, you can run e.g. make-alias.sh ~/Library/Preferences.

6
  • Will ~/Library/Preferences/org.herf.Flux.plist" work, or does the username need to be explicitly included in the Terminal command? Commented May 20, 2012 at 1:51
  • I just tried using ~ and it doesn't work with the one-line osascript command. I suggest using the script file instead, because the ~ is converted automatically.
    – Kelvin
    Commented May 20, 2012 at 1:56
  • Hmm. Seems to break on filenames with spaces such as /Library/Application Support/ Commented May 20, 2012 at 2:13
  • If you're using the bash script, you should put the filename in single quotes if it has any spaces or special characters. However, this will prevent ~ from being expanded. The best thing is not to use quotes, and to tab complete the filename so bash will properly "escape" the special characters. E.g. type ~/Library/Application then press tab. If Application Support was the only match, the shell should have inserted a backslash before the space. You can also manually use a backslash to escape.
    – Kelvin
    Commented May 20, 2012 at 2:26
  • Note that the spaces/special chars problem would exist in any solution - the shell can't know that you meant to pass 1 parameter rather than 2 separate ones.
    – Kelvin
    Commented May 20, 2012 at 2:35
2
#!/bin/bash

get_abs() {
  # $1 : relative filename
  echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}


if [[ $# -ne 2 ]]; then
    echo "mkalias: specify 'from' and 'to' paths" >&2
    exit 1
fi

from=$(eval get_abs $1)  
todir=$(dirname $(eval get_abs $2))
toname=$(basename $(eval get_abs $2))
if [[ -f "$from" ]]; then
    type="file"
elif [[ -d "$from" ]]; then
    type="folder"
else
    echo "mkalias: invalid path or unsupported type: '$from'" >&2
    exit 1
fi

osascript <<EOF
tell application "Finder"
   make new alias to $type (posix file "$from") at (posix file "$todir")
   set name of result to "$toname"
end tell
EOF
2
  • An explanation of how the script works would be useful
    – mmmmmm
    Commented Jul 10, 2018 at 10:09
  • Same as script above but without need for realpath Commented Jul 11, 2018 at 21:35
1

In case you need to target the link at a specific folder (or give it a specific name), you can use set name of result to "…" as in

#!/bin/bash

if [[ $# -ne 2 ]]; then
    echo "mkalias: specify 'from' and 'to' paths" >&2
    exit 1
fi

from="$(realpath $1)"
todir="$(dirname $(realpath $2))"
toname="$(basename $(realpath $2))"
if [[ -f "$from" ]]; then
    type="file"
elif [[ -d "$from" ]]; then
    type="folder"
else
    echo "mkalias: invalid path or unsupported type: '$from'" >&2
    exit 1
fi

osascript <<EOF
tell application "Finder"
   make new alias to $type (posix file "$from") at (posix file "$todir")
   set name of result to "$toname"
end tell
EOF
1

For people who would like a python solution, here is a function wrapping applescript, then calling subprocess.call:

def applescript_finder_alias(theFrom, theTo):
    """
    (theFrom, theTo)
    create a short/alias
    theFrom, theTo: relative or abs path, both folder or both file
    """
    # https://apple.stackexchange.com/questions/51709
    applescript = '''
    tell application "Finder"
       make new alias to %(theType)s (posix file "%(theFrom)s") at (posix file "%(todir)s")
       set name of result to "%(toname)s"
    end tell
    '''
    def myesp(cmdString):
        import os, inspect, tempfile, subprocess
        caller = inspect.currentframe().f_back
        cmd =  cmdString % caller.f_locals

        fd, path = tempfile.mkstemp(suffix='.applescript')
        try:
            with os.fdopen(fd, 'w') as tmp:
                tmp.write(cmd.replace('"','\"').replace("'","\'")+'\n\n')
            subprocess.call('osascript ' + path, shell=True, executable="/bin/bash")
        finally:
            os.remove(path)
        return None
    import os
    theFrom = os.path.abspath(theFrom)
    theTo = os.path.abspath(theTo)
    if os.path.isfile(theFrom): 
        theType = 'file'
    else:
        theType = 'folder'
    todir = os.path.dirname(theTo)
    toname = os.path.basename(theTo)
    myesp(applescript)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .