directory

  1. Basic commands
  2. variable
  3. Create and run the script
  4. conditions
  5. cycle
  6. function
  7. Others (read, mktemp, Trap)

Conditions of structure

If conditional structure

If is the most commonly used conditional judgment structure, and the specified command is executed only if a given condition is met. Its syntax is as follows.

if commands; then commands [elif commands; then commands...]  [else commands] fiCopy the code

This command is divided into three parts: if, elif, and else. The latter two parts are optional.

#! /bin/bashEcho -n ">" read character if ["$character" = "1"]; then echo 1 elif [ "$character" = "2" ]; then echo 2 elif [ "$character" = "3" ]; Then echo 3 else Echo The input is invalid FICopy the code

In the example above, if the user types in 3, it checks three times in a row.

The test command

The judgment condition of the if structure, generally using the test command, has three forms.

#Writing a
test expression

#Write two
[ expression ]

#Write three
[[ expression ]]
Copy the code

The three forms of the test command are equivalent, but the third form supports the regular test. The first two do not.

Expression is an expression. If true, the test command is executed successfully (the return value is 0). If false, the test command fails (the return value is 1). Note that in the second and third forms, there must be a space between [and] and the inner expression.

#Writing a
if test -e /tmp/foo.txt ; then
  echo "Found foo.txt"
fi

#Write two
if [ -e /tmp/foo.txt ] ; then
  echo "Found foo.txt"
fi

#Write three
if [[ -e /tmp/foo.txt ]] ; then
  echo "Found foo.txt"
fi
Copy the code

Judgment expression

The if keyword is followed by a command. This command can be the test command or any other command. If the return value of the command is 0, the check is true. If the return value is not 0, the check is not true. Because these commands are primarily for return values, they can be treated as expressions.

Common judgment expressions include the following.

  1. File to judge

The following expression is used to determine file status.

  • [ -a file ]: If file existstrue.
  • [ -b file ]: if file exists and is a block (device) filetrue.
  • [ -c file ]: if file exists and is a character (device) filetrue.
  • [ -d file ]: if file exists and is a directorytrue.
  • [ -e file ]: If file existstrue.
  • [ -f file ]: if file exists and is a normal filetrue.
  • [ -g file ]: If file exists and the group ID is settrue.
  • [ -G file ]: if file exists and belongs to a valid group IDtrue.
  • [ -h file ]: if file exists and is a symbolic linktrue.
  • [ -k file ]: If file exists and its sticky bit is settrue.
  • [ -L file ]: if file exists and is a symbolic linktrue.
  • [ -N file ]: if file exists and has been modified since the last readtrue.
  • [ -O file ]: If file exists and belongs to a valid user IDtrue.
  • [ -p file ]: if file exists and is a named pipetrue.
  • [ -r file ]: If file exists and is readable (the current user has read permission)true.
  • [ -s file ]: If file exists and its length is greater than zerotrue.
  • [ -S file ]: If file exists and is a network sockettrue.
  • [ -t fd ]: if fd is a file descriptor and is redirected to a terminaltrue. This can be used to determine if the standard input/output/error has been redirected.
  • [ -u file ]: If file exists and the setuid bit is settrue.
  • [ -w file ]: If file exists and is writable (the current user has writable permission)true.
  • [ -x file ]: if file exists and is executable (valid user has execute/search permission)true.
  • [ file1 -nt file2 ]: If FILE1 is updated more recently than FILE2 or FILE1 exists but FILE2 does nottrue.
  • [ file1 -ot file2 ]: If FILE1 is older than FILE2, or FILE2 exists but FILE1 does nottrue.
  • [ FILE1 -ef FILE2 ]: If FILE1 and FILE2 reference the same device and inode numbertrue.

Here is an example.

#! /bin/bash

FILE=~/.bashrc

if [ -e "$FILE" ]; then
  if [ -f "$FILE" ]; then
    echo "$FILE is a regular file."
  fi
  if [ -d "$FILE" ]; then
    echo "$FILE is a directory."
  fi
  if [ -r "$FILE" ]; then
    echo "$FILE is readable."
  fi
  if [ -w "$FILE" ]; then
    echo "$FILE is writable."
  fi
  if [ -x "$FILE" ]; then
    echo "$FILE is executable/searchable."
  fi
