Shell scripts are a useful tool for automating repetitive or complex tasks. This module will teach the development of Bash scripts.
Here is a tutorial on Bash scripting that I reference often for learning various I need for tasks I'm working on. This provides an interesting background for regular expressions and how they work.
find . -type f -name \*\.cpp -exec sed -i
's/Solenoid/frc::Solenoid/g' {} \;
find . -type f -name \*\.cpp recursively searches for files
whose name ends with ".cpp" starting from the current directory.
sed -i 's/Solenoid/frc::Solenoid/g' {} replaces instances
of "Solenoid" with "frc::Solenoid" where {} is where find puts
the filename. /g makes sed replace all occurences on a given
line.
grep -Rn Solenoid recursively searches for files starting
from the current directory for the pattern "Solenoid". It lists the
filename, line number, and line content of any matches.
The following scripts use git commands to manipulate a repository's history. The second uses the plumbing command for-each-ref to enumerate all local branches.
loc-generate.sh (Checks out each commit in a Git repository's history and generates a CSV file of number of lines of code in the repository)
#!/bin/bash
git switch -q main
read -r -a array > data.csv
else
echo $x$','$y','$x$','$y >> data.csv
fi
done
# Print newline so prompt appears on next line
echo
mirror.sh (Used for management of 20+ branches in allwpilib Git repository)
#!/bin/bash
# ./mirror.sh COMMAND STARTBRANCH
# 1st argument is command to run
# 2nd argument is starting branch
if [ $# -eq 0 ]; then
exit 1
fi
# If a starting branch was provided, don't run until that branch is checked out
if [ $# -eq 2 ]; then
run=false
else
run=true
fi
if [ "$1" == "rebase" ]; then
git switch -q main
git pull -q upstream main
fi
branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
base=$(basename $branch)
if [ "$run" = false ]; then
if [ "$base" == "$2" ]; then
run=true
fi
fi
if [ "$run" = true ]; then
echo "Switching to branch '$base'"
git reset -q --hard HEAD
git switch -q $base
# Run subcommand
case $1 in
"build")
if [ "$base" == "itable-base" ] ||
[ "$base" == "kalman-filter" ] ||
[ "$base" == "main" ] ||
[ "$base" == "motion-profile" ] ||
[ "$base" == "pid-dt" ]; then
continue
fi
git apply allwpilib-gradle.patch
./gradlew build
;;
"buildsim")
if [ "$base" == "itable-base" ] ||
[ "$base" == "kalman-filter" ] ||
[ "$base" == "main" ] ||
[ "$base" == "motion-profile" ] ||
[ "$base" == "pid-dt" ]; then
continue
fi
git apply allwpilib-gradle.patch
./gradlew build -PmakeSim
;;
"format")
./styleguide/format.py
./license-update.py
if [ `git diff | wc -l` != "0" ]; then
echo "branch '$base' modified by format.py"
exit 1
fi
;;
"push")
git push -f
;;
"rebase")
if [ "$base" != "cap-sys-nice" ] &&
[ "$base" != "cleanup-command" ] &&
[ "$base" != "cleanup-const" ] &&
[ "$base" != "getinstance" ] &&
[ "$base" != "itable-base" ] &&
[ "$base" != "motor-safety-base" ] &&
[ "$base" != "pid-filter" ]; then
git rebase main
fi
;;
"setorigin")
git branch --set-upstream-to origin/$base
;;
*)
echo '$1' not a valid subcommand
exit 1
;;
esac
if [ $? -ne 0 ]; then
exit 1
fi
fi
done