Bash if Function Breaks

If yous utilise bash for scripting you volition undoubtedly have to use weather a lot, for case for an if … then construct or a while loop. The syntax of these weather condition can seem a bit daunting to acquire and use. This tutorial aims to help the reader understanding conditions in bash, and provides a comprehensive list of the possibilities. A small amount of full general shell knowledge is causeless.


Accelerate your career in deject

A Cloud Guru makes it easy (and crawly) to level up your cloud career — even if yous're totally new to tech. Cheque out ACG's current free courses or become started now with a free trial.


Difficulty: Basic – Medium

Table of contents

  • What is Bash scripting?
    • Mutual special characters used in Bash
  • Fustigate Programming Introduction
  • The syntax of an bash if statement
  • The basic rules of bash weather
  • Dissimilar condition syntaxes
    • 1. Unmarried-bracket syntax
    • 2. Double-bracket syntax
    • 3. Double-parenthesis syntax
  • Table of conditions
  • Diving a little deeper
  • Conclusion

What is Fustigate scripting?

Earlier we starting time, permit's brand sure we're all on the same folio. What is Fustigate scripting? A simple way to recall of Fustigate scripts is to call back of them like movie scripts. They tell actors what to say at what time, right? Well, Bash scripts tell Bash what to do at what time.

Fustigate scripts are a elementary text file contained a serial of commands we want to automate running rather than running them manually.

Ane matter to recall that's easy to forget: When writing your own Bash script, you have to remember to ready the execute bit on a file before we effort to tun the script.

Common special characters used in Bash

" " or ' ' Denotes whitespace. Single quotes preserve literal meaning; double quotes allow substitutions.
$ Denotes an expansion (for utilise with variables, command commutation, arithmetics substitution, etc.)
\ Escape character. Used to remove "specialness" from a special character.
# Comments. Anything later this grapheme isn't interpreted.
= Assignment
[ ] or [[ ]] Test; evaluates for either true or false
! Negation
>>, >, < Input/output redirection
| Sends the output of i command to the input of some other.
* or ? Globs (aka wildcards). ? is a wildcard for a single character.

Bash Programming Introduction

Bash features a lot of built-in checks and comparisons, coming in quite handy in many situations. You lot've probably seen if statements similar the following before:

          if [ $foo -ge 3 ]; and then        

The condition in this case is essentially a command. Information technology may audio foreign, but surrounding a comparing with square brackets is the same as using the built-in examination command, similar this:

          if test $foo -ge 3; so        

If $foo is Greater then or Equal to 3, the cake after 'then' will be executed. If you always wondered why bash tends to use -ge or -eq instead of >= or ==, it's considering this status type originates from a control, where -ge and -eq are options.

And that's what if does essentially, checking the get out status of a command. I'll explain that in more than detail further in the tutorial.There besides are born checks that are more than specific to shells. Whatabout this one?

          if [ -f regularfile ]; then        

The above condition is true if the file 'regularfile' exists andis a regular file. A regular file means that information technology's not a block orcharacter device, or a directory. This way, you lot can brand sure a usablefile exists before doing something with it. You can fifty-fifty check if afile is readable!

          if [ -r readablefile]; so        

The higher up condition is true if the file 'readablefile' exists and is readable. Easy, isn't it?

The syntax of an bash if statement

The basic syntax of an if … so statement is like this:

          if            <condition>; and so<commands>fi        

The status is, depending on its type, surrounded by certainbrackets, eg. [ ]. Y'all tin can read about the unlike types further onin the tutorial. You can add commands to exist executed when the status is false using the else keyword, and use the elif (elseif) keyword to execute commands on another condition if the primary status is false. The else keyword ever comes terminal. Example:

          if [ -r somefile ]; and then        content=$(cat somefile)elif [ -f somefile ]; so        repeat "The file 'somefile' exists just is not readable to the script."else        echo "The file 'somefile' does not exist."fi        

A short explanation of the example: beginning we check if the file somefile is readable ("if [ -r somefile ]"). If so, nosotros read it into a variable. If non, we check if it really exists ("elif [ -f somefile ]"). If that'southward true, nosotros written report that it exists simply isn't readable (if it was, we would have read the content). If the file doesn't exist, we report and then, too. The condition at elif is only executed if the status at if was false. The commands belonging to else are only executed if both conditions are imitation.


