Get into the habit of writing shell scripts in a structured and systematic manner. Even "on-the-fly" and "written on the back of an envelope" scripts will benefit if you take a few minutes to plan and organize your thoughts before sitting down and coding.
Herewith are a few stylistic guidelines. This is not intended as an Official Shell Scripting Stylesheet.
Comment your code. This makes it easier for others to understand (and appreciate), and easier for you to maintain.
1 PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
2 # It made perfect sense when you wrote it last year, but now it's a complete mystery.
3 # (From Antek Sawicki's "pw.sh" script.) |
Add descriptive headers to your scripts and functions.
1 #!/bin/bash 2 3 #************************************************# 4 # xyz.sh # 5 # written bpTT CLASS="COMPUTEROUTPUT" >bash: type: ]: not found |
If, for some reason, you wish to use /usr/bin/test in a Bash script, then specify it by full pathname.
Example 7-2. Equivalence of test, /usr/bin/test, [ ], and /usr/bin/[
1 #!/bin/bash 2 3 echo 4 5 if test -z "$1" 6 then 7 echo "No command-line arguments." 8 else 9 echo "First command-line argument is $1." 10 fi 11 12 echo 13 14 if /usr/bin/test -z "$1" # Equivalent to "test" builtin. 15 # ^^^^^^^^^^^^^ # Specifying full pathname. 16 then 17 echo "No command-line arguments." 18 else 19 echo "First command-line argument is $1." 20 fi 21 22 echo 23 24 if [ -z "$1" ] # Functionally identical to above code blocks. 25 # if [ -z "$1" should work, but... 26 #+ Bash responds to a missing close-bracket with an error message. 27 then 28 echo "No command-line arguments." 29 else 30 echo "First command-line argument is $1." 31 fi 32 33 echo 34 35 36 if /usr/bin/[ -z "$1" ] # Again, functionally identical to above. 37 # if /usr/bin/[ -z "$1" # Works, but gives an error message. 38 # # Note: 39 # This has been fixed in Bash, version 3.x. 40 then 41 echo "No command-line arguments." 42 else 43 echo "First command-line argument is $1." 44 fi 45 46 echo 47 48 exit 0 |
The [[ ]] construct is the more versatile Bash version of [ ]. This is the extended test command, adopted from ksh88.
![]() | No filename expansion or word splitting takes place between [[ and ]], but there is parameter expansion and command substitution. |
1 file=/etc/passwd 2 3 if [[ -e $file ]] 4 then 5 echo "Password file exists." 6 fi |
![]() | Using the [[ ... ]] test construct, rather than [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, <, and > operators work within a [[ ]] test, despite giving an error within a [ ] construct. |
![]() | Following an if, neither the test command nor the test brackets ( [ ] or [[ ]] ) are strictly necessary.
Similarly, a condition within test brackets may stand alone without an if, when used in combination with a list construct.
|
The (( )) construct expands and evaluates an arithmetic expression. If the expression evaluates as zero, it returns an exit status of 1, or "false". A non-zero expression returns an exit status of 0, or "true". This is in marked contrast to using the test and [ ] constructs previously discussed.
Example 7-3. Arithmetic Tests using (( ))
1 #!/bin/bash 2 # Arithmetic tests. 3 4 # The (( ... )) construct evaluates and tests numerical expressions. 5 # Exit status opposite from [ ... ] construct! 6 7 (( 0 )) 8 echo "Exit status of \"(( 0 ))\" is $?." # 1 9 10 (( 1 )) 11 echo "Exit status of \"(( 1 ))\" is $?." # 0 12 13 (( 5 > 4 )) # true 14 echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0 15 16 (( 5 > 9 )) # false 17 echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1 18 19 (( 5 - 5 )) # 0 20 echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1 21 22 (( 5 / 4 )) # Division o.k. 23 echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0 24 25 (( 1 / 2 )) # Division result < 1. 26 echo "Exit status of \"(( 1 / 2 ))\" is $?." # Rounded off to 0. 27 # 1 28 29 (( 1 / 0 )) 2>/dev/null # Illegal division by 0. 30 # ^^^^^^^^^^^ 31 echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1 32 33 # What effect does the "2>/dev/null" have? 34 # What would happen if it were removed? 35 # Try removing it, then rerunning the script. 36 37 exit 0 |