tartarus's bolg tartarus's bolg
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • Linux and Unix Guide
  • CMake
  • gcc
  • gdb
  • bash
  • GNU Make
  • DDCA-ETH
  • CS106L
  • CS144
  • NJU PA
  • NJU OS(jyy)
  • C
  • C++
  • Python
  • reveal-md
  • LaTex
  • Paper Reading
  • TBD
  • pdb

  • make

  • cmake

  • Linux and Unix

    • Linux Tool介绍
    • Useful Linux Tool
    • regular-expression
    • Basic-Shell-Script
    • Using-Structured-Commands
      • 本章内容
      • if-then statement
        • if-then
        • if-then else
        • if-then elif-then
        • if-then elif-then else
      • test command and []
        • Numeric comparisons
        • String comparisions
        • File comparisions
        • Compound Testing
      • Working with Advanced if-then Features
        • Single Parentheses
        • Using double parentheses
      • Using double brackets
      • Considering the case Command
    • More-Structured-Commands
    • Handling-User-Input
    • Presenting-Data
    • Script-Control
  • Basic_Software
  • Linux and Unix
tartarus
2023-05-08
目录

Using-Structured-Commands

# 本章内容

  • if-then , if-then-else , if-then-elif statement
  • Understanding the test command
  • Testing compound conditions
  • Using double brackets and parentheses Looking at case

# if-then statement

# if-then

if-then 语句在 shell 中是用来判断命令的 (0 表示命令执行成功,非 0 标识命令执行失败),而在常规的编程语言中 if 语句通常是用来判断条件的。但在 shell 中判断条件使用 test 。具体见 test command and [] (opens new window)

我的缩进风格采用了 google shell (opens new window) 的缩进风格,在需要缩进的地方都使用两个 space。

if-then 的格式:

if command 
then 
  commands 
fi
1
2
3
4

或者也可以使用:

if command ; then 
  commands 
fi
1
2
3

如果 command 执行成功,exit code 为 0,那么就会执行 then 中的 commands .

# if-then else

if then 语句的缺点是如果 command 命令的退出码不为 0,那么就不会执行 commands 直接退出。使用 if then else 可以对 command 的退出码不为 0 时就会执行 else 中的 commands 。

if command 
then
  commands 
else
  commands 
fi
1
2
3
4
5
6

if-then else 和 if-then 可以嵌套使用。

# if-then elif-then

if command1 
then
  commands
elif command2 
then
  more commands 
...
fi
1
2
3
4
5
6
7
8

# if-then elif-then else

或者可以在 elif 中加入 else ,这样如果 command1 和 command2 返回的状态码都不为 0 时,会执行 commands3:

if command1 
then
  commands1
elif command2 
then
  commands2
else
  commands3
fi
1
2
3
4
5
6
7
8
9

# test command and []

if 语句只能用来直接判断命令的执行是否成功,然后执行一些操作。 test 命令使得 if 语句有了判断条件语句的能力。

test 和 [] 能判断的条件有:

  1. Numeric comparisions
  2. String comparisions
  3. File comparisions
    (接下来会一一介绍每种判断条件的使用方法)

如果 test 条件判断为 TRUE,那么 test 命令的条件状态码返回 0,否则条件状态码返回非零:

if test condition 
then
  commands 
fi
1
2
3
4

(如果 condition 为空,则 test 返回条件码为非零 (FALSE)。)

使用举例:

#!/bin/bash 
# testing if a variable has content 
# my_variable is empty
if test $my_variable 
then 
  echo "The my_variable variable has content and returns a True." 
  echo "The my_variable variable content is: $my_variable" 
else 
  echo "The my_variable variable doesn't have content," 
  echo "and returns a False." 
fi
1
2
3
4
5
6
7
8
9
10
11

output:

The my_variable variable doesn't have content,
and returns a False.
1
2

Bash shell 中声明了 square bracket [] 来代替 test。

if [ condition ] 
then
  commands 
fi
1
2
3
4

警告

