Scripting Conventions – One-Liner vs Script

conventionsscripting

I've noticed a lot of questions and answers and comments expressing disdain for (and sometimes even fear of) writing scripts instead of one-liners. So, I'd like to know:

  • When and why should I write a stand-alone script rather than a "one-liner"? Or vice-versa?

  • What are the use-cases and pros & cons of both?

  • Are some languages (e.g. awk or perl) better suited to one-liners than others (e.g. python)? If so, why?

  • Is it just a matter of personal preference or are there good (i.e. objective) reasons to write one or the other in particular circumstances? What are those reasons?

Definitions

  • one-liner: any sequence of commands typed or pasted directly into a shell command-line. Often involving pipelines and/or use of languages such as sed, awk, perl, and/or tools like grep or cut or sort.

    It is the direct execution on the command-line that is the defining characteristic – the length and formatting is irrelevant. A "one-liner" may be all on one line, or it may have multiple lines (e.g. sh for loop, or embedded awk or sed code, with line-feeds and indentation to improve readability).

  • script: any sequence of commands in any interpreted language(s) which are saved into a file, and then executed. A script may be written entirely in one language, or it may be a shell-script wrapper around multiple "one-liners" using other languages.


I have my own answer (which I'll post later), but I want this to become a canonical Q&A on the subject, not just my personal opinion.

Best Answer

Another response based on practical experience.

I would use a one-liner if it was "throw away" code that I could write straight at the prompt. For example, I might use this:

for h in host1 host2 host3; do printf "%s\t%s\n" "$h" "$(ssh "$h" uptime)"; done

I would use a script if I decided that the code was worth saving. At this point I would add a description at the top of the file, probably add some error checking, and maybe even check it into a code repository for versioning. For example, if I decided that checking the uptime of a set of servers was a useful function that I would use again and again, the one-liner above might be expanded to this:

#!/bin/bash
# Check the uptime for each of the known set of hosts
########################################################################
#
hosts=(host1 host2 host3)

for h in "${hosts[@]}"
do
    printf "%s\t" "$h"
    uptime=$(ssh -o ConnectTimeout=5 -n "$h" uptime 2>/dev/null)
    printf "%s\n" "${uptime:-(unreachable)}"
done

Generalising, one could say

  • One-liner

    • Simple code (i.e. just "a few" statements), written for a specific one-off purpose
    • Code that can be written quickly and easily whenever it is needed
    • Disposable code
  • Script

    • Code that will (probably) be used more than once or twice
    • Complex code requiring more than "a few" statements
    • Code that will need to be maintained by others
    • Code to be understood by others
    • Code to be run unattended (for example, from cron)

I see a fair number of the questions here on unix.SE ask for a one-liner to perform a particular task. Using my examples above, I think that the second is far more understandable than the first, and therefore readers can learn more from it. One solution can be easily derived from the other so in the interests of readability (for future readers) we should probably avoid providing code squeezed into in one line for anything other than the most trivial of solutions.

Related Question