Wednesday, April 11, 2012

Calling Mail from command line - What works and doesn't

I had some trouble recently calling /bin/mail with -s for subject, quoting the actual subject in single or double quotes, and passing in the destination addresses in a shell / environment variable. So, here's the truth table of what works and what doesn't.
# Explanation of what works and doesn't when calling mail with various params:

#[krice@test1 krice]$ EMDEST="Kevin@justanyone.com"
#[krice@test1 krice]$ ps | mail -s 1132 $EMDEST          OK
#[krice@test1 krice]$ ps | mail -s 1132A "$EMDEST"       OK
#[krice@test1 krice]$ ps | mail -s "1132B" "$EMDEST"     OK
#[krice@test1 krice]$ ps | mail -s "1132C" '$EMDEST'     BAD
#[krice@test1 krice]$ EMDEST="Kevin\@justanyone.COM"
#[krice@test1 krice]$ ps | mail -s "1132D" '$EMDEST'     BAD
#[krice@test1 krice]$ ps | mail -s "1132E" $EMDEST       BAD
#[krice@test1 krice]$ EMDEST="Kevin@justanyone.COM"
#[krice@test1 krice]$ ps | mail -s "1132F" $EMDEST       OK

Thursday, April 05, 2012

How to Pretty Print json.dumps() with indent, compactly

I'm working in Python and trying to pretty print some JSON objects. The trouble is, they print all weird. Indentation really messes up with TOO MANY LINES of data, one number per line. In other words, when I do this:
out = json.dumps(tfarray, sort_keys = True, indent = 2)
the indent=2 line causes each array element (in my case, a number) to be printed on its own line. This sucks and takes lots of space. Here's my program to pretty print the json.dumps result into something nicer:
#!/usr/bin/python
import re
instr = """    
       {
          "abbbb": 52,
          "acccc": 32220,
          "asdfasdfasfd": 32220,
          "asdfasdf": [
            0,
            1,
            2,
            3
            ],
          "somethingElse": 13,
          "asdfasdfasfd": [
            10,
            11,
            12,
            13
            ],
        }
"""
y = re.sub(r'\s\s+(\d+)', lambda match: r' {}'.format(match.group(1), instr), instr)
print "Y=%s" % (y)
the instr is the input string as pretty printed. The same sort of thing happens when I call pprint() or pformat() on a complex data structure - the result is hard to read. With the above re:sub, I get:
[krice@loadtest1 HD]$ python test_resub.py
Y=
       {
          "abbbb": 52,
          "acccc": 32220,
          "asdfasdfasfd": 32220,
          "asdfasdf": [ 0, 1, 2, 3
            ],
          "somethingElse": 13,
          "asdfasdfasfd": [ 10, 11, 12, 13
            ],
        }
Lots nicer, eh? Certainly more compact. Hurray for re.sub regex substitutions and lambda functions.