if-then 语句

  1. # 如果 if 后面的 command 的退出状态码是 0,执行 then 后面的命令
  2. if command
  3. then
  4. commands
  5. fi
  6. # 或者
  7. if command; then
  8. commands
  9. fi
  10. if grep $testuser /et/passwd
  11. then
  12. ...
  13. fi
  14. #!/bin/bash
  15. DIR="/media/cdrom"
  16. if [ ! -e $DIR ]
  17. then
  18. mkdir -p $DIR
  19. fi

if-then-else

  1. if command
  2. then
  3. commands
  4. else
  5. commands
  6. fi
  7. if command
  8. then
  9. commands
  10. elif command
  11. then
  12. commands
  13. fi
  14. #!/bin/bash
  15. ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
  16. if [ $? -eq 0 ]
  17. then
  18. echo "Host $1 is On-line."
  19. else
  20. echo "Host $1 is Off-line."
  21. fi

示例:

  1. # 使用 if...elif
  2. if grep $testuser /etc/passwd
  3. then
  4. echo "The user $testuser exists on this system."
  5. elif ls -d /home/$testuser
  6. then
  7. echo "The user $testuser does not exist on this system."
  8. echo "However, $testuser has a directory."
  9. else
  10. echo "The user $testuser does not exist on this system."
  11. echo "However, $testuser does not have a directory."
  12. fi
  13. #!/bin/bash
  14. read -p "Enter your score( 0-100): " GRADE
  15. if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then
  16. echo "$GRADE is Excellent"
  17. elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then
  18. echo "$GRADE is Pass"
  19. else
  20. echo "$GRADE is Fail"
  21. fi

test 命令

  1. # test 命令没有命令的话,以非零的退出状态码退出
  2. if test
  3. then
  4. echo "test command is ok."
  5. else
  6. echo "test command is false."
  7. fi
  8. # 可以使用 test 命令确定变量中是否有内容
  9. my_variable="23"
  10. if test $my_variable
  11. then
  12. echo "variable is not empty."
  13. else
  14. echo "variable is empty."
  15. fi

使用方括号定义测试条件,第一个方括号之后和第二个方括号之前必须有空格

  • 数值比较
  • 字符串比较
  • 文件比较

数值比较

n1 -eq n2

n1 -ge n2

n1 -gt n2

n1 -le n2

n1 -lt n2

n1 -ne n2

  1. # 方括号前后必须要有空格
  2. # test 命令中不能使用浮点数
  3. if [ $value1 -gt $value2 ]
  4. then
  5. echo "$value1 is greater than $value2"
  6. elif [ $value1 -lt $value2 ]
  7. then
  8. echo "$value1 is less than $value2"
  9. else
  10. echo "$value1 is equal $value2"
  11. fi
  12. echo
  13. FreeMem=`free -m | grep Mem: | awk '{print $4}'`
  14. [ $FreeMem -lt 1024 ] && echo "Insufficient Memory"

字符串比较

str1 = str2

str1 != str2

str1 < str2

str1 > str2

-n str1 检查 str1 的长度是否非0

-z str1 检查 str1 的长度是否为0

注意,字符串顺序比较中:

  • 大于号和小于号必须转义
  • 大于和小于顺序和 sort 命令所采用的不同

在比较测试中,大写字母被认为是小于小写字母的。而 sort 命令相反。

比较测试中用的是标准的 ASCII 顺序。sort 命令使用的是系统的本地化语言设置中定义的排序顺序。对于英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前。

  1. if [ $USER != $testuser ]
  2. then
  3. ...
  4. fi
  5. if [ $var1 \> $var2 ]
  6. then
  7. ...
  8. fi
  9. [ $LANG != "en.US" ] && echo "Not en.US"

文件比较

-d file测试文件是否为目录类型

-f file判断是否为一般文件

-e file测试文件是否存在

-r file测试当前用户是否有权限读取

-w file测试当前用户是否有权限写入

-x file测试当前用户是否有权限执行

-O file 检查 file 是否存在并属于当前用户所有

-G file 检查 file 是否存在并且默认组与当前用户相同

-s file 检查 file 是否存在并非空

file1 -nt file2

file1 -ot file2

使用 -nt-ot 比较文件之前,最后先检查文件是否存在:

  1. # 文件不存在,返回 false
  2. if [ badfile1 -nt badfile2 ]
  3. then
  4. echo "The badfile1 file is newer than badfile2"
  5. else
  6. echo "The badfile1 file is older than badfile2"
  7. fi
  8. # 结果是
  9. The badfile1 file is older than badfile2

复合条件测试

  1. [ condition1 ] || [ condition2 ]
  2. [ condition1 ] && [ condition2 ]
  3. [ ! $USER = root ] || echo "administrator"

双括号和双方括号

双括号里面可以进行算数运算。

双方括号里面可以进行字符串处理。

记住,不管是方括号还是双方括号,都需要有空格。而单括号的命令替换和双括号的算数运算,不需要有空格。

  1. # 双括号里面不需要使用 $
  2. if ((val1 ** 2 > 90))
  3. then
  4. # 赋值时 = 两边可以有空格
  5. ((val2 = val1 ** 2))
  6. echo "The square of $val1 is $val2"
  7. fi
  8. # 方括号两边必需要有空格,模式匹配功能
  9. if [[ $USER == x* ]]
  10. then
  11. echo "Hello $USER."
  12. else
  13. echo "Sorry, I do not know you."
  14. fi

case 命令

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

