
Use long flags when scripting - adamstac
http://thechangelog.com/use-long-flags-when-scripting/
======
npsimons
While it is generally a good idea to write readable code, it is also true that
long flags are not universally supported, and the short flags don't always
have the same meanings (or even exist!) across different systems.

This is an interesting conundrum. As has been pointed out, POSIX specifies
standard options (which are all short):

<http://news.ycombinator.com/item?id=5165058>

But these are not universally supported:

<http://unixhelp.ed.ac.uk/CGI/man-cgi?ps>

What to do? My proposal: do what we do in the C/C++ world when presented with
portability problems: abstract it away. POSIX sh supports functions, which can
be named appropriately for readability, while calling the proper arguments and
commands for different platforms. To avoid unnecessary duplication of
platform/argument detection, setup could be done in a function called before
anything else to create variables with the appropriate command names and
arguments.

This may all seem too involved, but realize that we are talking about creating
robust software that is to be maintained, so applying proper software
engineering principles seems appropriate.

~~~
jsaxton86
A much simpler solution is to comment your code:

# Invoke curl in silent mode (-s), pipe the output to grep

# and use an extended regex (-E) to only show the resulting

# digits (-o: only print matching text, not the whole line):

curl -s checkip.dyndns.org | grep -Eo '[0-9\\.]+'

~~~
npsimons
I don't like commenting the how and what; that's what the code is for.
Comments are for "why".

~~~
reledi
How and what are good to include when describing the function, but not for
specific statements of code.

------
ralph
This is very bad advice. I won't thank you for making me check GNU grep's
--ignore-case is precisely the same as the very well-known, POSIX'd, -i. And
ditto for all the other verbiage that clutter and obfuscate the script's
intent.

Short options should be used where they're the more typically known and
standardised. Long options are for the unusual.

    
    
        grep -iv
        sed -n
        tr -dc
        awk -f
        ls -tr
        comm -23
        tail -n

~~~
sirclueless
I'm a 4th year student in a well-respected CS program, I have used linux off
and on for over three years now, and I would consider myself perfectly capable
of maintaining a shell script using any of the utilities you mention. However,
without checking the man pages I could not tell you the behavior of the -n
flag for sed, the -dc flags for tr, the -f flag for awk, or the -tr flags for
ls, and I only have a guess as to what comm -23 does.

This is not the bread and butter of programming, where everyone worth a damn
should be able to decipher "int i = 10;" even if it's not their brand of
syntax. There are people who are perfectly capable of understanding and
maintaining a piece of software that uses "tr --delete --complement" but would
be dumbfounded when confronted with "tr -dc" until they looked it up.

~~~
rlpb
> This is not the bread and butter of programming...

This is, however, the bread and butter of _shell_ programming.

> ... "tr --delete --complement"...

And, likewise, I'm not sure of the meaning of --delete and --complement, but I
do understand "tr -dc". I'd have to look up --delete and --complement to work
out what they're the equivalent of.

~~~
danielvinson
"This is, however, the bread and butter of shell programming."

This is really old-fashioned thinking. The people who have been in this
industry for 10+ years all grew up without computers - and thus had to
memorize all of the flags, obscure shell commands, and weird regular
expression. What was taught in school back then was to do things perfectly the
first time, because CPU cycles were expensive, and bugs were time consuming.

The generation that graduated from college about 2 years ago is the first one
that had universal access to a search engine since they knew how to use a
computer. This generation (and all future ones for the rest of time) sees
memorizing things like this as more of a waste of mental space. What is taught
in Universities now is problem solving, research, and larger concepts. There
is very little straight memorization, and almost zero programming by
hand/whiteboard programming. No current college grad will be able to write a
shell script without reference material, but every college grab should be able
to write any simple script in less than 5 minutes with Google.

~~~
kragen
You're going to have a hard time making it through Hemingway if you have to
reach for a dictionary every time you come across a word like "middleweight"
or "khaki", even if your dictionary is online and answers your query in less
than a second. You need to memorize the meanings of a vocabulary of words in
order to read fluently or write well. That's not "old-fashioned thinking".
It's just common sense. And it's just as true of shell scripts as it is of
electrical engineering, mechanical engineering, poetry, or math.

~~~
rrreese
While both the above words are known to me, I do like that when reading a book
in Kindle on my iPad, I can tap a word, and have its definition show.

------
taylorfausak
Agreed! It saves a trip to the man page.

Something else I figured out recently is that if you put the pipe at the end
of a line, you don't need a backslash:

    
    
        echo thing |
        grep thing

~~~
pmattos
I have seen this working, but didn't understand why... thanks!

------
kps
No. Use standard POSIX flags to invoke standard POSIX functionality, so your
scripts don't break when run on a different system.