else
  echo "$FILE does not exist"
  exit 1
fi
Copy the code

In the above code, $FILE is placed in double quotes. This prevents $FILE from being empty, because then [-e] is judged to be true. When placed in double quotes, an empty string is always returned, and [-e “”] is judged to be false.

  1. String judgment

The following expression is used to determine strings.

  • [ string ]If:stringIf it is not null (length greater than 0), it is judged to be true.
  • [ -n string ]: If stringstringIf the length of is greater than zero, it is true.
  • [ -z string ]: If stringstringIf the length of is zero, it is judged true.
  • [ string1 = string2 ]If:string1andstring2If they are the same, it is true.
  • [ string1 == string2 ]Is equivalent to[ string1 = string2 ].
  • [ string1 != string2 ]If:string1andstring2If they are not the same, they are judged to be true.
  • [ string1 '>' string2 ]: in dictionary orderstring1Arranged instring2After that, it is judged true.
  • [ string1 '<' string2 ]: in dictionary orderstring1Arranged instring2Before, it is judged true.

Note that the > and < inside the test command must be enclosed in quotes (or escaped with backslashes). Otherwise, they are interpreted by the shell as redirection operators.

Here is an example.

#! /bin/bash

ANSWER=maybe

if [ -z "$ANSWER" ]; then
  echo "There is no answer." >&2
  exit 1
fi
if [ "$ANSWER" = "yes" ]; then
  echo "The answer is YES."
elif [ "$ANSWER" = "no" ]; then
  echo "The answer is NO."
elif [ "$ANSWER" = "maybe" ]; then
  echo "The answer is MAYBE."
else
  echo "The answer is UNKNOWN."
fi
Copy the code

In the code above, first determine if the $ANSWER string is empty. If it is empty, the script is terminated and the exit status is set to 1. There is no answer. Redirect to standard Error, which is a common way to handle error messages. If the $ANSWER string is not empty, determine whether its value is equal to yes, no, or maybe.

The variable must be enclosed in double quotation marks, for example, [-n “$COUNT”]. Otherwise, the test command may display an error message indicating too many parameters after the variable is replaced with a string. Otherwise, if the variable is empty, the command becomes [-n], which is judged to be true. If placed in double quotation marks, [-n “”] is false.

  1. Integer judgment

The following expression is used to determine integers.

  • [ integer1 -eq integer2 ]If:integer1Is equal to theinteger2, it istrue.
  • [ integer1 -ne integer2 ]If:integer1Is not equal tointeger2, it istrue.
  • [ integer1 -le integer2 ]If:integer1Less than or equal tointeger2, it istrue.
  • [ integer1 -lt integer2 ]If:integer1Less thaninteger2, it istrue.
  • [ integer1 -ge integer2 ]If:integer1Greater than or equal tointeger2, it istrue.
  • [ integer1 -gt integer2 ]If:integer1Is greater thaninteger2, it istrue.

Here is an example of its use.

#! /bin/bash

INT=-5

if [ -z "$INT" ]; then
  echo "INT is empty." >&2
  exit 1
fi
if [ $INT -eq 0 ]; then
  echo "INT is zero."
else
  if [ $INT -lt 0 ]; then
    echo "INT is negative."
  else
    echo "INT is positive."
  fi
  if [ $((INT % 2)) -eq 0 ]; then
    echo "INT is even."
  else
    echo "INT is odd."
  fi
fi
Copy the code

$INT = null; $INT = null; $INT = null; $INT = null;

  1. Regular judgment

[[expression]] Supports regular expressions.

[[ string1 =~ regex ]]
Copy the code

In the syntax above, regex is a regular representation, and =~ is the regular comparison operator.

Here’s an example.

#! /bin/bash

INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
  echo "INT is an integer."
  exit 0
else
  echo "INT is not an integer." >&2
  exit 1
fi
Copy the code