左括号后和右括号前都必须有一个 sapce,否则会报错误。

# Numeric comparisons

使用 test 或者 [] 来进行整型数值条件的比较 (注意 n1, n2 可以是数字或者是存储数字的变量):

Comparison Description
n1 -eq n2 Checks if n1 is equal to n2.
n1 -ge n2 Checks if n1 is greater than or equal to n2.
n1 -gt n2 Checks if n1 is greater than n2.
n1 -le n2 Checks if n1 is less than or equal to n2.
n1 -lt n2 Checks if n1 is less than n2.
n1 -ne n2 Checks if n1 is not equal to n2.

举例:

# This file is named script.sh
#!/bin/bash 
var1=1
var2=2
if [ $var1 -ge $var2 ]
then
  echo "var1 >= var 2"
else
  echo "var1 < var 2"
fi
1
2
3
4
5
6
7
8
9
10

output:

$ ./script.sh
var1 < var 2
1
2

# String comparisions

使用 test 或者 [] 来进行字符串条件的比较 (要比较的两个字符串可以是字符串或者是存储字符串的变量):

Comparison Description
str1 = str2 Checks if str1 is the same as string str2.
str1 != str2 Checks if str1 is not the same as str2.
str1 < str2 Checks if str1 is less than str2.
str1 > str2 Checks if str1 is greater than str2.
-n str1 Checks if str1 has a length greater than zero.(-n is "not zero")
-z str1 Checks if str1 has a length of zero.

注意事项:

  1. 使用 > 和 < 进行比较时,需要使用 \ 进行 escape. 否则 bash 会把它理解为重定向。
  2. > 和 < 是按照每个字符的 Unicode 进行比较的。
  3. sort 进行比较时,小写字符比大写字符都小,这是根据字符的使用习惯。而 shell 的比较条件 < 和 > 使用的是每个字符对应的 Unicode 进行比较,所以大写字符比小写字母都要小。
  4. 未定义的变量,对应的字符串长度也为 0。
#!/bin/bash 
var1="He"
var2="he"
if [ $var1 \> $var2 ]
then
  echo "var1 > var 2"
else
  echo "var1 < var 2"
fi
1
2
3
4
5
6
7
8
9

# File comparisions

(最常使用在文件访问时)
用来检查 Linux 中文件的各种属性。

命令 解释
-d f Checks if f exists and is a directory.
-e f Checks if f exists and is file or directory.
-f f Checks if f exists and is a file.
-r f Checks if f exists and is readable.
-w f Checks if f exists and is writable.
-x f Checks if f exists and is executable.
-s f Checks if f exists and is not empty.
-O f Checks if f exists and is owned by the current user.
-G f Checks if f exists and the default group of the file f is the same as the group of the current user.
f1 -nt f2 Checks if f1 is newer than f2 . (-nt means "new than")
f1 -ot f2 Checks if f1 is older than f2 .(-nt means "old than")

提示

  1. -d 命令常使用在读写文件前,用来判断文件所在的目录是否存在。
  2. -r 命令常使用在读文件前,用来判断文件是否是可读的。
  3. -w 命令常使用在读文件写,用来判断文件是否是可写的。
  4. -s 命令常使用在删除文件前,用来判断文件是否是空的。
  5. -nt 和 -ot 常用来比较两个文件的新旧,但是比较前,应该使用 -f 命令确保两个文件都是存在的。

表格中的 f, f1, f2 可以是一个变量,也可以直接是一个字符串

举例:

#!/bin/bash 
name="foo.md"

if [ -f $name ]
then
  echo "$name is a file"
fi
1
2
3
4
5
6
7

output:

$ file foo.md
foo.md: empty

./script.sh
foo.md is a file
1
2
3
4
5

# Compound Testing

[ condition1 ] && [ condition2 ] // AND 
[ condition1 ] || [ condition2 ] // OR
1
2

对于 OR 语句来说: The first condition is always verified, but the second condition is only verified if the first condition is false.
对于 AND 语句来说: The first condition is always verified, but the second condition is only verified if the first condition is true.

