(B)itovi (A)nd (SH)
Easily writing predictable shell scripts
tl;dr / TOC
Which shell should I use?
Use a linter! Rationale
As with any programming language-- you should be using a linter!
Linters:
Use a linter! shellcheck
https://www.shellcheck.net/ is an excellent linter that covers:
Use a linter! Installing shellcheck
Shellcheck is available for all common platforms, and can even be run from docker. Install instructions in shellcheck's README.
Editor plugins that can automatically show shellcheck errors in your editor:
Bonus: format your scripts
Basics - The anatomy of a script
#!/bin/bash
echo “hello world”
“hashbang” or “shebang” line -> specifies which interpreter to use[1][2]
one or more commands to run
Basics - Exit statuses
Basics - Conditionals
if command; then
echo ‘command exited 0!’
elif other-command; then
echo ‘other-command exited 0, but command exited nonzero!’
else
echo ‘both commands exited nonzero’
fi
# takeaway: if statements use exit statuses, not output
Basics - Conditionals with `test`
The `test` command is the same as `[` (see `man test` for details)
if [ “$var” = some-string ]; then
echo ‘$var equals “some-string”’
elif [ $(grep -c str file.txt) -gt 10 ]; then
echo ‘“str” shows up more than 10x in file.txt’
fi
test “$var” = some-string && echo ‘Same as the first `if`’
# takeaway: see `man test` for help with `[` (most comparisons)
Basics - Loops
# print files in a directory
for file in $(ls directory/); do
echo “directory/$file”
done
# count to 5
for num in 1 2 3 4 5; do
echo “$num”
done
# echo statements or quit on ‘q’
statement=’’
while [ “$statement” != ‘q’ ]; do
echo “Text? (q to quit): “
read statement
echo “You entered: $statement”
done
# wait for file to exist
name=file.txt
while [ -f “$name” ]; do
sleep 1
done
echo “file $name should exist now”
Basics - AND / OR
&& || both deal with exit statuses:
test (prog1 && prog2) && echo “prog1 and prog2 both returned 0”
if grep something file.txt || [ $var -gt 2 ]; then
echo “Found ‘something’ in file.txt”
echo or
echo ‘$var is a number greater than 2!’
fi
Basics - output
# ignore error output
echo ‘test’ 2> /dev/null # prints ‘test’
# ignore standard output
cat file-that-does-not-exist.txt > /dev/null # prints an error
Summary
References
Demo
Questions?