I’ve been writing lots of bash scripts lately, so I thought it would be a good idea to document a few of the little tricks I’ve been using.

First off, to make a script that has to be executed in bash:
```
#!/bin/bash
if [ ! "$BASH_VERSION" ] ; then
echo "Please do not use sh to run this script ($0), just execute it directly" 1>&2
exit 1
fi
```

This was needed for a script that makes uses of Bash syntax for `for` loop and some basic math, and I had a user reporting errors when they tried to do `sh script.sh`. `sh` ignores the opening `#!/bin/bash` line and tries to execute the script directly, and fails when it hits those lines.

Then, to make a script that has to be sourced in the global environment (to set environment variables like `PATH` and `LD_LIBRARY_PATH` for the user).

```
#!/bin/bash
if [[ "$(basename "$0")" == "script.sh" ]]; then
echo "ERROR: Don't run $0, source it" >&2
exit 1
fi
```

replace `script.sh` with the name of the actual file.

Then, to URL Encode a parameter in bash (I used this to encode a user provided git password into the url), use this function:

```
rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""

for (( pos=0 ; pos
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}" # You can either set a return variable (FASTER)
REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
}
```

Then you can use it like so:

```
echo Enter your GitHub username:
read GIT_USER

echo Enter your GitHub Password:
read GIT_PASSWORD

GIT_AUTH=$( rawurlencode "${GIT_USER}" ):$( rawurlencode "${GIT_PASSWORD}" )
git clone http://${GIT_AUTH}@github.com/user/repo
```

*yeah yeah, I know.. SSH keys are better… tell it to the users, not me*

Finally, using `getopt`. It’s a big tool, but the basics of using it:

```
USE_SSH=0
AUTOMATED=0
BUILD_WIDTH=1
while getopts "aj:s" o; do
case "${o}" in
s)
USE_SSH=1
;;
a)
AUTOMATED=1
;;
j)
BUILD_WIDTH=${OPTARG}
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
```

Important bits:

* the `getopts` line: Include each character recognized as a flag, and following it with a `:` if it requires an argument.
* Then include a case for each one in the big switch.. use `$(OPTARG)` to get the argument, if it’s needed.

Makes argument parsing simple in bash scripts simple… Also define a `usage` function to spew out the supported options, and you’re golden.