BASH and Shell
These are the BASH and SHELL language-specific coding styles. Anything mentions here overrides/adds to the "In General" guides.
#1 Shebang Line
#1 Shebang Line
Always include Shebang Line in Line 1. Period.. You’ll break your script and let your user crying to figure out which Shell program to use if you avoid it. A Shebang line is:
#!/bin/bash
Example:
#!/bin/bash
1>&2 echo "Hello World"
#2 - Filename
#2 - Filename
The file extension is .sh
or .bash
.
#3 - Naming Convention
#3 - Naming Convention
- Inherit In General - naming convention.
- Consistency first.
- Otherwise, use
snake_case
convention. - Attach package name with double colon (::) for writing a package.
Example 1:
integer=5
export OS_LEVEL=5
TITLE_SHARABLE_VARIABLE="the shared data for other script to source from"
process_data() {
...
}
# run
unset integer
process_data
Example 2:
# Single function
my_func() {
...
}
# Part of a package
mypackage::my_func() {
...
}
#4 - Functions
#4 - Functions
- Inherit In-General - Variable and Functions.
- Opening brace
{
after the function naming since it breaks the script. export
comes after the function declaration.- Always keep track to
unset
your functions after used.
Example:
function_name() {
echo "Hello World"
}
export -f function_name
#5 - Variables
#5 - Variables
- Inherit In-General - Variable and Functions.
- Keep operations outside variables.
export
comes before the variable.- Forbid array if you it want to be POSIX compliant.
- Forbid yourself from using
local
keyword. Use the naming convention for maximum POSIX compatibility. - Forbid the use of
alias
. Usefunction
instead. - One exception: use of global variables for configuration is greatly encouraged due to SHELL limitation in object-oriented facility.
Example:
# variable requires operations
GLOBAL_VARIABLE="$(ls)"
export GLOBAL_VARIABLE
# variable with only value
export GLOBAL_LANGUAGE="en-US"
# DO NOT do this. $(...) is an operation
export GLOBAL_VARIABLE="$(ls)"
#6 - Indentation
#6 - Indentation
- Inherit In General - Indentation.
- Maximum columns are 80 characters
Rationale
Rationale
It’s a terminal script.
#7 - If Else and While Loop Condition Syntax
#7 - If Else and While Loop Condition Syntax
- Perferbly
[[ ... ]]
for bash while[ ... ]
for POSIX compliant. - 1 space after
[
or[[
. - 1 space before
]
or]]
. then
ordo
should shares the same line asif
,elif
,while
andfor
respectively.- No space before the semi-colon (
;
); 1 space after; thenthen
ordo
comes later. - All contents inside should have 1 TAB inside.
Example:
# BASH
if [[ 5 != 0 ]]; then
...
elif [[ 5 != 0 || 5 != 4 ]]; then
...
elif [[ ([[ 5 != 0 || 5 != 4 ]]) && ([[ 5 != 0 || 5 != 4 ]]) ]]; then
...
elif [[ ([[ 5 != 0 || 5 != 4 ]]) &&
([[ 5 != 0 || 5 != 4 ]]) &&
([[ 5 != 0 || 5 != 4 ]]) &&
([[ 5 != 0 || 5 != 4 ]]) ]]; then
else
...
fi
# POSIX Compliant
if [ -z "$filename" ]; then
...
elif [ -z "$filename" ] && { [ -e "$filename" ] || [ -r "$filename" ] }; then
...
else
...
fi
# BASH
while [[ ([[ 5 != 0 || 5 != 4 ]]) && ([[ 5 != 0 || 5 != 4 ]]) ]]; do
...
done
for item in "${list[@]}"; do
...
done
# POSIX Compliant
while { [ 5 != 0 ] || [ 5 != 4 ] } && { [ 5 != 0 ] || [ 5 != 4 ] }; do
...
done
for file in ./directory/*; do
...
done
#8 - Printout (stderr) vs. Output (stdout)
#8 - Printout (stderr) vs. Output (stdout)
- Inherit In General - Silence is Gold.
Example:
Add() {
echo "$((1 + 2))"
return 0
}
1>&2 echo -n "This is a status message. Doing 5 + 3 = "
Add 5 3
#9 - Command Substitution
#9 - Command Substitution
- Use
$(...)
instead of backtick`...`
. - Stringtify (
"$(...)"
) the output.
Example:
# This is preferred:
var="$(command "$(command1)")"
# This is not:
var="`command \`command1\``"
# 10 - Built-In or External Commands
# 10 - Built-In or External Commands
- Use built-in as far as much as possible to reduce dependency.
- Use "type" commands to find out your keyword nature.
Example:
$ type time
time is a shell keyword
$
That's all for BASH and SHELL script.