Skip to main content
6 of 6
why are sections not working?
user avatar
user avatar

Bash

Scoring

Typically counted in bytes. Bash programs don't need a trailing newline, so don't count this if your editor adds one automatically.

If your entry only uses builtin features (use type -a <command> to find out), then you can claim your entry as Pure Bash. However if your entry calls external binaries (e.g. paste from coreutils), then your entry should mention this in the header, e.g. Bash + coreutils.

Truthy/Falsey

This is a little odd in shell-type languages. Shell commands - be they external binaries or shell builtins - return a status code between 0 and 255. Typically 0 indicates success whereas any other number indicates some error. The return code can be accessed in the $? variable. For example grep returns 0 if it finds a match and 1 if not:

$ echo haystack | grep -q needle
$ echo $?
1
$ echo haystack | grep -q hay
$ echo $?
0
$ 

The flow control statements (including if) use these values accordingly:

$ if echo haystack | grep -q needle; then echo Found it; fi
$ if echo haystack | grep -q hay; then echo Found it; fi
Found it
$ 

So TRUE = 0, and FALSE = anything else - upside down, right? You can see this even in the true and false builtins:

$ true
$ echo $?
0
$ false
$ echo $?
1
$ 

If this wasn't confusing enough, the (( )) arithmetic expansion test may be used to produce a return code. Internally these operate using the more usual TRUE = 1/FALSE = 0 paradigm, but this is switched for when the result of an expression is returned out of the (( )). For example:

$ ((1))
$ echo $?
0
$ ((0))
$ echo $?
1
$ 

I/O

Both programs and functions may read from STDIN and/or use positional command-line parameters $1, $2, etc (or $@ for them all).

For testing purposes, you may explicitly put values in the positional parameters using set -- <param1> <param2> ...

Output is typically to STDOUT. Any output to STDERR may be ignored as per standard rules.

Truthy/Falsey output may also be in the form of a shell return code as described above. This works for programs and functions. The return keyword may be used to explicitly return with a given status, but if it is not used, the status of a program or function will be the status of the last executed command:

$ f()(true;false)
$ f
$ echo $?
1
$ f()(false;true)
$ echo $?
0
$ 

I/O datatypes

This is pretty flexible. The most common (Unix) way to input/output a list is to make it newline-delimited - i.e. one item per line. However there is no reason why you couldn't use comma-separated values instead, if that is convenient for the given challenge. There is not really a right-or-wrong way to do this with shell scripts.

Versions

Version 4.0 and later have several more advanced features. Some that spring to mind:

  • Associative arrays
  • More expressive brace expansions
  • Regex conditionals
  • mapfile

Different OSes have different utilities. For example the Linux find is most commonly a version from coreutils. This is quite different to the BSD-flavour find on MacOS - even if the bash versions are the same.

Digital Trauma
  • 73k
  • 1
  • 22
  • 39