05401, 05403, 05446, 05462, 05482, 05673, 05701, 37signals, 40hz, 2008, 2010, aardman animations, ac propulsion, adium, ads, aim, airport, al franken, algorithm, amazon, animation, apache, apple, applescript, architecture, archive, art, article id, asterisk, at&t, atom, automobile, away message, backpack, badge, barack obama, basecamp, bash, beos, bernie sanders, bicycling, billboard, blacklisting, blog, blogroll, blogzot, bluetooth, blunt, bluray, book, bookmarklet, bot-net, brad bird, browser, btv, bug, build, bungie, bunny, burlington, call of duty, camera, camping, can-spam, cars, centralized, channel camp, chocolate, classic, classic mac workshop, clothing, cms, collection, color classic, comedy, comedy central, comic, computer, concert, conversion, cookbook, corrosion, cowards way out, crack, crashing, creature comforts, criticism, daring fireball, darwin, dashboard, david byrne, dcl, death, delicious, derbi, design, development, digg, dilemma, discussion, disney, domain, download, drivers, dvd, dynetk, e-mail, e3, easter, ebox, eckhart, eckhart köppen, eckhart koppen, eddie izzard, edward gorey, einstein, election, electric motorcycle, electric motorsport, electric vehicle, electronics research laboratory, elmo, emate, emulator, encryption, environment, environmental impact, erin mckeown, escale, exploit, express 530t, expressionengine, feature, feed, feedburner, filtering, finance, firmware, fixdavsvn, flickr, flynn center, focus, font, food, ford, for sale, free, freeverse, freezing, fresh air, frog design, front row, fusion, games, gears of war, geek, geek technique, geocities, gmail, google, gpr, grammar, grant hutchinson, graylisting, gtd, hack, haiku, halo, hayao miyazaki, health, higher ground, highrise, hiking, hiroshi noguchi, history, hope, hotspot, html, html5, hulu, humor, hybrid, hybrid technologies, hypercard, intel, internet, interview, ipad, iphone, ipod touch, isao takahata, itunes, jabber, japan, javascript, jetblue, jfk, john gruber, john oliver, jon stewart, kid koala, launchd, layover, leopard, liberal, long trail, lorem ipsum, mac, macbook pro, macworld, maczot, magazine, mail, maine, makkintosshu, marathon, marketing, mark hoekstra, matthias melcher, media, mesagepad, messagepad, microbus, microsoft, mobileme, model s, modern warfare, money, monitoring, moon river, motorola, movie, movies, mrtg, multitasking, music, mwsf07, mystic, nascar, ncx, nda, netflix, network, newton, newton os, newton press, newtontalk, newton x press, nick park, nitch, npr, on point, openpbx, open source, operation ivy, optimization, organic, os 8, os9, osheaga, osx, os x, owc, package, palm, password, paul guyot, pbx, pdf, pesticides, photography, pico card, pilot, pixar, playstation, plist, plug-in, pod jungle, politics, productivity, ps3, psp, pump-and-dump, quicksilver, racism, rack-n-roll, radio, ratatouille, rebooting, recycling, remake, required reading, restoration, retrochallenge, review, roadster, room without a window, rss, scion, screencast, script, search, security, server, sesame street, seven days, shame, shelburne, shelburne museum, shirt, shoppinging cart, simon bell, small dog electronics, snow leopard, social, software, solution, sony, spam, spam haus, startup item, statistics, status, stefano paris, stephen colbert, steve jobs, steven colbert, steven frank, studio 360, studio ghibli, subethaedit, subversion, swiss, sync, syndication, sysmon, tablet, tags, tax, technorati, ted talk, television, terry gross, tesla motors, textpattern, the colbert report, the daily show, the flaming lips, the gashleycrumb tinies, the radiator, the world, times argus, titles, tkip, todd kollins, tom gage, trailer, travel, tree, trends, troubleshooting, twitter, typography, tzero, unicel, unna, update, upgrade, url title, user interface, v710, venue, verizon wireless, vermont, victor rehorst, video, virtualization, vmware, volkswagen, volvo 122, vpr, vw, wait wait don't tell me, wall-e, wallace & gromit, wavelan, web, web 2.0, webkit, web site, whitepaper, wifi, wikipedia, windows, winter warm-up, wireless, wpa, writing, wwdc, wwnc, xbox 360, xbox live, xhtml, yahoo, ze frank, zero emission
Articles Tagged "bash":
Automating Countdown Tweets with Bash ¬
2009-11-02
Modern Warfare 2 will be out in a few days, so I felt @cowardswayout should count down to the release day. I could spend a few minutes at some point during each of the next few days—assuming I can remember to—posting a nearly-the-same message to Twitter or I could automate it. Yeah, better automate.
In trying to keep my bash-fu hightened, I tossed together the following bash script:
#!/bin/bash# # mw2_countdown # # Post countdown to Modern Warfare 2 release to Twitter every day #release_year=2009 release_month=11 release_day=10 year=10#$(date +%Y) month=10#$(date +%m) day=10#$(date +%d) username='cowardswayout' password='somethingiwontleakhere'if (( $release_year == $year && $release_month == $month && $day <= $release_day )); then if (( $day == $release_day )); then printf -v message "Modern Warfare 2 (http://bit.ly/dQMPz) is out! Go get your copy!" else printf -v message "Modern Warfare 2 (http://bit.ly/dQMPz) in %s..." $(( $release_day - $day )) fi curl -u $username:$password -d status="$message" http://twitter.com/statuses/update.xml fi
Since I host with Mac OS X Server and am anal about doing things “The Mac Way”, I whipped up a launchd job to run it every morning at 1am:
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.cowardswayout.mw2_countdown</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/mw2_countdown</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>1</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
As you can see, I installed the bash script in /usr/local/bin/mw2_countdown and the launchd job went in /Library/LaunchDaemons/com.cowardswayout.mw2_countdown.plist.
I changed the permissions so that only root has read/execute access to the bash script, since the Twitter account password is stored in plain text:
sudo chmod 700 /usr/local/bin/mw2_countdown
And loaded the launchd job:
sudo launchctl load /Library/LaunchDaemons/com.cowardswayout.mw2_countdown.plist
Now I only have to remember to remove the bash script and launchd job sometime after 11/10/09. Naturally, this script can be easily tailored to your own needs.
Update: I’ve updated the script to prepend 10# to each call like $(date +%y) to force it to be evaluated as base 10 and also switched from using test (square brackets) to using the correct arithmetic evaluations (double parentheses).
fixDAVsvn ¬
2009-03-07
Subversion, mod_dav, and mod_dav_svn are all pre-installed on Leopard Server, authentication via Open Directory is a piece of cake, and you can even mostly config & manage via Server Admin. Nayan Hajratwala has a good tutorial explaining the setup and the few lines you have to manually add to the apache config files, but there’s one problem: whenever you update any site using Server Admin, it replaces all occurrences of ‘DAV svn’ with ‘DAV Off’, completely defeating the purpose.
When I just had just a couple of Subversion repositories and wasn’t changing my apache configs very frequently it was fine to manually switch ‘DAV Off’ back to ‘DAV svn’ and restart apache, but recently I’ve exceeded my tolerance. So, this morning I whipped up the following bash script which accepts the names of config files that’ll need to be fixed, performs the substitution, and restarts apache:
#!/bin/bash# # fixDAVsvn - Replace occurrences of 'DAV Off' in specified apache2 configs with # 'DAV svn' and restart apache. This helps do some dirty work on Mac # OS X Server when using Server Admin to modify apache configs if # you use DAV svn anywhere. # # v0.1 - 2009-03-07 - Morgan Aldridge <morgant@makkintosshu.com> # Initial development. #date=`date "+%Y-%m-%d-%H%M"`function usage() { printf "Usage: fixDAVsvn file [...]\n" }if [ $# -gt 0 ]; then until [ -z "$1" ]; do src=$1 dst=$src-$date.bak rsync -a $src $dst # back up the original file cat $dst | sed 's/DAV Off/DAV svn/g' > $src # replace 'DAV Off' w/'DAV svn' shift done/usr/sbin/apachectl restart # reload the apache configs else usage fi
I’d suggest installing it into /usr/local/bin/.
Example usage:
sudo fixDAVsvn /etc/apache2/sites/0003_any_80_svn.domain.tld.conf
Let me know if you find this useful.
Update: I’ve since released a launchd job which automates the process of running fixDAVsvn when the apache config files are modified (esp. by Server Admin).
Automatic Delicious Backups Under Leopard ¬
2009-01-26
I’ve been using delicious.com, nee del.icio.us, for my bookmarks on and off since early 2006, but only recently have I decided to really keep all my bookmarks there. Yahoo!‘s future has been somewhat questionable as of late and I’m not entirely sure I like the idea of not having my data backed up in a place where I can get at if the service goes down. I don’t really have control over the former, but the latter I do.
Delicious has a tool to export your bookmarks that gives you an HTML bookmark file for easy importing into a browser, but, alas, it’s not really scriptable. However, they do offer a way to dump all your bookmarks to xml using their API.
So, I whipped up the following bash script to perform the backup and tossed it in ~/bin/deliciousBackup:
#!/bin/bash# # deliciousBackup - delicious.com bookmarks backup # # See: http://delicious.com/help/api#posts_all # # v0.1 2009-01-25 - Morgan Aldridge <morgant@makkintosshu.com> # Initial version. #user='<username>' pass='<password>' date=`date "+%Y-%m-%d"` src='https://api.del.icio.us/v1/posts/all' dst='Users/<username>/Documents/Backups'curl -s --user $user:$pass $src | bzip2 > $dst/delicious.com-$user-$date.xml.bz2
I needed to make deliciousBackup executable, but also wanted to make sure it wasn’t readable by any other user/group since it contains my password in plain text:
chmod 700 ~/bin/deliciousBackup
Of course, if someone ever had direct access to my hard drive they could still pull my Delicious password from that file, so consider yourself warned.
I prefer to run most of my backup scripts and such using launchd instead of cron since it follows my home folder sync better, so I tossed the following .plist in ~/Library/LaunchAgents/com.makkintosshu.deliciousBackup-morgant.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
<key>Label</key>
<string><tld>.<domain>.delciousBackup-<user></string>
<key>ProgramArguments</key>
<array>
<string>/Users/<user>/bin/deliciousBackup</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>12</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
The following call loaded my LaunchAgent without a logout:
launchctl load ~/Library/LaunchAgents/com.makkintosshu.deliciousBackup-morgant.plist
You’ll note that the LaunchAgent runs every day at noon. That’s because I currently run this on my MacBook Air which may not be online most nights, but is usually online by mid-day.
Feel free to use this method if you’re so inclined.
Testing the OS Version on Darwin/Mac OS X in bash ¬
2008-08-14
I’ve been updating an installer bash script that needs to install different files depending on the version of Mac OS X (and Darwin, for that matter) that the machine is running and so set out to find the easiest, most straightforward way to check the OS version.
Of course, the hostinfo command shows you most of the juicy details one would need, but it’s not worth trying to parse it. sysctl lets you query various kernel states, including the OS release version:
sysctl -n kern.osrelease
Which will spit back something like the following (on Mac OS X 10.5.4, in this example):
9.4.0
This is the Darwin release number. To convert a darwin release version number to a Mac OS X version number just subtract 4 from the major revision (9, in this case) and then prepend the ’10.’ to the entire thing. So, 9.4.0 becomes 10.5.4.0.
You can also use uname -r to get the OS release version, but I’m going to stick with sysctl for now.
Of course, you can’t do a direct comparison, so you’ll want to compare either the major or the minor revision (the last release field is always zero, so it can be ignored). The easiest way to do that is to pipe the output from sysctl through the cut command.
The following will give you the major release number (again, 9, in this case):
sysctl -n kern.osrelease | cut -d . -f 1
It cuts the output of sysctl on the ‘.’ delimiter and returns the first field. We can return the second field (the minor revision; 4, in our example) like so:
sysctl -n kern.osrelease | cut -d . -f 2
In my script, I simply needed to test if the machine was running Tiger or earlier, or Leopard or newer. Here’s a quick example of getting that functionality:
#!/bin/bash
if [ `sysctl -n kern.osrelease | cut -d . -f 1` -lt 9 ]; then
echo "Tiger or earlier"
else
echo "Leopard or newer"
fi
If you’re doing something more advanced, it might be easier to set variables first:
darwinos_major=`sysctl -n kern.osrelease | cut -d . -f 1`
darwinos_minor=`sysctl -n kern.osrelease | cut -d . -f 2`
Then just reference $darwinos_major & $darwinos_minor whenever needed.