Complete guide to the Cloud and Dictionary

Get the Cloud Dictionary of Hurting
Speaking cloud doesn't have to be hard. Nosotros analyzed millions of responses to ID the height terms and concepts that trip students upwards. In this cloud guide, you'll find succinct definitions of some of the most painful cloud terms.


The bones rules of bash atmospheric condition

When you start writing and using your own atmospheric condition, in that location are some rules y'all should know to preclude getting errors that are hard to trace. Hither follow three of import ones:

  1. E'er keep spaces betwixt the brackets and the bodily bank check/comparing. The post-obit won't piece of work:
                  if [$foo -ge 3]; and so            

    Bash will complain virtually a "missing `]'".

  2. Ever end the line before putting a new keyword similar "so". The words if, then, else, elif and fi are beat out keywords, pregnant that they cannot share the same line. Put a ";" between the previous argument and the keyword or place the keyword on the offset of a new line. Fustigate volition throw errors like "syntax error virtually unexpected token `fi'" if y'all don't.
  3. It is a good habit to quote string variables if you lot use them in conditions, because otherwise they are likely to requite trouble if they containspaces and/or newlines. By quoting I mean:
                  if [ "$stringvar" == "tux" ]; then            

    There are a few cases in which you should notquote, only they are rare. You lot will see 1 of them farther on in the tutorial.

Also, there are ii things that may be useful to know:

  1. You tin can invert a condition by putting an "!" in front end of it. Case:
                  if [ ! -f regularfile ]; then            

    Exist sure to place the "!" within the brackets!

  2. You can combine weather by using certain operators. For the single-subclass syntax that we've been using so far, y'all can use "-a" for and and "-o" for or. Example:
                  if [ $foo -ge three -a $foo -lt 10 ]; then            

    The above condition will return true if $foo contains an integer greater than or equal to 3 and Less Than 10. Yous tin read more about these combining expressions at the respective condition syntaxes.

And, one more bones matter: don't forget that weather condition can likewise exist used in other statements, like while and until. It is outside the scope of this tutorial to explicate those, but you tin read nearly them at the Fustigate Guide for Beginners.

Anyway, I've only shown you lot weather betwixt single brackets so far. There are more syntaxes, even so, equally you lot volition read in the next section.

Different condition syntaxes

Bash features different syntaxes for conditions. I will list the iii of them:

ane. Single-subclass syntax

This is the condition syntax you take already seen in the previous paragraphs; it'south the oldest supported syntax. It supports three types of atmospheric condition:

  • File-based weather condition
    • Allows different kinds of checks on a file. Instance:
                        if [ -50 symboliclink ]; then                

      The in a higher place status is true if the file 'symboliclink' exists and is a symbolic link. For more than file-based conditions run across the table below.

  • String-based conditions
    • Allows checks on a string and comparing of strings. Example i:
                        if [ -z "$emptystring" ]; and then                

      The above condition is true if $emptystring is an empty string or an uninitialized variable. Example ii:

                        if [ "$stringvar1" == "cheese" ]; and then                

      The higher up condition is truthful if $stringvar1 contains just the string "cheese". For more string-based conditions meet the table below.

  • Arithmetic (number-based) conditions
    • Allows comparing integer numbers. Example:
                        if [ $num -lt 1 ]; then                

      The above condition returns true if $num is less than 1. For more than arithmetic conditions see the table beneath.

2. Double-bracket syntax

You may take encountered conditions enclosed in double square brackets already, which wait like this:

          if [[ "$stringvar" == *string* ]]; then        

