A collection of shell scripts written just for fun and learning aimed towards UNIX and Linux systems.
- Why is the commit history overwritten so much?
To start from scratch and correct any mistakes I made (e.g illogical commit dates).
- Why do I get an error message when running
git pull
?
Because I forcefully pushed commits. To fix it, delete the repository's directory and clone it again.
- bash >= 5
- git >= 2.40.1
- coreutils >= 9.1
- Any POSIX compliant shell (e.g
dash
)
dl | si | che | chk4up | screenshot |
---|---|---|---|---|
youtube-dl >= 2021.12.17 | apt >= 2.7.0 | shadow >= 4.12.3 | pamac >= 10 | scrot >= 1.9 |
dnf >= 4.15.0 | libnotify >= 0.8.2 | libnotify >= 0.8.2 | ||
pacman >= 6 | ||||
ncurses >= 6.4 |
- Get required software.
- Clone repository.
git clone https://github.com/tricantivu/bashy.git
.
- Run (from repository's root):
./install.sh
- Indentation
- Shebang
- Quoting
- Variables
- Constants
- Functions
- Arithmetic
- Loops
- Conditions
- Switch-Case
- Traps
- ShellCheck
- 4 spaces.
for (( ;; )); do
printf 'y\n'
done
Use the env
command without options that are not specified by
POSIX (e.g -S
).
POSIX scripts:
#!/usr/bin/env sh
Non-POSIX scripts:
#!/usr/bin/env bash
- Single quote strings without parameter expansions.
printf '%s\n' 'Success!'
echo 'Failure!'
- Do not quote parameters expanding to numerical values.
- Names are snake cased. Except for loop counters, they must be lowercase letters.
i=0 j=0 k=0
parent_node
- Initialized or declared without
declare
builtin command.
- Names must be in SCREAMING_SNAKE_CASE.
readonly INT_MAX=32767
- Initialized with
readonly
builtin command.
readonly LONG_MAX=2147483647
-
Define them with inline curly braces.
-
Write a space after the closing parenthesis.
-
Names are snake cased, abbreviated or full words.
getaddrinfo() {
:
}
get_current_dir_name() {
:
}
-
Avoid floating point numbers.
-
Surround expressions with a space.
(( i * 3 ))
- Check parameters expand to one or more without operators.
(( UID )) || exit 1
- Check parameters expand to zero without operators.
(( EUID )) && exit 1
- If you are not scripting with a POSIX shell, use unary operators to increment or decrement variables. Otherwise, use arithmetic expansions.
Non-POSIX:
(( i++ ))
(( j-- ))
POSIX:
i=$(( i + 1 ))
j=$(( j - 1 ))
- Bodies must preceded and followed by a blank line.
for i in {1..10}; do
echo "${i}"
done
while (( RANDOM < 1000 )); do
echo 'Hello'
done
until (( 1 = 2 )); do
:
done
-
Do not write them inline.
-
Preferably, iterate using brace expansions. However, C like loops are allowed.
- Use logical operators for trivial conditions.
if [[ "${REPLY}" == [Nn] ]]; then
exit
fi
‡
[[ "${REPLY}" == [Nn] ]] && exit
Equivalently for negated conditions:
if ! [[ -f /etc/fstab ]]; then
echo 'Your system is broken!'
fi
‡
[[ -f /etc/fstab ]] || echo 'Your system is broken!'
- Use command groups when there is more than one statement to execute if a
command fails or succeeds (i.e
$? > 0
and$? == 0
respectively).
while read -r line; do
[[ "${line}" =~ ^root ]] && break
done < /etc/passwd || {
echo 'Hmm?'
exit 1
}
while read -r line; do
[[ "${line}" =~ ^(/usr)?/bin/bash$ ]] && break
done < /etc/shells && {
echo 'Bash is a valid login shell'
exit 0
}
-
Patterns must be followed by a blank line.
-
Semicolons must be on a new line and at the same indentation level as its corresponding pattern.
case "${USER}" in
(root)
echo 'I am almost Groot!'
;;
(groot)
echo 'I am Groot!'
;;
esac
-
Use complete signal names.
-
Sort command lines by length.
trap 'rm "${TMPFILE}"' EXIT
trap "printf '\e[2J\e[H'" EXIT
- Do not prefix codes with
SC
.
# shellcheck disable=2086
echo $*