Archive for the ‘ramblings’ Category

python subprocess over shell

Monday, May 10th, 2010

One of my common gripes is when people struggle with complicated shell scripts that would be much simpler in a scripting language like Python, Ruby or Perl. I used to abuse PHP for this, but saw the light.

If you’re talking about replacing shell scripts, all of these are pretty much equivalent, but I don’t really do Perl for no particular reason, I’m a big fan of Python for general purpose work just because of the rich module system, and at least “dozens of engineers” use it at work..

The reason we generally write shell scripts is because we want to execute a bunch of external processes in an automated way.

In this area you can whip something basic up fastest in shell, yes, but at some point you’re going to have to repay that technical debt if you need to get past a certain point.

Besides, it’s not like shell scripting always stays simple and easy… and the overhead of moving to a more powerful language isn’t that huge.

If I’m sure the scope of a script will be small, or I don’t have the option of moving to structured data format for input and output with external commands, or I don’t have to futz around with arrays, I’ll stick with bash.

But, if I want to work with dictionary objects or talk in a protocol like LDAP or model things as objects, or need complex handling and passing around of stdin/stdout/exit statuses, or know some module handles lots of edge cases for me, I’ll move to Python or Ruby. I quite like both, but feel that Python is more utilitarian, and simply due to whitespace enforcement and extensive linters is a good fit for code that may need to be picked up and understood quickly by a co-worker.

When it comes to getting started with Python, I still suggest Dive into Python for people. Just flipping through Chapters 1-3 equips you with an awful lot.

Anyway, some people think Python is hard, but it’s not really. I think of Python as being extremely utilitarian, which makes it a great fit for sysadmin work.

Someone posted on the MacEnterprise list a question about working out what PPD was in use by each printer on the system in OS X, and someone gave a good shell example using the usual suspects of for, grep and awk.

There’s nothing really wrong with doing this, but I’ve come to distrust parsing non-structured output if I need to keep this solution working across many multiple versions of operating systems, or even between OS X major versions given Apple’s history. One of the big advantages of moving to Python is being able to parse and manipulate property lists, which can get really painful in shell. You end up writing out lots of temp files or giving up on dealing with error conditions.

Anyway, so lets see what it’s like executing a command in Python with the subprocess module. We’re asking System Profiler for printer info, and telling it to return the output in XML plist format.

#!/usr/bin/python

import subprocess

command = [‘system_profiler’, ‘-xml’, ‘SPPrintersDataType’]
task = subprocess.Popen(command,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)

(stdout, stderr) = task.communicate()
print stdout

To skim through those lines, we’re

  • setting the python shebang
  • importing the subprocess module
  • defining a list called ‘command’ to store the command we want to run
  • creating a subprocess Popen object to run our command called ‘task’
  • setting standard out and standard error to go to our own pipes
  • getting standard out and standard error from the task.
  • printing standard out

This really isn’t much work, and if you really only wanted this functionality, there are other convenience functions that you can use to make this even shorter, or write your own convenience function.

But we have all sorts of options now.

We can send standard input to the task:

(stdout, stderr) = task.communicate(stdin)

We can ask what the exit status is easily:

status = task.returncode

and if we get None we know the process hasn’t terminated yet.

And if we want to do something a bit more complicated we can search through the structured data plist output easily like:

#!/usr/bin/python

import plistlib
import subprocess

command = [‘system_profiler’, ‘-xml’, ‘SPPrintersDataType’]
task = subprocess.Popen(command,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)

(stdout, stderr) = task.communicate()
printers = plistlib.readPlistFromString(stdout)
printers = printers[0][‘_items’]

for printer in printers:
  print ‘Name: ‘ + printer[‘_name’]
  print ‘PPD: ‘ + printer[‘ppd’]
 

This is easier to extend than the standard for/grep/awk/sed equivalents tend to be, and much easier for a co-worker to pick up and understand. It comes close to documenting itself, just needs some comments about the structure of Apple’s output, and some try/except blocks in case the output is malformed or does change.

MacPort issue when using patch…

Sunday, March 23rd, 2008

After spending a little while banging my head against the wall over this one….

root@snicko [ ~ ]
# port install git-core +svn +bash_completion
---> Applying patches to perl5.8
Error: Target org.macports.patch returned: shell command " cd "/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_lang_perl5.8/work/perl-5.8.8" && patch -p0 < '/opt/local/var/macports/sources/rsync.macports.org/release/ports/lang/perl5.8/files/patch-makedepend.SH'" returned error 2
Command output: Get file makedepend.SH from Perforce with lock? [y]
Perforce client error:
Connect to server failed; check $P4PORT.
TCP connect to perforce failed.
perforce: host unknown.
patch: **** Can't get file makedepend.SH from Perforce

Error: The following dependencies failed to build: p5-error perl5.8 p5-libwww-perl p5-compress-zlib p5-compress-raw-zlib p5-io-compress-base p5-scalar-list-utils p5-io-compress-zlib p5-html-parser p5-html-tagset p5-uri p5-svn-simple subversion-perlbindings apr apr-util db44 sqlite3 gawk gmake readline neon subversion bash-completion p5-term-readkey rsync popt
Error: Status 1 encountered during processing.

I finally found Jack Palevich's post talking about exporting the POSIXLY_CORRECT environment variable as follows.


POSIXLY_CORRECT=1 port install git-core +svn +bash_completion