The double-bracket syntax serves equally an enhanced version of the single-bracket syntax; information technology mainly has the same features, but also some of import differences with it. I will list them here:

  • The first difference tin can be seen in the above example; when comparing strings, the double-bracket syntax features trounce globbing. This means that an asterisk ("*") will expand to literally annihilation, merely as you probably know from normal control-line usage. Therefore, if $stringvar contains the phrase "string" anywhere, the condition will return true. Other forms of beat out globbing are allowed, too. If you'd like to match both "String" and "string", y'all could use the following syntax:
                  if [[ "$stringvar" == *[sS]tring* ]]; then            

    Annotation that merely general beat globbing is immune. Fustigate-specific things like {1..4} or {foo,bar} will not work. As well note that the globbing will not work if you quote the right string. In this case you should leave information technology unquoted.

  • The 2nd difference is that word splitting is prevented. Therefore, you could omit placing quotes around string variables and use a condition like the following without problems:
                  if [[ $stringvarwithspaces != foo ]]; then            

    Nevertheless, the quoting string variables remains a adept addiction, and then I recommend just to keep doing it.

  • The third difference consists of non expanding filenames. I will illustrate this difference using two examples, starting with the old unmarried-bracket state of affairs:
                  if [ -a *.sh ]; then            

    The in a higher place condition will return truthful if there is 1 single file in the working directory that has a .sh extension. If in that location are none, information technology will return false. If there are several .sh files, bash volition throw an error and finish executing the script. This is because *.sh is expanded to the files in the working directory. Using double brackets prevents this:

                  if [[ -a *.sh ]]; and so            

    The to a higher place condition will return true only if at that place is a file in the working directory chosen "*.sh", no matter what other .sh files exist. The asterisk is taken literally, because the double-bracket syntax does non expand filenames.

  • The fourth difference is the improver of more generally known combining expressions, or, more specific, the operators "&&" and "||". Instance:
                  if [[ $num -eq iii && "$stringvar" == foo ]]; then            

    The to a higher place condition returns truthful if $num is equal to 3 and $stringvar is equal to "foo". The -a and -o known from the single-bracket syntax is supported, too.Note that the and operator has precedence over the or operator, significant that "&&" or "-a" will be evaluated earlier "||" or "-o".

  • The fifth difference is that the double-bracket syntax allows regex pattern matching using the "=~" operator. See the table for more data.

3. Double-parenthesis syntax

At that place as well is another syntax for arithmetics (number-based) conditions, most likely adopted from the Korn vanquish:

          if (( $num <= v )); so        

The above status is true if $num is less than or equal to 5. This syntax may seem more familiar to programmers. It features all the 'normal' operators, like "==", "<" and ">=". Information technology supports the "&&" and "||" combining expressions (but non the -a and -o ones!). It is equivalent to the built-in let control.

Table of conditions

The post-obit table listing the condition possibilities for both the single- and the double-bracket syntax. Salvage a unmarried exception, the examples are given in unmarried-bracket syntax, simply are e'er compatible with double brackets.

 i. File-based atmospheric condition:

