> For the complete documentation index, see [llms.txt](https://cajac.gitbook.io/ctf-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cajac.gitbook.io/ctf-notes/prog/bash-scripting/functions.md).

# Functions

## Examples

### Getopts example

Reference: <https://stackoverflow.com/questions/16483119/an-example-of-how-to-use-getopts-in-bash#16496491>

```bash
#!/bin/bash

usage() { echo "Usage: $0 [-s <45|90>] [-p <string>]" 1>&2; exit 1; }

while getopts ":s:p:" o; do
    case "${o}" in
        s)
            s=${OPTARG}
            ((s == 45 || s == 90)) || usage
            ;;
        p)
            p=${OPTARG}
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))

if [ -z "${s}" ] || [ -z "${p}" ]; then
    usage
fi

echo "s = ${s}"
echo "p = ${p}"
```

### Unpacking of matryoshka zip file

```bash
#!/bin/bash

function unpack() {
    if [ -r $1 ] 
    then
        password=$(unzip -Z -1 $1 | sed -e 's/\([0-9]*\)\.zip/\1/')
        echo "Unpacking file $1 with password $password..."
        
        # Unpack and remove old file
        unzip -o -P $password $1
        if [ $? -eq 0 ] 
        then
            echo "Removing old file $1"
            rm $1
        fi
    else
        echo "Tried to unpack non-existing file: $1"
    fi
}

if [ $# == 1 ]
then
    unpack $1
    
    # Call the script recursively with next zip file if found
    next_zip=$(ls -1 [0-9]*.zip)
    if [ $? -eq 0 ] && [ "$1" != "$next_zip" ] 
    then
        ./unpack_zip_loop.sh $next_zip
    fi
else
    echo "Usage: $0 <name_of_starting_zip_file>"
fi
```

## Test Conditions

### File Test Operators

<table><thead><tr><th width="151">Operator</th><th>Description</th></tr></thead><tbody><tr><td>-f</td><td>True if the file exists</td></tr><tr><td>-d</td><td>True if the directory exists</td></tr><tr><td>-r</td><td>True if the file is readable</td></tr><tr><td>-w</td><td>True if the file is writable</td></tr><tr><td>-x</td><td>True if the file is executable</td></tr></tbody></table>

### Numeric Comparison Operators

<table><thead><tr><th width="145">Operator</th><th>Description</th></tr></thead><tbody><tr><td>-eq</td><td>Equal to</td></tr><tr><td>-ne</td><td>Not equal to</td></tr><tr><td>-lt</td><td>Less than</td></tr><tr><td>-le</td><td>Less than or equal to</td></tr><tr><td>-gt</td><td>Greater than</td></tr><tr><td>-ge</td><td>Greater than or equal to</td></tr></tbody></table>

### String comparison operators <a href="#string-comparison-operators" id="string-comparison-operators"></a>

<table data-search="false"><thead><tr><th width="156">Operator</th><th>Description</th></tr></thead><tbody><tr><td>=</td><td>Equals to (but for strings)</td></tr><tr><td>!=</td><td>Not equal to (for strings)</td></tr><tr><td>&#x3C;</td><td>Less than (in ASCII alphabetical order)</td></tr><tr><td>></td><td>Greater than (in ASCII alphabetical order)</td></tr><tr><td>==</td><td>Double equals to (used to compare two strings)</td></tr><tr><td>-z</td><td>The String is null</td></tr><tr><td>-n</td><td>The String is not null</td></tr></tbody></table>

## Special Bash Variables

Bash reserves some special variable names, as shown in the table below.

<table data-search="false"><thead><tr><th width="160">VARIABLE NAME</th><th>DESCRIPTION</th></tr></thead><tbody><tr><td>$0</td><td>The name of the Bash script</td></tr><tr><td>$1 - $9</td><td>The first 9 arguments to the Bash script</td></tr><tr><td>$#</td><td>Number of arguments passed to the Bash script</td></tr><tr><td>$@</td><td>All arguments passed to the Bash script</td></tr><tr><td>$?</td><td>The exit status of the most recently run process</td></tr><tr><td>$$</td><td>The process ID of the current script</td></tr><tr><td>$USER</td><td>The username of the user running the script</td></tr><tr><td>$UID</td><td>The user identifier of the user running the script</td></tr><tr><td>$HOSTNAME</td><td>The hostname of the machine</td></tr><tr><td>$RANDOM</td><td>A random number</td></tr><tr><td>$LINENO</td><td>The current line number in the script</td></tr></tbody></table>

## Resources

getopts - Bash Reference Manual: <https://www.gnu.org/software/bash/manual/bash.html#index-getopts>

Shell Functions - Bash Reference Manual: <https://www.gnu.org/software/bash/manual/bash.html#Shell-Functions>
