0
 $ factorial() {  [ "$1" = "0" ] && echo ${2:-1} || factorial $(( $1 - 1 )) $(( ${2:-1} * $1 )); }

Nov. 25, 2019, 8:06 a.m.CK

Explanation

Not as short and elegant as the one below, but this doesn't call out to external programs. It's a simple ternary expression, which, for any call to the function except when passed 0 as its first argument, calls the function again with adjusted parameters, the first of which starts at the value to factorialise and is decremented with each call, while the second stores the product of all the values the first parameter is ever passed.

  • [ "$1" = "0" ] evaluates to true if the first argument passed to the function is 0, and false otherwise

  • && performs the command immediately to its right iff the expression immediately to its left evaluated to true

  • echo ${2:1} prints the second argument if there is one, otherwise it prints 1

  • || performs the command immediately to its right iff the command immediately to its wasn't performed

  • factorial is the recursive function call to which the following arguments are passed:

    1. $(( $1 - 1 )) is the first argument decremented by 1

    2. $(( ${2:-1} * $1 )) is the product of second argument (if one exists, otherwise unity) with the first