What you need to know to build structured bash programs. A few lessons learned.
# set -e provides more output that can help with testing your program.
set -e
Running a script from afar is easy, Get the current directory name: source
DIR=${PWD##*/}; echo $DIR;
# means "PWD with the first part removed, up to, and including the last slash.
The first challenge a developer runs into is trying to run another script that is nearby the script you are running from afar.
Scripts know the location of the person running the script
but are not automatically self aware of their own location.
This line of code ensures that your script will know its current location.source
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
relative file locations are now accessable
ls $DIR/../;
./$DIR/script open $DIR/.app #-mac
I know this guide is about bash but its worth considering javascript. The most elegant solution I have seen for this might be using javascript promises to await the completion of the program .then(run_the_next_script)
sh-exec is javascript library that is worth checking out.
There is a way in bash called autoexpect that I am not overly familiar with in bash. source
For operations dependent on a user, I have stored information in a hidden file fired a notification every five seconds and every second checked if the file existed.
adaptive_wait () { # bash function for macintosh notifications. Checking presence of file every second.
TIMEOUT=25;
until [ -d ~/Library/Screen\ Savers/$screen$saver ] || [ -d /Library/Screen\ Savers/$screen$saver ] || [ $TIMEOUT -eq 0 ] ; do
if ! ((TIMEOUT % 5)); then
osascript -e 'display notification "To allow for Decision/User Credentials" with title "Application Waiting"';
fi
sleep 1;
TIMEOUT=$[$TIMEOUT-1];
done
}
Calling functions from another file: source
source ./file_to_source;
name_of_function;
Running multiple tests in one go pass your parameters in with read. source
# Run tests
# argument table format:
# testarg1 testarg2 expected_relationship
source ./file_we_are_running_function_from;
echo "The following tests should pass"
while read -r test
do
testvercomp $test
done << EOF
1 1 =
2.1 2.2 <
3.0.4.10 3.0.4.2 >
4.08 4.08.01 <
3.2.1.9.8144 3.2 >
3.2 3.2.1.9.8144 <
1.2 2.1 <
2.1 1.2 >
5.6.7 5.6.7 =
1.01.1 1.1.1 =
1.1.1 1.01.1 =
1 1.0 =
1.0 1 =
1.0.2.0 1.0.2 =
1..0 1.0 =
1.0 1..0 =
EOF
echo "The following test should fail (test the tester)"
testvercomp 1 1 '>'
# uses "?" as a wildcard inserts into the 9th line the variable pwd3 wiping overidding the line that was previously at that location.
sed -i '' '9s?.*?'"$pwd3"'?' $DIR/.tmp/com.monitor.charge.plist
echo "hello" >> test.txt
echo "hello is gone\ngoodbye" > test.txt"
for d in ./*/ ; do (cd "$d" && echo "$d" && echo "hi"); done
One great attribute bash provides is that you can quickly test everything on terminal in a single line of code
In bash everything can be a one liner and copied and pasted directly into terminal.
Bash can be used by other languages such as ruby or node-javascript to in a simple way add functionality to your application.
everything below from source
Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when the function is executed, because a function definition is itself a command. As a consequence, aliases defined in a function are not available until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use alias in compound commands.
For almost every purpose, shell functions are preferred over aliases.
( list )
Placing a list of commands between parentheses causes a subshell environment to be created
{ list; }
Placing a list of commands between curly braces causes the list to be executed in the current shell context.