Of course now I’ve run into an issue with tcl…. *sigh*, but I’ve seen the patch issue above crop up a few times, and this certainly seems to be fixing it.

It’s bad enough that MacPorts and Fink can’t depend upon Apple to provide sane libraries and headers in OS X, and thus you end up with most of another whole freaking operating system in /opt/local or /sw, but I simply refuse to have both installed, no matter how frustrating it is that I can’t get all the software I need working via just one of them.

My first earthquake….

Thursday, November 1st, 2007

So last night I experienced my first earthquake ever….

Considering it was a 5.6 and quite close to our house, I’m a little disappointed now that it wasn’t more dramatic… nothing even fell off the shelves. Just several huge thumps that felt like something dropped from a great height into the backyard.

Not to give any impression I didn’t freak out … On the other hand, Chantal having grown up in Tokyo was calm and collected.

I see Bill Baumgarter felt it too...

E-3 Visa Experience…

Thursday, March 22nd, 2007

So after finding Andrew Pollock’s blog entry and Yasser Hamed’s info incredibly useful, I thought I may as well post some updates on a slightly more recent E-3 visa application experience.

For those of you who don’t know, the E-3 visa is a US visa that is only open to Australian residents. It’s essentially the same as the H-1B visa, apart from the fact that your spouse can also work in the US, it’s indefinitely renewable, and so far at least, you can’t apply for the green card while in the US on an E-3.

There’s a nice summary available on the Sydney US Consulate site. Things may be different with other companies, but Google seem to be rather familiar with the whole process and pretty much organised everything I needed. The two things that seem mandatory for the company sponsoring you to provide are a statement in support of your application and a Labor Condition Application approved by the US Dept of Labor, which is normally used for the H-1B applications. It looks like the bureaucracy has caught up with the existence of the E-3 now and it’s actually an option on the form, so you no longer need the company to scrawl E-3 across the top of it.

(more…)

Leaving Sydney… moving to the USA

Monday, January 29th, 2007

So some of the people I know who read this already know… but it looks like I’ll be moving the family over to Silicon Valley in the next couple of months.

I’ve accepted a position at Google HQ in Mountain View (huzzah!) doing Mac/Linux sysadmin stuff, which means several things…

We’re finally getting married tomorrow, as we’ll be doing it on an E-3 visa, and the US doesn’t recognize de facto/common law relationships… I think our daughter is the most excited person involved… :) The process doesn’t look too bad, and luckily Andrew Pollock has put up some useful info about his experiences going through the same situation. I’ll add some more posts here if anything has changed…

We’re not doing much of a ceremony, but we’ll combine something with our farewell party here in Sydney before we leave.

We’ll also be looking for someone to replace my current position as Senior Technical Officer at the College of Fine Arts, UNSW here in Sydney, Australia. Here’s the post I sent to macos-x-server@lists.apple.com about it. Please contact me if you think you might be interested…

This probably means I’ll be a bit light on technical articles for this blog and afp548.com for a while, but hopefully that won’t be a permanent state of affairs…

I’m not sure we can afford to live in Mountain View itself, and at this stage it looks like we might be looking around Sunnyvale, Santa Clara or San Jose. Useful suggestions for an ex-pat moving to the US and looking for housing would be much appreciated… :) Someone pointed me to housingmaps.com which is rather cool, but it doesn’t seem like the local newspapers have sites like domain.com.au and realestate.com.au from poking around…

Heading to MacWorld…

Friday, December 22nd, 2006

Just as a quick note…

After spending four (maybe five if England can hold out that long) glorious days watching Shane Warne’s last Test match at the SCG, I’ll be flying straight out to San Francisco to do some presentations at MacWorld.

It’s always good to put faces to names, so if you’re around make sure to say hi, and even more importantly, make sure you make it to the AFP548 Kick-Off Session at Macworld.

We can play the drinking game every time Joel’s voice does that squeaky Jay Leno thing… :)

Typos can be fatal…

Wednesday, October 18th, 2006

So last night I was playing around with the MBR on an external drive… and completely without thinking managed to wipe out my laptop.

/dev/rdisk1 Nigel, not /dev/rdisk0 ….

bleagh.

Anyway, it’s made me realise just how much I love HomeSync, as 95% of everything that matters has been syncing up to the server… and as I’ve had two requests now for a post on Mobile Accounts and HomeSync best practices, this is as good a time as any… working on it now while watching OS X and Win XP reinstall….

Welcome to the new blog…

Monday, September 18th, 2006

So here’s the new blog… I finally bit the bullet and bought some hosting space… and man, things have changed in the 9 or so years since I last did this… The prices are insanely low for what you get… and everyone has these beautiful cPanel/Fantastico style auto-installers.

Off to WWDC 2006…

Friday, August 4th, 2006

Drinking my coffee, mentally double-checking that I’ve packed everything…

Oh no, 13 and a half hours on the plane means that long without decent coffee. ugh

So it’s that time of year again… I’d love to chat to anyone in person who actually reads this blog, I’m still not entirely convinced that awstats isn’t just making up all these web statistics… :)

I’ll be at the MacEnterprise event on Sunday night (and probably the Australia/New Zealand meetup as well), and will be at the afp548.com event on Tuesday night. I’ll be putting on my best tough Australian guy act as the door guy from 9:45 to 10:20, so please come up and say hi!