9

To set an icon on a file or directory is straight forward using the "Get Info" dialog in Finder.

  1. copy image from e.g. Preview
  2. open "Get Info" on file or directory
  3. press TAB to select the icon
  4. paste Cmd-V

But how do you do this using the command line?

Gregory Vincic
  • 304
  • 3
  • 8
  • If you are going to answer your own question, you should move the answer part to the answer section and mark it as accepted. Otherwise, people are going to try to answer it for you. – Ned Deily Dec 03 '11 at 23:22

2 Answers2

11

Here is a bash script "setIcon.sh" for it

#!/bin/sh
# Sets an icon on file or directory
# Usage setIcon.sh iconimage.jpg /path/to/[file|folder]
iconSource=$1
iconDestination=$2
icon=/tmp/`basename $iconSource`
rsrc=/tmp/icon.rsrc

# Create icon from the iconSource
cp $iconSource $icon

# Add icon to image file, meaning use itself as the icon
sips -i $icon

# Take that icon and put it into a rsrc file
DeRez -only icns $icon > $rsrc

# Apply the rsrc file to
SetFile -a C $iconDestination

if [ -f $iconDestination ]; then
    # Destination is a file
    Rez -append $rsrc -o $iconDestination
elif [ -d $iconDestination ]; then
    # Destination is a directory
    # Create the magical Icon\r file
    touch $iconDestination/$'Icon\r'
    Rez -append $rsrc -o $iconDestination/Icon?
    SetFile -a V $iconDestination/Icon?
fi

# Sometimes Finder needs to be reactivated
#osascript -e 'tell application "Finder" to quit'
#osascript -e 'delay 2'
#osascript -e 'tell application "Finder" to activate'

rm $rsrc $icon 
ijoseph
  • 6,505
  • 4
  • 26
  • 26
Gregory Vincic
  • 304
  • 3
  • 8
  • Just tried this on MLion and got ### Rez - SysError -37 during create of "../https-::www.pivotaltracker.com:dashboard.webloc". ### Rez - Fatal error trying to open the resource file "../https-::www.pivotaltracker.com:dashboard.webloc" for writing. – ort11 Mar 18 '13 at 14:59
  • Thanks for this. Your script worked for me when my iconSource was an .icns file as well. – bryan kennedy Dec 03 '14 at 21:05
  • 2
    Rez and SetFile are marked deprecated in their man pages. Is there a non deprecated way of doing this? – Johannes Bittner Jan 29 '19 at 04:55
  • 1
    I have not found a non-deprecated way of doing this. But fwiw, Rez and SetFile are still present now in 2022, in macOS 12.3. I'll keep going with this method for now. – magicus Mar 04 '22 at 16:18
  • Still works fine on macOS 13.0 – ijoseph Feb 10 '23 at 03:44
  • I chased my tail for a while today, trying to get the magic Icon\r file working from shell script. The light bulb finally went off when I realized that the notation usually used for specifying the file name in this case is actually [ANSI-C Quoting](https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html). But, it works differently in scripts vs. the command line. In scripts, you cannot do `Icon$'\r'`, for instance. You have to specify it as `$'Icon\r'`. And, no amount of quoting or escaping will make bash/zsh happy. – MushyMiddle Apr 06 '23 at 20:26
2

Assuming that we have icns-file already. Create temp resource file which points to icns-file:

$ echo "read 'icns' (-16455) \"Icon.icns\";" >> Icon.rsrc

Append the resource file as value of extended attribute "com.apple.ResourceFork" to a file:

$ Rez -a Icon.rsrc -o FileName.ext

Show the icon of the file:

$ SetFile -a C FileName.ext

Append resource file as value of extended attribute "com.apple.ResourceFork" to a magic icon file inside current folder:

$ Rez -a Icon.rsrc -o Icon$'\r'

Show the icon of current folder:

$ SetFile -a C .

Hide the magic icon file inside current folder (press ⇧⌘. to show/hide hidden files in Finder):

$ SetFile -a V Icon$'\r'

Additional details

Icon data is stored as value of extended attribute "com.apple.ResourceFork" (Terminal command "xattr -p com.apple.ResourceFork FileName.ext" prints the value). For a folder there is magic (which is empty and hidden) file Icon$'\r' inside the folder. To extract icon data from extended attribute "com.apple.ResourceFork" into plain text resource file (from which we know correct icns-type identifier "-16455"):

$ DeRez -only icns FileWithIcon.ext > Icon.rsrc
$ DeRez -only icns /Folder/With/Icon/Icon$'\r' > Icon.rsrc

Under macOS 10.13 High Sierra command $ sips -i ImageFile.icns/png/jpg generates error --addIcon is no longer supported. Switch -i means "--addIcon" as extended attribute "com.apple.ResourceFork" onto this file itself using the content of this image file.