INT (^-?); INT (^-?); The regular pattern for [0-9]+$, if satisfied, indicates that it is an integer.

  1. The arithmetic to judge

Bash also provides ((…) The judgment of arithmetic operations as arithmetic conditions.

if ((3 > 2)); then
  echo "true"
fi
Copy the code

After the above code is executed, it prints true.

Note that arithmetic judgments do not require the test command, but instead use ((…) directly. ) structure, whose return value determines whether the judgment is true or false. If the result of the arithmetic calculation is non-zero, the judgment is true, which is the opposite of the return value of the command, so be careful.

$ if ((1)); then echo "It is true."; fi
It is true.
$ if ((0)); then echo "It is true."; else echo "it is false."; fi
It is false.
Copy the code

In the above example, ((1)) indicates that the judgment is true and ((0)) indicates that the judgment is not true.

The following example demonstrates how to use arithmetic judgment to determine numeric types.

#! /bin/bash

INT=-5

if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
  if ((INT == 0)); then
    echo "INT is zero."
  else
    if ((INT < 0)); then
      echo "INT is negative."
    else
      echo "INT is positive."
    fi
    if (( ((INT % 2)) == 0)); then
      echo "INT is even."
    else
      echo "INT is odd."
    fi
  fi
else
  echo "INT is not an integer." >&2
  exit 1
fi
Copy the code

Determine the logical operation of an expression

  1. puretestThe logical operation of a command

Through logical operations, multiple test judgment expressions can be combined to create more complex judgments. The three logical operations, AND, OR, AND NOT, have their own symbols.

  • ANDOperation: symbol&&, you can also use parameters-a.
  • OROperation: symbol||, you can also use parameters-o.
  • NOTOperation: symbol!.

Here is an AND example to determine whether an integer is in a range.

#! /bin/bashMIN_VAL=1 MAX_VAL=100 INT=50 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if [[ $INT -ge $MIN_VAL && $INT -le $MAX_VAL ]]; then echo "$INT is within $MIN_VAL to $MAX_VAL." else echo "$INT is out of range." fi else echo "INT is not an integer."  >&2 exit 1 fiCopy the code

In the example above, && is used to join two criteria: greater than or equal to $MIN_VAL and less than or equal to $MAX_VAL.

Use the negation operator! It is best to use parentheses to determine the scope of the escape.

if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then
    echo "$INT is outside $MIN_VAL to $MAX_VAL."
else
    echo "$INT is in range."
fi
Copy the code

In the above example, the parentheses used inside the test command must be quoted or escaped, otherwise they will be interpreted by Bash.

  1. testThe logical operation of commands with other commands

If instead of using the test command, the if structure uses a normal command, such as the ((…) in the previous section. Arithmetic operations AND/OR test command with a mixture of ordinary command, you can use the Bash command control operators && (AND) AND | | (OR), logic operation for multiple commands.

$ command1 && command2
$ command1 || command2
Copy the code

For the && operator, command1 is executed, and command2 is executed only if command1 is successful. For | | operators, execute command1 first, only after failed to perform command1, will perform command2.

$ mkdir temp && cd temp
Copy the code

The preceding command creates a directory named temp. After the command is executed successfully, the second command is executed to enter the directory.

$ [ -d temp ] || mkdir temp
Copy the code

The above command tests for the existence of the temp directory and, if not, executes a second command to create it. This is very helpful in handling errors in scripts.

[ ! -d temp ] && exit 1
Copy the code

In the command above, if the temp subdirectory does not exist, the script terminates and returns a value of 1.

The following example shows how to rewrite an && judgment expression into the corresponding if structure.

[[ -d "$dir_name" ]] && cd "$dir_name" && rm *

#Is equivalent to
if [[ ! -d "$dir_name" ]]; then
  echo "No such directory: '$dir_name'" >&2
  exit 1
fi
if ! cd "$dir_name"; then
  echo "Cannot cd to '$dir_name'" >&2
  exit 1
fi
if ! rm *; then
  echo "File deletion failed. Check results" >&2
  exit 1
fi
Copy the code