Tag: bash

  • Shell Nuggets: Quickie Tabulizer

    I’m real bad about things lining up.  Used to go out of my way to ensure variable declarations were columnized by access mode, type, name, equals sign and initial value.

    final BufferedImage mapImg = MapImageFactory.newInstance(width, height);
    final int           count  = ad.getPosition() * 2;
    
    mapImg.composite(adImg, 25               , (this.adHeight + 20) * count + 20, Over);
    mapImg.composite(adTxt, 25 + this.adWidth, (this.adHeight + 20) * count + 20, Over);
    

    The Tabularizer plugin for vim was a boon for productivity.  Well, mine.  For everyone else, it meant either destroying the pre-formatted beauty or re-aligning all the columns.

    Anyway, it’s considered bad practice, so I’ve tried to get away from it– at least when writing shared code.  I still like perfect tabular output in my day-to-day.  Take the df command, for example.  It’s default “human readable sizes” output:

    2016-02-05 11:03:57 «««« ~
     rons@rons-VM$ df -h
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/mapper/VolGroup00-LogVol00
                           59G   29G   27G  52% /
    /dev/sda1              99M   33M   61M  36% /boot
    tmpfs                 1.5G     0  1.5G   0% /dev/shm
    

    Bleah. A line break. Why you mess my rows, GNU? An easy fix jumped into my noggin the other day and crept down my arms and out my fingertips:

    2016-02-05 11:03:58 «««« ~
     rons@rons-VM$ df -h | sed 's/Mounted on$/Mount/;' | xargs printf '%-40.40s %8s %8s %8s %5s  %s\n'
    Filesystem                                   Size     Used    Avail  Use%  Mount
    /dev/mapper/VolGroup00-LogVol00               59G      29G      27G   52%  /
    /dev/sda1                                     99M      33M      61M   36%  /boot
    tmpfs                                        1.5G        0     1.5G    0%  /dev/shm
    

    The trick is that a printf format with a trailing newline will repeat if it runs out of input tokens.   That’s why I had to truncate the “Mounted on” to just “Mount” above– otherwise there would be an irregular number of columns (and thus printf tokens) on each line/row.  Spaces in filesystems and mounts will mess it up, too, but if you use spaces in the names of your mounts, you deserve the dissonance.

    Edit: Better shell function replacement below.

    unset -f df ; function df() {
      command df -P $@ | perl -ane '
        push(@rows, [@F]);
        for (0..$#F) {
          $ll = length($F[$_]); $cm[$_] = $ll if $ll > ($cm[$_] // 0);
        }
        END { printf("%-$cm[0]s %$cm[1]s %$cm[2]s %$cm[3]s %$cm[4]s %s\n", @{$_})
          for @rows; }';
    } ;

     

    Uses the -P flag for POSIX one-line-per-mount format.   Dynamically calculates column widths.

     

  • Shell Nuggets: Musing on Dates

    Nigh ever day I happen across some gem tucked away in the opaque vista of the *nix command-line shell.   While attempting to contrive the proper arguments for a date command interpolation, the following editorial injection from its GNU info entry caught my fancy.

    28 Date input formats
    *********************
    First, a quote:
    Our units of temporal measurement, from seconds on up to months,
    are so complicated, asymmetrical and disjunctive so as to make
    coherent mental reckoning in time all but impossible. Indeed, had
    some tyrannical god contrived to enslave our minds to time, to
    make it all but impossible for us to escape subjection to sodden
    routines and unpleasant surprises, he could hardly have done
    better than handing down our present system. It is like a set of
    trapezoidal building blocks, with no vertical or horizontal
    surfaces, like a language in which the simplest thought demands
    ornate constructions, useless particles and lengthy
    circumlocutions. Unlike the more successful patterns of language
    and science, which enable us to face experience boldly or at least
    level-headedly, our system of temporal calculation silently and
    persistently encourages our terror of time.
    ... It is as though architects had to measure length in feet,
    width in meters and height in ells; as though basic instruction
    manuals demanded a knowledge of five different languages. It is
    no wonder then that we often look into our own immediate past or
    future, last Tuesday or a week from Sunday, with feelings of
    helpless confusion. ...
    -- Robert Grudin, `Time and the Art of Living'.
    This section describes the textual date representations that GNU
    programs accept. These are the strings you, as a user, can supply as
    arguments to the various programs. The C interface (via the `get_date'
    function) is not described here.
    
    

    Now back to work.

     

  • Stuffing Text Into All Screen Windows

    Various pagers have been giving me question marks in boxes and hexadecimal codes.  This is probably because I didn’t have the right font in the past and inserted various hacks into my ~/.bash tree to get around them, e.g. aliasing a LANG=C before every perldoc command.

    Well, now I’ve just about got everything right and proper in UTF-8 mode using a uxterm, but those little nigglers still pop up.  Today I did a man less and found the LESSCHARSET environment variable.  Awesome!  But if it’s not set, it’s supposed to use the locale, and my locale is already properly set up to en_US.utf-8.  Not a problem.  I just export -n LESSCHARSET to un-export the variable.

    But I’m in screen, with fourteen windows open.  How do I loop through all screen windows, stuffing a command into each?

    Luckily, a quick reading of the screen man page led me to this:

    at \# stuff "export -n LESSCHARSET\015source ~/.bash/aliases\015
    

    And BAM that gets stuffed into every window I have open.  Unfortunately, some of those are SQL prompts, log tails, and maybe an open vim session or two, but such are the pitfalls of impatiently trying out a new command, and no harm was done.

    The trick is to use the backslash-escaped octothorpe to specify all windows.  The rest is just a normal stuff, with that annoying octal \015 to specify a newline.

    Oh, and I added a second command to source my bash aliases, because I’d added new ones recently.