An Interest In:
Web News this Week
- April 22, 2024
- April 21, 2024
- April 20, 2024
- April 19, 2024
- April 18, 2024
- April 17, 2024
- April 16, 2024
Bash Scripting Concepts: Part 2 of 2
Overview
This is the second part of the tutorial. If not done already, please read the first part: Bash Scripting Concepts: Part 1 of 2
Working with loops
Bash provides three ways of creating loops:
for
: loop for a predefined number of timeswhile
: loop while the exit condition is true. The condition is evaluated before executing tasks.until
: loop until the exit condition is true. The condition is evaluated after executing tasks.
In addition to the loop condition, Bash provides two statements that can be used to control the loop execution flow:
break
: forces the loop to stop.continue
: forces the loop to skip remaining tasks and start the next iteration.
Command: while
In the following example, the loop iterates 5 times. The loop condition is evaluated after all commands in the code block are executed:
#!/bin/bashdeclare -i count=1declare -i max=5while ((count <= max)); do printf 'counter: %s
' "${count}" count=$((count + 1))done
Command: until
Using the same structure as in the while
example, notice that now the loop iterates 4 times only. This is because the loop condition is evaluated before executing the code block:
#!/bin/bashdeclare -i count=1declare -i max=5until ((count == max)); do printf 'counter: %s
' "${count}" count=$((count + 1))done
Command: for
In the case of the for
loop the iteration is predefined. Instead of having a loop condition, the loop variable count
will be assigned each value in the list:
#!/bin/bashdeclare -i countfor count in 1 2 3 4 5 ; do printf 'counter: %s
' "${count}"done
Working with conditionals
Bash provides the following options for implementing conditional execution:
||
: (logical OR) evaluates the execution of two commands and sets the exit status to zero if any associated exit status is zero.&&
: (logical AND) evaluates the execution of two commands and sets the exit status to zero if all associated exit statuses are zero.\!
: (logical NOT) evaluates the execution of a command and sets the exit status to zero if the associated exit status is not zero.(( ))
: performs logical evaluation on the integer expression and sets the exit status to zero if true[[ ]]
: evaluates the literal expression and sets the exit status to zero if true.if
: executes a command and if the exit status is zero then performs additional actions.case
: compares the provided value against a list of patterns and executes the commands upon match.
As mentioned before, Bash interprets the exit status of commands as:
0
: true>0
: false
In the following examples true
and false
are external commands that emulates true and false values (exist status 0 and 1 respectively)
Logical OR: ||
#!/bin/bashtrue || falseprintf 'evaluation result of (true || false): %s
' $?true || trueprintf 'evaluation result of (true || true): %s
' $?false || falseprintf 'evaluation result of (false || false): %s
' $?false || trueprintf 'evaluation result of (false || true): %s
' $?
Logical AND: &&
#!/bin/bashtrue && falseprintf 'evaluation result of (true && false): %s
' $?true && trueprintf 'evaluation result of (true && true): %s
' $?false && falseprintf 'evaluation result of (false && false): %s
' $?false && trueprintf 'evaluation result of (false && true): %s
' $?
Logical NOT: !
#!/bin/bash! trueprintf 'evaluation result of (! true): %s
' $?! falseprintf 'evaluation result of (! false): %s
' $?
Arithmetic Expression Evaluation: (( ))
The (( ))
form accepts several logical operators. Some of them are:
==
: equal!=
: not equal>
: greater than<
: less than>=
: greater than or equal<=
: less than or equal
#!/bin/bashdeclare -i test=$RANDOM(( ${test} > 5000 ))printf 'evaluation result of (( %s > 5000 )): %s
' ${test} $?
Expression Evaluation: [[ ]]
The [[ ]]
form accepts several logical operators and tests. Some of them are:
==
: equal!=
: not equal-z
: string is empty-n
: string is not empty-f
: path is a file
For ==
and !=
the special character *
can be used as a wildcard to match zero or more characters to the right.
#!/bin/bashdeclare test="$RANDOM"[[ "${test}" == 1* ]]printf 'evaluation result of [[ "%s" == 1* ]]: %s
' "${test}" $?
Command: if
In the following example, arithmetic evaluation is used. Notice that quotes are not required within (( ))
#!/bin/bashdeclare -i test=${RANDOM}if (( ${test} >= 10000 )); then printf 'test value (%s) is equal or greater than 10000
' ${test}elif (( ${test} > 5000 || ${test} < 10000 )); then printf 'test value (%s) is between 5001 and 9999
' ${test}else printf 'test value (%s) is less than than 5001
' ${test}fi
Command: case
#!/bin/bashdeclare -i test=${RANDOM}case ${test} in 1*|2*) printf 'Random number (%s) starts with 1 or 2
' ${test};; 3*) printf 'Random number (%s) starts with 3
' ${test};; *) printf 'Random number (%s) does not start with 1,2 or 3
' ${test};;esac
Redirecting data flows
Bash provides two alternatives for establishing data flows:
- Redirection
- Set read source for STDIN
- Set write destination for STDOUT
- Set write destination for STDERR
- Pipelines: integrate two commands by plugging the STDOUT from the first one to the STDIN of the second one
Redirection
In the following example, two functions will communicate with each other using a common file:
#!/bin/bashreadonly DATA_BRIDGE="$(mktemp)"function produce_data() { printf 'produce_data(): write data to the temporary file (%s) by redirectin the STDOUT of the printf command
' "${DATA_BRIDGE}" printf '[sample data]
' >"${DATA_BRIDGE}"}function ingest_data() { printf 'ingest_data(): read data from the temporary file (%s) by redirecting the STDIN of the cat command: ' "${DATA_BRIDGE}" cat < "${DATA_BRIDGE}"}produce_dataingest_datarm -f "${DATA_BRIDGE}"
Pipelines
This example shows an alternative way of integrating both functions using pipelines:
#!/bin/bashfunction produce_data() { printf '[sample data]
'}function ingest_data() { cat}printf 'Integrate functions produce_data() and ingest_data() by piping their STDIN and STDOUT: 'produce_data | ingest_data
Next Steps
Discover advanced features by exploring the Bash Reference Manual:
- jobs
- signals
- traps
- parallelism
- error handling
- configuration settings
Organize your code by choosing a coding style. For example: Google Shell Style Guide
Enhance script's quality by incorporating linter and testing tools:
Copyright information
This article is licensed under a Creative Commons Attribution 4.0 International License. For copyright information on the product or products mentioned inhere refer to their respective owner.
Disclaimer
Opinions presented in this article are personal and belong solely to me, and do not represent people or organizations associated with me in a professional or personal way. All the information on this site is provided "as is" with no guarantee of completeness, accuracy or the results obtained from the use of this information.
Original Link: https://dev.to/serdigital64/bash-scripting-concepts-part-2-of-2-3j0f
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To