~~~
jerf
It's always a cost/benefits analysis. I think for a lot of us, the
cost/benefit goes something like this:

"Will I ever have to read and modify this script again? Effectively-100%
likely. Will this script ever run anywhere that I don't have the GNU
toolchain? Effectively-0% likely."

It's a no-brainer at that point.

If you can't say that second part honestly, reconsider, but a lot of us can.

~~~
lamby
> Will this script ever run anywhere that I don't have the GNU toolchain?
> Effectively-0% likely.

Not really. A lot of stuff broke when /bin/sh moved to a POSIX-compatibile
shell rather than Bash.

~~~
njharman
No a lot of stuff broke because people depended on implicit rather than being
explicit.

    
    
        #!/bin/bash

~~~
Wilya

      wilya@home $ /bin/bash
      zsh: no such file or directory: /bin/bash
      wilya@home $ which bash
      /usr/local/bin/bash
    

(Yes, I'm annoyed when I see #!/bin/bash, especially on scripts which are
otherwise basic enough to be portable everywhere)

~~~
dfox
It is still better to write #!/bin/bash for bashism using scripts than
#!/bin/sh. I recently had to run sed -i (well, another GNUism) 1s%/sh%/bash%
on bunch of customer's scripts to make them work on debian. At least when
script wants /bin/bash it is going to fail cleanly (and not in the middle
after modifying random things) and with mostly meaningful error.

------
dclowd9901
As a part-time scripter (is there any other kind?) I'm ashamed to say that I
often use shortcut flags because I looked up the functionality I needed and
copy pasted without taking the time to even understand what all of the flags
mean.

This advice is good not only for others but setting a standard for yourself
where you take a moment to learn what exactly is going on.

~~~
ajross
Like everything else it depends. "rm -rf" is a lot easier to read than "--
recursive --force" simply because every likely maintainer will (1) already
know the short form and (2) will have no idea the long form options even
exist. Likewise arguments to tar are probably best left in traditional form,
etc...

Don't rock the boat just to adhere to silly style rules. The goal is
readability. You're probably already the best judge of what is most readable,
so trust your intuition. If you had to look it up, then spell it out. If not,
relax and do it the sane way.

~~~
ojbyrne
I think the correct answer is do both.

------
hnolable
Disagree. There isn't and shouldn't be any hard fast rule for this. Same as
most things in programming. Do what makes sense.

Also, [0-9.] not [0-9\\.]

~~~
eli
IMHO, if your intent is to capture a literal dot then you should escape it
even if, based on the context, you don't have to.

~~~
ralph
No, that's wrong, a reader that knows his onions, e.g. me, will be puzzled as
to what the writer's intent was and spend time investigating if there is an
error before deciding the writer needs to spend more time studying his onions.

~~~
eli
I think the goal should be clarity, not conservation of characters. And I
think the escaped dot is clearer (the author's intent is obviously to include
a dot in the range).

I do think it's funny that you said "There isn't and shouldn't be any hard
fast rule for this" and then one comment later said my approach is "wrong" :)
(EDIT: oops, that wasn't you -- Sorry!)

~~~
logn
It's only clear for people who don't really understand regexes. For people
with knowledge of them, it's more ambiguous as to whether a slash is being
matched or used to escape. It reminds me of commenting the end of your for
loops, } //end for ... it's clear for people who come from Python and don't
know Java but that's not who we should be helping.

~~~
Firehed
Are you writing this for yourself or to share? If the latter, optimize
readability for people who don't understand regexes.

As for commenting the end of loops - that too just improves readability,
especially in long functions. If your editor doesn't show invisible
characters, it can be easy to lose track if some indent is part of the 'i'
loop or the 'j' loop, for example (yes, that can indicate a bigger problem,
but that's not the point. I'm talking about real-world code, not idealistic
academic nonsense)

~~~
hkolek
Why? So my grandma can read my code? That's not the way to enlightenment if
you program in a professional setting.

------
shizcakes
This is a practice I use; in my opinion it is akin to descriptive variable
names.

------
rohit6223
I write a lot of shell scripts as part of my daily Sys Admin work. In my
opinion, the author gave us choice to write less codes & readable code by
using short flags for most of the command functionalities.

Consider something like this: $ rsync -qaogtHr example.com:/opt/data/
/home/backup/

1\. Elaborating all the short flags into long ones will increase readability
by explaining this statement but at the cost of more lines of code.

2\. All UNIX commands have options to combine short flags. For eg: ls -l -t -r
./ can be written as: ls -ltr ./ This also helps in reducing code. Writing
less code helps in managing it more easily.

Long options may help beginners, but once they get comfortable, Short flags
may seem more readable!!

