2022-05-29
The Joy of One-Liners
There is an engineering idiom which withstands time like no other. As old as the hills but never forgotten. In informational technology relations, one could say it is ancient. Its dawn proclaimed from the shores of Seattle, defeated by an apocalyptic horseman with the melodious name NT. Shot! Point blank into the chest. Buried under the hills of an IT dark age which we call the nineties, dead. But is it? Well, not exactly. There is still life in the old dog. Like Beatrix Kiddo, it one-inch punches itself back to daylight. Coal black as a miner. Topsoil sticks to its beige 1978's leather jacket, it trickles to the ground with every step taken to the nearest diner. The door opens again. "May I have a glass of water, please?"
An art passed down from the ancestors. Its most visible interface: The Shell. Its name: The Unix Philosophy.
Coined by Doug McIlroy in the Bell System Technical Journal as a foreword to the UNIX Time-Sharing System. There is an even more concise version[1] and according to Eric Steven Raymond this is [2]:
"This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface."
--- Doug McIlroy ---
In some way, this is similar to the concept of the on vogue philosophy of microservices everywhere. Services are written to do one thing and do it well. They work together. Also, text is the connecting link between programs, services, and humans. The possibility to read a program's output as text seems benign, as long as everything is working well. The advantage is interactivity at any time, testability of every component, and debuggability at every step of the process in an on the fly manner. Impromptu, out of reflex like a punch.
Pipe Dreams
Mc Ilroy made another very important contribution, which is the Unix
pipe. It is the practical implementation of connecting the programs
inside the shell. He saw the programs as tools, plugged together via
pipes building a
toolbox. Program
A's stdout
is put into the stdin
of program B. This leaves us with a
single line of chained, well-defined programs to solve a problem that
would otherwise be an extensive, multi-line program in any programming
language of your choice.
Let's say we've got two programs. The first is one is fortune, the
fortune cookie program from BSD games, which outputs random quotes as
text. The second one is cowsay, which displays various kinds of
animals as ASCII art. In order to work in a coherent manner a |
is
used. The pipe connects the first one to the second one.
fortune | cowsay
_________________________________________
/ Gil-galad was an Elven-king. Of him the \
| harpers sadly sing: the last whose |
| realm was fair and free between the |
| Mountains and the Sea. |
| |
| His sword was long, his lance was keen, |
| his shining helm afar was seen; the |
| countless stars of heaven's field were |
| mirrored in his silver shield. |
| |
| But long ago he rode away, and where he |
| dwelleth none can say; for into |
| darkness fell his star in Mordor where |
| the shadows are. |
| |
\ -- J. R. R. Tolkien /
-----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
To mix in some colors pipe everything through lolcat. Try it out!
fortune | cowsay | lolcat
So far so good, let us gain some real-world practice.
Punching Lines and Retire Your Password Generator
Have you ever questioned the integrity of your one-click, GUI, proprietary password generator? Is its randomness really as unpredictable as it proclaims? Are you the only one which ends up knowing your generated password? There is a one-liner that ups your opsec instantly. Right from the source of randomness:
head -n 42 /dev/urandom | tr -cd '[:alnum:]' | cut -c-12
So, what is going on here? Everything is a file, that is the way *nix
systems see it, even the device which puts out random data. To read the
upper part of a file we use head
. It will be sent to stdout
and
displayed via the shell. Parameter -n
reads exactly 42 lines of the
file given to gather enough randomness. The output of head
will be
sent to tr
. In order to select only alphanumeric characters for our
password, we use '[:alnum:]'
. Parameters -c
selects the complement
of alphanumeric characters and -d
deletes them. cut
does exactly
what it says, -c-12
cuts after 12 characters with leaves us with a
random password of length 12. Every time you execute this one-liner a
freshly made random password is returned.
To extend the pool of possible symbols the manual of tr
lists various
sets of filtered symbols. In the case of a password generator, further
sensible filters are '[:alpha:]'
or '[:digit:]'
. While '[:graph:]'
is also viable in this case it returns one of the greater sets of
symbols. Use it with caution, especially if you create passwords for
database users. These might be terminated prematurely through `
or
'
inside the returned string.
Sunday Punch
This blog entrance can be seen as a prelude to a series of one-liners I use time and time again. The are multiple in the pipeline. One-liners should save you the time you otherwise would spend coding a complex solution. There is little better than solving a challenging problem in a single line.
References
[1] A Quarter Century of Unix, 1994, Peter Salus,
ISBN:9780201547771
[2] The Art of UNIX Programming, 2003, Eric Raymond,
ISBN:9780131429017