BASH shell scripts are essentially a series of bash commands that are stored in a file that can be executed by running the script.
hello-world.sh
#!/bin/bash# This is a commentecho"Hello world"
#!/bin/bash - the first line says the script should be run using bash
#! = shebang
# = pound/hash - used for comments
There are a few ways to execute the script:
bashhello-world.shHelloworld# bash is the executable program# To start the script without "bash" command, the script must be executablechmod+xhello-world.sh./hello-world.shHelloworld
executing-commands-example.sh
#!/bin/bash# ************************************# Executing commands example# Execute whoami commanduser=$(whoami)# Execute hostname commandhostname=$(hostname)# Execute print working directory (pwd) commanddirectory=$(pwd)# Display informationecho"User=[$user] Host=[$hostname] Working dir=[$directory]"# Display contents of directoryecho"Contents:"ls
Conditionals allow the script to take different actions depending on some sort of state, referred to as if-then rules.
if-examples.sh
if statements.
The expression inside the brackets [[ ... ]] is evaluated and used to determine if the conditional code is executed.
If the expression evaluates to TRUE, the block (the code inside the IF statement) is executed.
If the expression evaluates to FALSE, BASH skips over all of the conditional code and starts execute after the "fi" keyword.
else statements
Code inside the else block is executed if the test returns FALSE.
elif statements (else-if)
If the first test in the if statement fails, the elif statement will be evaluated.
elif statements will be tested from top down.
the code block associated with the first TRUE evaluated test will be executed and the rest of the conditional will be skipped.
#!/bin/bash# ************************************# If examples# Test to see if /etc is a directoryif [[ -d /etc/ ]]; thenecho/etc/isindeedadirectoryfi# Check to see if a file existsif [[ -e sample.txt ]]; thenechoThefilesample.txtexistselseechoThefilesample.txtdoesNOTexistfi# Check a variable's valueTEST_VAR="test"if [[ $TEST_VAR =="test" ]]; thenechoTEST_VARhasavalueof"test"elif [[ $TEST_VAR =="again" ]]; thenechoTEST_VARhasavalueof"again"elseechoTEST_VARhasanunknownvaluefi
A case statement is essentially an if statement with multiple elif statements.
it uses a command line argument - $1
#!/bin/bash# ************************************# Case example# Switch off of the first command line argumentcase $1 in[1-3]) message="Argument is between 1 and 3 inclusive" ;;[4-6]) message="Argument is between 4 and 6 inclusive" ;;[7-9]) message="Argument is between 7 and 9 inclusive" ;;1[0-9]) message="Argument is between 10 and 19 inclusive" ;;*) message="I don't understand the argument or it is missing" ;;esac# Print out a message describing the resultecho $message
bashcase-example.sh6Argumentisbetween4and6inclusivebashcase-example.sh22Idon't understand the argument or it is missing
Loops
Loops allow to write code once and execute it multiple times.
Definite loops
know the number of loops (times it is executed) before the loop ever starts.
most common: for loop
Indefinite loops
unknown number of loops until the end (it depends on the user input for example).
most common: while loop
Infinite loops
loops that never end (whether by design or accident), != indefinite loops
loop-examples.sh
#!/bin/bash# ************************************# For loop examplesecho-----------------------------------echoForloops# Iterate through the numbers 1 through 5 and print them outechoPrintoutahard-codedsequencefor i in12345; doechoIndex=[$i]done# Same as above, but generate the sequenceechoPrintoutageneratedsequencefor i in {1..5}; doechoIndex=[$i]done# Same as above, but use a more conventional format# NOTE: Double parenthesis are used since we are doing arithmeticechoPrintoutageneratedsequenceusingthe3-expressionformatfor(( i=1; i<=5; i++ ))doechoIndex=[$i]done# Print out the last line of each shell script in the current directoryechoPrintoutthelastlineofeachshellscriptfor FILE in*.shdoecho=====================================echoFile=[$FILE]tail-n1 $FILEdoneecho''# ************************************# While loop exampleecho-----------------------------------echoWhileloop# Countdown to blastoffechoExecutingawhilelooptocountdowntoblastoffcounter=5while [[ $counter -gt0 ]]; doechoCountdown [$counter] counter=$(($counter - 1))doneechoBlastoff
#!/bin/bash# ******************************************************************************# Processing command line arguments# What is the name of the executed script?echoNameofscript [$0]# How many were provided?echoCommandlineargumentcount [$#]# Iterate through each argumentfor arg in $@; doechoArgument [$arg]done# Display all the arguments as a stringechoAllarguments [$*]# Use parenthesis for arguments with numbers 10 or largerif [ "${12}"!="" ]; thenechoArgument12is [${12}]echoArgument12isNOT [$12]fi
This script generates a password by combining a specified number of words.
Each word is capitalized and separated by a separator character provided as a command line argument.
#!/bin/bash# Grab the command line argumentspasswd_word_count=$1separator=$2# Start with a blank passwordpassword=''# Get the total number of words in the word listtotal_word_count=`wc-lwordlist.txt|awk '{print $1;}'`# Build the password using the specified number of wordsfor (( i=1; i<=$passwd_word_count; i++ ))do# Generate a random number using OpenSSL to be cryptographically secure rand_num_hex=`opensslrand-hex4` rand_num_dec=$((16#$rand_num_hex))# Use the random number as an index into the word list word_index=$(($rand_num_dec % $total_word_count)) random_word=`awk-vidx="$word_index" '{if (NR==idx) print $1}' wordlist.txt`# Capitalize the word random_word_upper=`echo ${random_word^}`# Insert a separator if this isn't the first word in the passwordif [[ ${#password} -gt0 ]]; then password=$password$separator$random_word_upperelse password=$random_word_upperfidone# Display the passwordecho $password