------
opk
For well known flags like grep's -E, this makes it less obvious what the
script is doing. Not everyone speaks English as their first language and most
of the long options are GNU specific so won't be portable.

------
nathanstitt
A secondary benefit not mentioned in the article is immutability.

Long flags on a command line utility _should_ never change. Short flags may be
modified between major versions of a utility, which would break scripts.

Of course this is just a convention, and I'm sure it's not followed 100%. I'll
take whatever protection I can get though.

~~~
Flimm
Neither long flags or short flags should change meaning. I'm not sure where
you got the idea that short flags do.

~~~
nathanstitt
You now, I'm really not sure where I picked that up. It's always been my
understanding that it was acceptable to change the short flags on a utility as
part of a new major version. Not that you should change 'em capriciously, but
that it wasn't the end of the world if you did.

Of course, I can't find any references to back me up on that, so you may very
well be correct.

~~~
zxtang
"GNU grep 2.12 changes behavior of recursion options, breaks existing
scripts": <http://news.ycombinator.com/item?id=4295681>

------
6ren
Ironically, tab-completion works on the command-line for long options, but not
in a script (I'm sure vim can do it though).

~~~
bazzargh
C-x C-e opens an editor for the command-line, so after you've tab completed it
it's easy to save.

------
xutopia
I recently found myself going back and changing a script I had done to use the
long form flags because I had forgotten what the short ones meant.

------
natefinch
This is very good advice. You may not be maintaining your script later on,
maybe someone who is new to unix will be asked to go change it. Having the
intention much more obvious will save them some hassle. Hell, even someone who
uses unix a lot may not know every flag of every command you use. With no
other context, it's pretty hard to know if -r is recursive or reverse sort, or
something else entirely.

And god forbid you _think_ you know which one it is and end up being wrong...
you might not realize until it hits production (scripts not always being the
best tested things in the world).

Yes, they might not be supported on BSD.. they're also not supported on
Windows, what's your point? It's a lot more likely you'll have to read and/or
change the script 6 months down the line when you've forgotten everything
about what's in it, then you'll all of a sudden need to run your script on BSD
when you've never had to in the past (obviously if portability is a
requirement from te beginning, then that changes how you write the script from
the start).

------
pacala
Add auto-complete to the command line and everyone will start using long form
without the need to beg. Imperfectly remembering the flag spelling is a rather
large annoyance, short flags avoid this problem at the cost of crypticism,
autocomplete actually solves it.

~~~
npsimons
First and foremost, the article talks about flags _in files_ , where your IDE
of choice can probably autocomplete them (see
<http://emacswiki.org/emacs/DynamicAbbreviations> for an example). Second,
even on the commandline, bash_completion
([http://www.gnu.org/software/bash/manual/html_node/Programmab...](http://www.gnu.org/software/bash/manual/html_node/Programmable-
Completion.html)) has been available for a while now.

------
shurcooL
Or, there should be an automated tool that takes scripts with short flags and
displays them with automatically replaced equivalent long flags for
readability.

Not everything has to be static text, one format does not fit all situations.

------
james-manning
At least for scripts that are on github, it seems like this could be
potentially tackled by creating a robot that submits pull requests for such
scripts, changing the options passed from short to long. For people fine with
the change, they could just merge the PR, and for those that don't like it,
people still have a long-option version of the script they can check out in
the PR.

I've not written a github robot, though, this is just based on my vague
understanding from the robots already out there (whitespace, .gitignore, etc),
so please correct me if this isn't actually feasible. :)

------
webreac
I think the short flags are more useful when using directly the command
(outside of a script). It is faster to type man grep in a window and to type
grep -Eo than to type grep --extended-regexp --only-matching. At first, I even
didn't realize that --extended-regexp was the same as the usual -E flag. I had
to check with man.

Theoretically, I would like to agree that long flags are better than short
ones in scripts. In practice, I prefer grep -E. And I can not imagine a tar
cvfhz with long flags.

------
pmattos
I too have been using this practice for years now, unfortunately most
coworkers don't seem to appreciate the genius of it.

------
captn3m0
Time to update some of my scripts.

------
darrikmazey
My age probably shows in this statement, but it seems odd to me to suggest
that someone else change their behaviour so the poster does not have to rtfm.
We're coders. When we don't understand something, we read the manual, then the
source.

------
jstanley
I accept --silent, but almost everybody knows what -E to grep means. Normally
I would just use egrep rather than grep -E however.

------
joshbaptiste
heh.. I have never thought of that. I basically script exactly how I construct
commands in the cmd line, but the author is correct looking at my past bash
scripts it would be better to use long options, good stuff.

------
blktiger
Amen!

------
evandrix
if you can't read the short flags, you shouldn't be reading my code.

------
evandrix
there's always a "man" page (and Google) to look it up, stupid.

