OS X Tricks

The information below has been gathered over the years from various sources, mostly other people’s blogs. There’s really nothing new here, but I have found them so helpful on so many occasions that I thought I should re-share them with the world. If you have any other helpful OS X tips or tricks, please feel free to share them in the comments.

Finding Files With Find

To find all files in the current directory or any sub-directories that was modified within the last hour:

find . -mtime -1h

To find all files on the file system modified more than one day ago:

find / -mtime +1

(The default unit of time is days.)

Here is one example of using find - with the exec option to run some utility on each file:

find . -name "*.zip" -exec unzip {} \;

Actually, the example above isn’t that good, because the -exec option is really meant as a way to run a utility that will execute some kind of test on the file and return true or false, which is an indicator to the find command about whether or not that file should be included in the result set. Strictly speaking the test should not really manipulate the file and doing so is really a side effect.

The correct way to do the above unzip function would be as follows (the 0 is a zero):

find . -name "*.zip" -print0 | xargs -0 unzip

To delete all files within a directory structure that match a certain pattern, use this:

find . -name "._*" -delete

Or, using xargs:

find . -name "._*" | xargs rm {}

Note that the example above was required on a Debian box to remove the attribute files that got extracted from a tar file created on a Mac. OS X stores additional file information in extended attributes that (A) aren’t very well documented and (B) annoying, because they result in all sorts of junky files being created on non-Mac volumes and (C) hard to get rid of. Mostly these are used to store the origin of a file (eg. some web site, Time Machine backup, etc) and whether or not you have approved the viewing of that file.

To view extended attributes, use:

ls -l@

Thankfully, someone wrote a small script that will clean the attributes off every file in the current directory and below:

for i in $(ls -Rl@ | grep ’^	’ | awk '{print $1}' | sort -u); \
   do echo echo Removing $i ... >&2;  \
   find . | xargs xattr -d $i 2>/dev/null ; done

The space after the caret is a tab, created by typing Control-V then pressing tab in vi.

Following on from the previous example, we can use a similar loop to power a grep command. This command creates a script that looks for occurrences of each string in the file ../blah.txt in all folders in the current folder:

for i in $(cat ../blah.txt ); do echo echo Processing $i...; grep -l $i *; done

If you are trying to find out which files a particular system function or application is modifying, a simple (albeit imperfect) solution is to create a timestamp file and then use the find command to list all files modified since that the timestamp:

cd ~
sudo -s
touch now
# At this point you carry out the function you are testing
find -x / -newer timestamp

Improving Finder

To prevent Finder (and some other internal processes) from creating .DS_Store files on network shares, issue the following command:


defaults write com.apple.desktopservices DSDontWriteNetworkStores true
killall Finder

To add the current folder to the title bar of a Finder window:

defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
killall Finder

The above command is particularly useful because the additional information occupies an otherwise empty part of the window. Hence you get additional information without the window requiring more space.

To make Tweetbot show the actual URLs embedded in Tweets rather than the t.co URL:

defaults write com.tapbots.TweetbotMac OpenURLsDirectly YES

Other Cool Stuff

Unfortunately there is no “pause” command in OS X, but this will work just as well:

read -p "Press any key to continue..."

To run a command on OS X and have the output redirected to a process on another machine (via SSH), do something like this:

tar czf - somedir | ssh james@kong "cat > incoming.tgz"

Even cooler: to re-start an aborted SCP transfer on a non-standard port using rsync:

rsync --partial --progress -e 'ssh -p PORT' user@host:/remotesrcfilename localdestfilename

The above was tested on Snow Leopard to complete an aborted transfer from Snow Leopard Server.

To manually add an SSH key with a passphrase to the Keychain:

ssh-add -K .ssh/id_rsa

To create a RAM disk:

diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://4629672`;ln -s /Volumes/ramdisk ~/ram

To remove the disk (assuming its the only one you’ve created):

hdiutil detach /dev/disk1

This will probably work on Linux too, but this tip landed in here because I used it to copy a Time Machine backup folder, which includes loads of symbolic links, to another hard drive. The problem is that the cp command doesn’t copy links, it copies the files they point to. Given the clever way in which Time Machine saves files (ie. if a file hasn’t changed since the previous backup it simply writes a symbolic link instead of another copy of the file), using cp to copy a backup database would require about 10 times as much space as the original file system.

So the solution is to use the tar command, but, of course, you want to try and avoid creating an intermediate tar file if at all possible. So piping the stream from one tar process to another does the trick. The syntax that I used to duplicate a Time Machine backup folder was as follows:

cd destination_folder

tar cp /Volumes/Time Machine Backup/Backups.backupdb/machine_name | tar xvf -

The reason you need to change to the destination folder is because the second tar process will proceed to untar its input immediately.

When setting up a new Mac Mini Server, you may want to reconfigure the two drives to create a RAID-1 array (mirrored drives).

The way to do this is:

  1. Start the remote install application on another Mac
  2. Boot up whilst holding down the Option key
  3. Choose to boot up off the remote disk
  4. Once it has booted up (and this takes a while) start a terminal prompt and issue the commands provided here: http://blog.scottlowe.org/2010/07/17/enabling-raid-1-on-a-mac-mini-server/
  5. This might NOT actually result in the mirror being rebuilt, so after you’ve rebooted and gone through the set-up process, remember to go into Disk Utility and check the status of the array.

Macports Stuff

To update Macports:

sudo port selfupdate

Then:

sudo port upgrade outdated

To see installed ports:

port installed

To remove inactive ports:

sudo port uninstall inactive

To view unused dependencies:

port echo leaves

To remove unused dependencies:

sudo port uninstall leaves

To see the variants for a port:

port variants ffmpeg

To add a variant to an already installed port:

port install ffmpeg +nonfree

Yet Another Programming Blog

Where James Gordon rambles about PHP and web development in general.

Find me on Twitter Find me on Stack Exchange Find me on Github Subscribe