注意结尾的双分号

  1. case $USER in
  2. xiaocan | barbara)
  3. echo "Welcome, $USER"
  4. echo "Please enjoy your visit.";;
  5. testing)
  6. echo "Special testing account.";;
  7. jessica)
  8. echo "Do not forget to log off when you're done.";;
  9. *)
  10. echo "Sorry, your are not allowed here";;
  11. esac
  12. #!/bin/bash
  13. read -p "请输入一个字符,并按 Enter 键确认: " KEY
  14. case "$KEY" in
  15. [a-z]|[A-Z])
  16. echo "您输入的是 字母。 "
  17. ;;
  18. [0-9])
  19. echo "您输入的是 数字。 "
  20. ;;
  21. *)
  22. echo "您输入的是 空格、功能键或其他控制字符。 "
  23. esac

for 命令

  1. for var in list
  2. do
  3. command
  4. done

示例:

  1. for test in Alabama Alaska Arizona Arkasas California
  2. do
  3. echo The next state is $test
  4. done
  5. # 不同于其他编程语言,在 for 循环结束后,也能够使用 test 变量
  6. echo $test
  7. # 对单引号转义,或者使用双引号包括它
  8. for test in I don\'t know if "this'll" work
  9. do
  10. echo "word: $test"
  11. done
  12. # 使用双引号包括多个词汇
  13. for test in Nevada "New Hampshire" "New York"
  14. do
  15. echo "City: $test"
  16. done
  17. # 字符串拼接的常用方法
  18. list=$list" Connecticut"
  19. # 怎么打印带有空格的字符呢?
  20. files="states"
  21. # 更新字段的分割符
  22. IFS=$'\n'
  23. for state in $(cat $files)
  24. do
  25. echo "Visit beautiful $state"
  26. done

for 循环假定每个值都是空格分割的。使用 IFS (内部字段分隔符 internal field separator)指定分隔符。

  1. IFS.OLD=$IFS
  2. IFS=$'\n'
  3. # 之后再还原 IFS 的值
  4. IFS=$IFS.OLD
  5. IFS=:
  6. # 换行符、冒号、分号、双引号
  7. IFS=$'\n':;"

读取目录:

  1. # 可以指定多个目录
  2. for file in /Users/xiaocan/Documents/learn/shell-learn/* /home/rich/badtest
  3. do
  4. # 防止 file 名称有空格,所以添加引号
  5. if [ -d "$file" ]
  6. then
  7. echo "$file is a directory."
  8. elif [ -f "$file" ]
  9. then
  10. echo "$file is a file."
  11. fi
  12. done

image.png
批量 ping 主机:

  1. #!/bin/bash
  2. HLIST=$(cat ~/ipadds.txt)
  3. for IP in $HLIST
  4. do
  5. ping -c 3 -i 0.2 -W 3 $IP &> /dev/null
  6. if [ $? -eq 0 ] ; then
  7. echo "Host $IP is On-line."
  8. else
  9. echo "Host $IP is Off-line."
  10. fi
  11. done

C 语言风格的 for 命令

  1. # 括号两边的空格不是必需的
  2. for (( i = 1; i <= 10; i++ ))
  3. do
  4. echo "The next number is $i"
  5. done
  6. echo
  7. for (( a=1, b=10; a <= 10; a++, b--))
  8. do
  9. echo "$a - $b"
  10. done

while 命令

  1. while test command
  2. do
  3. commands
  4. done

示例:

  1. var1=10
  2. while [ $var1 -gt 0 ]
  3. do
  4. echo $var1
  5. var1=$(( var1 - 1 ))
  6. done
  7. echo
  8. var1=5
  9. # 多个测试命令
  10. # 只有最后一个命令成立时才会停止。如果互换了下面两条命令的位置,就一直循环下去了
  11. while echo $var1
  12. [ $var1 -gt 0 ]
  13. do
  14. echo "This is inside the loop"
  15. var1=$(( var1 - 1 ))
  16. done

猜数字游戏:

  1. 猜数字游戏
  2. #!/bin/bash
  3. PRICE=$(expr $RANDOM % 1000)
  4. TIMES=0
  5. echo "商品实际价格为 0-999 之间,猜猜看是多少? "
  6. while true
  7. do
  8. read -p "请输入您猜测的价格数目: " INT
  9. let TIMES++
  10. if [ $INT -eq $PRICE ] ; then
  11. echo "恭喜您答对了,实际价格是 $PRICE"
  12. echo "您总共猜 g $TIMES 次"
  13. exit 0
  14. elif [ $INT -gt $PRICE ] ; then
  15. echo "太高了! "
  16. else
  17. echo "太低了! "
  18. fi
  19. done

until 命令

  1. until test command
  2. do
  3. commands
  4. done

示例:

  1. var1=100
  2. until [ $var1 -eq 0 ]
  3. do
  4. echo $var1
  5. var1=$(( var1 - 25 ))
  6. done
  7. echo
  8. # 使用多个测试命令
  9. var1=100
  10. until echo $var1
  11. [ $var1 -eq 0 ]
  12. do
  13. echo Inside the loop.
  14. var1=$(( var1 - 25 ))
  15. done

break 和 continue

和编程语言中的 break 和 continue 类似,不同的是,在 shell 中它们后面可以跟一个数字,指定跳出的层数。

  1. # 注意在 while 中使用 continue,下面的例子不会结束
  2. var2=1
  3. while [ $var2 -lt 15 ]
  4. do
  5. if [ $var2 -gt 5 ] && [ $var2 -lt 10 ]
  6. then
  7. continue
  8. fi
  9. echo "The value is $var2"
  10. var2=$((var2+1))
  11. done

处理循环的输出

可以在 done 命令之后添加一个处理命令。

  1. # 在 done 后面使用管道或重定向命令
  2. for state in "North Dakata" Connecticut Illinois Alabama Tennessee
  3. do
  4. echo "The state is $state"
  5. done | sort
  6. # 或者
  7. # done > test.txt