Wednesday, July 10, 2013

Execute complex Python or Ruby code inline within Bash

A lot of times when we write extensive shell code, using pipes, file descriptors etc, we eventually run into the limitations of shell and are forced to write an external helper to keep the whole pipe ninja thing moving forward. Well, what if I said you didn't have to?

Update: cannot be used with set -e

read -r -d '' VAR <<'EOF'
import sys,re
state = sys.stdin.read().rstrip('\n')
g = re.match('^([\w-]+)(\s[\w+\/]+)(, \w+ \d+)?',state).groups()
# if the last field exists, it's running
if g[-1] is not None:
  print 'running'
else:
  print 'stopped'
EOF

Upstart does lots of things right, except status, I mean...


tty2 start/running, process 738
udevtrigger stop/waiting
That's just not right, requiring a regular expression to get status. So I created this little snippet. read takes the heredoc and shoves it into VAR and then, it's no different than it having been in a file to begin with.

# initctl list
...

tty3 start/running, process 740
udev-finish stop/waiting
juju-daq-emitter-0 start/running, process 12022
hostname stop/waiting
mountall-reboot stop/waiting
mountall-shell stop/waiting
mounted-tmp stop/waiting



root@ip-10-147-220-141:~# initctl status tty3 | python -c "$VAR"
running
root@ip-10-147-220-141:~# initctl status udev-finish | python -c "$VAR"
stopped
root@ip-10-147-220-141:~# initctl status hostname | python -c "$VAR"
stopped
Much better.