
Some advanced bash scripting - jdorfman
https://medium.com/@starkcoffee/some-advanced-bash-scripting-a00524e29f8#.jyioghsku
======
Xophmeister
This is kind of lacking in content for something claiming to be "advanced", to
say the least. "Defensive BASH programming"[1], which has been featured on HN
before, contains a lot more useful advice.

Personally, I would also recommend using ShellCheck[2] to lint your scripts.

[1] [http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-
progr...](http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/)

[2] [https://www.shellcheck.net/](https://www.shellcheck.net/)

~~~
jdorfman
These are great resources, thank you.

------
prairiedock
It's not advanced, it's not long enough, and it's not correct either.

> This will set the value of TMP to `/tmp/myproject` only if it has not been
> set.

This should read "if", not "only if". And it should read: "This will set the
value of TMP to `/tmp/myproject` if it has not been set _or if it is null_."

The form that means 'if it has not been set' has no colon; it is

    
    
      TMP=${TMP-/tmp/myproject}
      

See [https://www.gnu.org/software/bash/manual/bash.html#Shell-
Par...](https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-
Expansion)

------
cosmie
The first example has a lot more use cases than it alludes to. I have a lot of
aliased utility scripts for text processing, and frequently need to use them
over entire files as well as on output piped from other processes. In this
case, I don't know if the input file is going to be an argument or stdin from
some upstream operation. That's easily taken care of with

    
    
      INPUT_FILE="${1:-/dev/stdin}"
    

Which sets the input to the first argument if there is one, or stdin if there
isn't. My solution was a lot messier before I learned about parameter
substitution.

------
joatmon-snoo
Also, set -e is not a good flag to rely on, because it can really trip you up
if you do anything at all that involves subshells, e.g.:

    
    
      set -e
    
      function foo {
          false
          echo foo
      }
    
      i=1
      while [[ i -le 20 ]]; do
          echo "$i $(foo)"
          i=$((i+1))
      done

------
robinhoodexe
Interesting, but a whole lor shorter than what I expected to be honest.