# Working with Advanced if-then Features

在 if-then 中还能使用三种高级特性:

  • Single Parentheses

# Single Parentheses

Single Parenthese: 在 bash 执行 command 之前,会创建一个 subshell 来执行 command 命令。如果不加括号,就直接在运行脚本的那个 shell 中执行 command 命令。

使用方法:

if (command)
then 
  commands
fi
1
2
3
4

如果 command 的退出码为 0,就会执行 then 中的 commands

# Using double parentheses

double parentheses 命令提供了高级的字符串比较功能。(还增加了赋值功能)

在 if 中使用 test 命令可以使得我们可以进行三种类型的比较:数字比较,字符串比较,文件比较。双括号使得我们可以在 if 中使用更多的数学运算。更加符合编程语言比较语句的语法逻辑
(若双括号中的运算结果是 0,则退出码为非 0;若双括号中的运算结果为非 0,则退出码为 0,即正常退出)

$ ((0))
$ echo $?
1
$ ((1))
$ echo $?
0
1
2
3
4
5
6

在双括号比较语句和赋值语句,还可以在双括号中使用:

Symbol Description
val++ Post-increment
val-- Post-decrement
++val Pre-increment
--val Pre-decrement
! Logical negation
~ Bitwise negation
** Exponentiation
<< Left bitwise shift
>> Right bitwise shift
& Bitwise Boolean AND
| Bitwise Boolean OR
&& Logical AND
|| Logical OR

不仅可以在 if 进行判断时使用双括号语句,还可以在正常命令中使用双括号将数学运算的结果赋值给变量:

$ cat script.sh
#!/bin/bash 
# Testing a double parentheses command 
#
val1=10 
#
if (( $val1 ** 2> 90 )) 
then 
  (( val2 = $val1 ** 2 ))  # 也可以使用上一章中的: val2=$[$val1 ** 2]
  echo "The square of $val1 is $val2," 
  echo "which is greater than 90." 
#
fi

$ ./script.sh
The square of 10 is 100,
which is greater than 90.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

提示

在使用 test 或者 [] 对字符串进行比较时,还需要使用 backslash 来 escape > 和 < 符号。但是使用双括号时不需要 escape。

# Using double brackets

double brackets 命令提供了高级的字符串比较功能。 它和 test 中字符串比较方式相同,但是 double brackets 提供了一个 test 没有的高级功能 —— pattern matching
举例:

$ bash --version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ cat script.sh
#!/bin/bash 
# Using double brackets for pattern matching 
#
#
if [[ $BASH_VERSION == 5.* ]] 
then echo "You are using the Bash Shell version 5 series." 
fi

$ ./script.sh
You are using the Bash Shell version 5 series.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

注意

使用 double bracket 来比较字符串时,判断两字符串相等使用的是 == . 在 test 命令中使用的时 = .

# Considering the case Command

语法:

case variable in 
pattern1 | pattern2 ) commands1 ;; 
pattern3 ) commands2 ;; 
*) default commands ;; 
esac
1
2
3
4
5

使用举例:

$ cat script.sh
#!/bin/bash 
# Using a short case statement 
#
case $USER in 
rich | christine) 
  echo "Welcome $USER" 
  echo "Please enjoy your visit.";; 
barbara | tim | tartarus) 
  echo "Hi there, $USER" 
  echo "We're glad you could join us.";; 
testing) 
  echo "Please log out when done with test.";; 
*) 
  echo "Sorry, you are not allowed here."
esac

$ ./script
Hi there, tartarus
We're glad you could join us.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

提示

每个选项都可以是多个命令,只有最后一个命令需要使用 ;;

上次更新: 12/27/2023, 8:55:47 AM
Basic-Shell-Script
More-Structured-Commands

← Basic-Shell-Script More-Structured-Commands→

Theme by Vdoing | Copyright © 2023-2023 tartarus | CC BY-NC-SA 4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式