Condition True if Example/caption
[ -a existingfile ] file 'existingfile' exists. if [ -a tmp.tmp ]; thenrm -f tmp.tmp # Make sure we're not bothered by an old temporary filefi
[ -b blockspecialfile ] file 'blockspecialfile' exists and is block special. Cake special files are special kernel files institute in /dev, mainly used for ATA devices similar difficult disks, cd-roms and floppy disks.if [ -b /dev/fd0 ]; thendd if=floppy.img of=/dev/fd0 # Write an image to a floppyfi
[ -c characterspecialfile ] file 'characterspecialfile' exists and is grapheme special. Character special files are special kernel files constitute in /dev, used for all kinds of purposes (sound hardware, tty'due south, simply also /dev/null).if [ -c /dev/dsp ]; thencat raw.wav > /dev/dsp # This actually works for certain raw wav filesfi
[ -d directory ] file 'directory' exists and is a directory. In UNIX-style, directories are a special kind of file.if [ -d ~/.kde ]; thenecho "You seem to be a kde user."fi
[ -east existingfile ] file 'existingfile' exists. (same as -a, meet that entry for an example)
[ -f regularfile ] file 'regularfile' exists and is a regular file. A regular file is neither a block or character special file nor a directory.if [ -f ~/.bashrc ]; thensource ~/.bashrcfi
[ -g sgidfile ] file 'sgidfile' exists and is set-group-ID. When the SGID-bit is prepare on a directory, all files created in that directory will inherit the group of the directory.if [ -g . ]; thenecho "Created files are inheriting the group '$(ls -ld . | awk '{ print $iv }')' from the working directory."fi
[ -G fileownedbyeffectivegroup ] file 'fileownedbyeffectivegroup' exists and is owned past the constructive group ID. The constructive group id is the main group id of the executing user.if [ ! -G file ]; and so # An assertion mark inverts the issue of the condition following itchgrp $(id -thou) file # Change the group if it's not the effective onefi
[ -h symboliclink ] file 'symboliclink' exists and is a symbolic link. if [ -h $pathtofile ]; thenpathtofile=$(readlink -east $pathtofile) # Make sure $pathtofile contains the bodily file and not a symlink to itfi
[ -chiliad stickyfile ] file 'stickyfile' exists and has its glutinous bit set up. The gluey chip has got quite a history, but is now used to forestall world-writable directories from having their contents deletable by anyone.if [ ! -chiliad /tmp ]; then # An exclamation marker inverts the consequence of the status following information technologyecho "Warning! Anyone tin can delete and/or rename your files in /tmp!"fi
[ -L symboliclink ] file 'symboliclink' exists and is a symbolic link. (same as -h, see that entry for an example)
[ -N modifiedsincelastread ] file 'modifiedsincelastread' exists and was modified afterward the last read. if [ -N /etc/crontab ]; thenkillall -HUP crond # SIGHUP makes crond reread all crontabsfi
[ -O fileownedbyeffectiveuser ] file 'fileownedbyeffectiveuser' exists and is owned by the user executing the script. if [ -O file ]; thenchmod 600 file # Makes the file individual, which is a bad idea if you don't own itfi
[ -p namedpipe ] file 'namedpipe' exists and is a named piping. A named pipe is a file in /dev/fd/ that tin be read just once. See my fustigate tutorial for a example in which it's used.if [ -p $file ]; thencp $file tmp.tmp # Brand certain nosotros'll exist able to readfile="tmp.tmp"    # the file as many times as nosotros likefi
[ -r readablefile ] file 'readablefile' exists and is readable to the script. if [-r file ]; thencontent=$(true cat file) # Gear up $content to the content of the filefi
[ -s nonemptyfile ] file 'nonemptyfile' exists and has a size of more than than 0 bytes. if [ -s logfile ]; thengzip logfile    # Backup the old logfiletouch logfile # before creating a fresh one.fi
[ -S socket ] file 'socket' exists and is a socket. A socket file is used for inter-process advice, and features an interface similar to a network connectedness.if [ -Southward /var/lib/mysql/mysql.sock ]; thenmysql –socket=/var/lib/mysql/mysql.sock # See this MySQL tipfi
[ -t openterminal ] file descriptor 'openterminal' exists and refers to an open last. Most everything is washed using files on Linux/UNIX, and the last is no exception.if [ -t /dev/pts/three ]; thenecho -e "nHello there. Message from terminal $(tty) to you." > /dev/pts/3 # Anyone using that final will actually see this message!fi
[ -u suidfile ] file 'suidfile' exists and is ready-user-ID. Setting the suid-bit on a file causes execution of that file to be done with the credentials of the owner of the file, non of the executing user.if [ -u executable ]; thenecho "Running programme executable equally user $(ls -l executable | awk '{ print $three }')."fi
[ -w writeablefile ] file 'writeablefile' exists and is writeable to the script. if [ -w /dev/hda ]; thengrub-install /dev/hdafi
[ -x executablefile ] file 'executablefile' exists and is executable for the script. Note that the execute permission on a directory ways that information technology's searchable (you tin can see which files it contains).if [ -ten /root ]; thenecho "You tin can view the contents of the /root directory."fi
[ newerfile -nt olderfile ] file 'newerfile' was inverse more than recently than 'olderfile', or if 'newerfile' exists and 'olderfile' doesn't. if [ story.txt1 -nt story.txt ]; thenecho "story.txt1 is newer than story.txt; I advise standing with the former."fi
[ olderfile -ot newerfile ] file 'olderfile' was changed longer ago than 'newerfile', or if 'newerfile' exists and 'olderfile' doesn't. if [ /mnt/remote/remotefile -ot localfile ]; thencp -f localfile /mnt/remote/remotefile # Make sure the remote location has the newest version of the file, toofi
[ same -ef file ] file 'same' and file 'file' refer to the same device/inode number. if [ /dev/cdrom -ef /dev/dvd ]; thenecho "Your primary cd drive appears to read dvd'southward, too."fi

 2. String-based weather condition:

Condition True if Example/explanation
[ STRING1 == STRING2 ] STRING1 is equal to STRING2. if [ "$i" == "moo" ]; thenecho $cow # E'er tried executing 'apt-get moo'?fiNote: you can likewise employ a single "=" instead of a double ane.
[ STRING1 != STRING2 ] STRING1 is non equal to STRING2. if [ "$userinput" != "$password" ]; thenecho "Access denied! Wrong password!"exit 1 # Stops script execution correct hitherfi
[ STRING1 > STRING2 ] STRING1 sorts after STRING2 in the electric current locale (lexographically). The backslash earlier the angle bracket is there because the subclass needs to be escaped to be interpreted correctly. As an example nosotros have a bones chimera sort:(Don't feel ashamed if you don't understand this, it is a more than complex example)array=( linux tutorial blog )swaps=1while (( swaps > 0 )); doswaps=0for (( i=0; i < (( ${#array[@]} – i )) ; i++ )); doif [ "${array[$i]}" > "${array[$(( i + ane ))]}" ]; and then # Here is the sorting conditiontempstring=${assortment[$i]}assortment[$i]=${array[$(( i + 1 ))]}array[$(( i + 1 ))]=$tempstring(( swaps=swaps + ane ))fidonedoneecho ${assortment[@]} # Returns "blog linux tutorial"
[ STRING1 < STRING2 ] STRING1 sorts earlier STRING2 in the electric current locale (lexographically).
[ -n NONEMPTYSTRING ] NONEMPTYSTRING has a length of more than zero. This condition only accepts valid strings, and then be certain to quote anything you requite to it.if [ -n "$userinput" ]; thenuserinput=parse($userinput) # Only parse if the user actually gave some input.fiNote that you can also omit the "-n", as brackets with only a string in it conduct the same.
[ -z EMPTYSTRING ] EMPTYSTRING is an empty string. This condition also accepts non-string input, like an uninitialized variable:if [ -z $uninitializedvar ]; thenuninitializedvar="initialized" # -z returns true on an uninitialized variable, and then we initialize it here.fi
Double-bracket syntax only:[[ STRING1 =~ REGEXPATTERN ]] STRING1 matches REGEXPATTERN. If you are familiar with Regular Expressions, you can use this weather condition to perform a regex friction match.if [[ "$email" =~ "b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,four}b" ]]; thenecho "$email contains a valid e-mail address."fi

 three. Arithmetic (number-based) conditions:

Status Truthful if Example/caption
[ NUM1 -eq NUM2 ] NUM1 is EQual to NUM2. These conditions simply take integer numbers. Strings will be converted to integer numbers, if possible. Some random examples:if [ $? -eq 0 ]; and then # $? returns the exit status of the previous controlrepeat "Previous command ran succesfully."fiif [ $(ps -p $pid -o ni=) -ne $(dainty) ]; thenecho "Procedure $pid is running with a non-default squeamish value"fiif [ $num -lt 0 ]; thenecho "Negative numbers not allowed; exiting…"exit 1fi
[ NUM1 -ne NUM2 ] NUM1 is Not Due eastqual to NUM2.
[ NUM1 -gt NUM2 ] NUM1 is Grandreater Than NUM2.
[ NUM1 -ge NUM2 ] NUM1 is Greater than or Eastwardqual to NUM2.
[ NUM1 -lt NUM2 ] NUM1 is Less Than NUM2.
[ NUM1 -le NUM2 ] NUM1 is Less than or Eastqual to NUM2.

iv. Miscellaneous conditions:

Condition True if Case/explanation
[ -o shelloption ] shell selection 'shelloption' is enabled. Shell options modify the behaviour of bash, except a few unmodifiable ones that signal the shell condition.if [ ! -o checkwinsize ] # An assertion marker inverts the outcome of the condition following information technologyecho "Shell option checkwinsize is disabled; enabling it and then you can resize you terminal window without problems."shopt -south checkwinsize # This shell selection is modifiablefiif [ -o login_shell ]; thenecho "This a a login shell." # This crush option is non modifiablefi

With the double-parenthesis syntax, you lot can utilize the post-obit conditions:

5. Double-parenthesis syntax conditions:

Condition True if Instance/caption
(( NUM1 == NUM2 )) NUM1 is equal to NUM2. These atmospheric condition only accept integer numbers. Strings volition be converted to integer numbers, if possible. Some random examples:if (( $? == 0 )); then # $? returns the leave condition of the previous controlrepeat "Previous control ran succesfully."fiif (( $(ps -p $pid -o ni=) != $(nice) )); thenecho "Process $pid is running with a non-default squeamish value"fiif (( $num < 0 )); thenecho "Negative numbers not immune; exiting…"leave 1fi
(( NUM1 != NUM2 )) NUM1 is not equal to NUM2.
(( NUM1 > NUM2 )) NUM1 is greater than NUM2.
(( NUM1 >= NUM2 )) NUM1 is greater than or equal to NUM2.
(( NUM1 < NUM2 )) NUM1 is less than NUM2.
(( NUM1 <= NUM2 )) NUM1 is less than or equal to NUM2.

After this dry data load, hither's a scrap of explanation for those who desire to know more…

Diving a little deeper

I said I'd tell more about the fact that if essentially checks the exit status of commands. And and so I will.

The basic dominion of bash when it comes to weather is 0 equals true, >0 equals simulated.

That's pretty much the opposite of many programming languages where 0 equals false and one (or more) equals truthful. The reason behind this is that shells like fustigate deal with programs a lot. Past UNIX convention, programs use an exit status for indicating whether execution went alright or an error occured. Equally a succesful execution doesn't crave any explanation, it needs only one go out condition. If there was a trouble, however, it is useful to know what went wrong. Therefore, 0 is used for a succesful execution, and 1-255 to indicate what kind of error occured.

The meaning of the numbers 1-255 differs depending on the plan returning them.

Anyway, if executes the block afterwards then when the control returns 0. Yeah, conditions are commands. The phrase [ $foo -ge 3 ] returns an leave condition, and the other 2 syntaxes equally well! Therefore, there's a neat play tricks you tin can use to quickly test a status:

          [ $foo -ge 3 ] && echo true        

In this example, "echo true" is only executed if "[ $foo -ge iii ]" returns 0 (true). Why is that, y'all might ask. It's because bash only evaluates a condition when needed. When using the and combining expression, both conditions need to be true to make the combining expression return true. If the beginning status returns faux, it doesn't affair what the 2nd one returns; the upshot will be fake.

Therefore, bash doesn't evaluate the second status, and that's the reason why "echo true" is not executed in the example. This is the same for the or operator ("||"), where the 2nd condition is not evaluated if the starting time one is true.Well, then much for the diving.

If you desire to know even more than, I'd like to betoken you lot to the Advanced Bash-Scripting Guide and maybe the Bash Reference Manual. You can besides bank check out our course the System Administrator's Guide to Bash Scripting.

Conclusion

In this tutorial, you've been able to make a start at agreement the many possibilities of conditions in bash scripting. You've been able to read about the bones rules of writing and using weather condition, about the three syntaxes and their properties, and perchance you took the opportunity to dive a trivial deeper.

I hope you enjoyed the reading every bit much every bit I enjoyed the writing. You can ever return here to look upwards weather in the table (bookmark that link to run across the table directly), or to refresh your knowledge. Thanks for reading and happy scripting!

Looking to level up your tech game? Subscribe to A Cloud Guru on YouTube, like the states on Facebook, follow us on Twitter, or join the chat on Discord!

vogelclany1972.blogspot.com

Source: https://acloudguru.com/blog/engineering/conditions-in-bash-scripting-if-statements

0 Response to "Bash if Function Breaks"

Enregistrer un commentaire

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel