How to persistently set the priority of an app in Mac OS X

The question at superuser.com sounds a bit differently from what I chose for my post. It's: "How do I pass command line arguments to Dock items?". However the point is the same: how to launch an app with a commandline that is a bit different from what the app's developers had in mind.

As the author of the most popular answer to that question outlined: you either create a wrapper app (that you can put into Dock, click on/launch, etc.) which will start the target app with the parameters that you like ... or you can modify the original app. Neither of the two approaches is ideal. The first one will result in two application icons in your Dock (one for the wrapper and one for the target app), the second means you've to reapply your changes whenever the app updates itself (which most apps do from time to time).

A third option is available but only in my special case. I want to launch an app with a specific "nice" value (ie. CPU priority). Activity Monitor (the "Task Manager" of Mac OS X) does not reveal the process priorities that can be assigned to any process by the user. However the commands to do this (nice and renice ... and to check the priorities you can use ps with the proper -o ...,nice,... switches) are still there.

So to launch an app with a lower priority, you can try this from the commandline:
nice -n 18 /Applications/Calculator.app/Contents/MacOS/Calculator

To check the result, use this (the "nice" column contains the process priority ... the higher the number, the lower the priority):
ps -A -o pid,nice,command

So the two approaches from the superuser.com post would be:
  • Create an Automator app that launches a shell script that starts with nice -n 18 /Applications/...
  • Create a wrapper shellscript (that launches the target app via nice) in the app's directory and modify the app's Info.plist to start the shellscript instead of the app's executable.
The third option comes from the renice command: we can create a cronjob that modifies the priority of an already running application. Obviously putting this into a cronjob is serious overkill, but it's still better than to have a continuously running daemon process that does the same (which would be the only other alternative if we want to avoid the problems from the first to approaches).

I've attached a sample shellscript which demonstrates this method. It lowers the priority of the uTorrent app (if it's running) and raises the priority of MPlayer OS X Extended (if it's running and the script is executed by root). To raise the priority of an app, you've to be root (the superuser of your Mac OS X system). To use the script, save it somewhere on your disk (eg. /Users/myuser/mac_os_x_process_scheduler.sh) and launch echo "* * * * * /Users/myuser/mac_os_x_process_scheduler.sh" | sudo crontab - to set up a cronjob executed by root every minute. Since the execution of the script takes only a split of a second, it won't seriously affect your system's performance ... not even if executed every 60 seconds. But of course it's up to you. The execution could be scheduled for every 10 minutes, but obviously it'd take that much longer to take effect on already running apps.

AttachmentSize
mac_os_x_process_scheduler.sh865 bytes