shell 是一个命令行解释器,它接收应用程序/ 用户命令,然后调用操作系统内核。Shell 还是一个功能的强大的编程语言,易编写、易调式、灵活性强。
shell 编程 - 图1

  1. Linux 提供的 Shell 解析器有:

image.png

  1. bash 和 sh 的关系

image.png

  1. CentOS 默认的解析器是 bash

image.png


Shell 脚本入门:

  1. 脚本文件格式:一般文件都以 .sh 结尾。当然不加后缀,只要文件里面的内容符合 shell 的格式,那么都是可以执行的。只是 .sh 是约定俗成的一种规定。
  2. 脚本格式:脚本都要以#!bin/bash开头,这是为了指定解析器。
  3. hello world:
    1. 创建一个 shell 脚本文件
    2. 编辑文件,在文件中写出helloecho "hello, world"
    3. 保存并退出
  4. 脚本的常用执行方式:
    1. 采用 bash 或 sh+脚本的相对路径或绝对路径(不用赋予脚本+x 权限)
    2. 采用输入脚本的绝对路径或相对路径(必须具有可执行权限+x)chmod +x 脚本路径。添加好可执行权限以后,可以直接输入脚本路径,直接执行(不需要在输入 bash 或者 sh)
    3. 在脚本路径前加上source 或 .也可以执行

      前两种方式都是在当前 shell 中打开一个子 shell 来执行脚本内容,当脚本内容结束的时候,则子 shell 关闭,回到 shell 中。 第三种则是不打开子 shell,直接在当前的 shell 中直接执行。这样的执行方式,区别在于某些变量的作用域不同,有可能在子 shell 里面进行了更改,但最后在最外层的 shell 中没有效果。这也就是在我们修改完/etc/profile后需要 source 一下的原因。


变量:

系统预定义变量:

  1. 常用的系统变量:
    1. $HOME
    2. $PED
    3. $SHELL
    4. $USER
  2. 查看系统变得值

image.png

  1. 显示当前 Shell 中的所有变量:set

自定义变量:

  1. 基本语法:
    1. 定义变量:变量名=变量值=号后面不能有空格
    2. 撤销变量:unset 变量名
    3. 声明静态变量:readonly 变量名=变量值静态变量不能 unset
  2. 变量定义规则:
    1. 变量名称可以由:字母、数字、下划线组成,但是不能以数字开头。环境变量建议全部大写。
    2. =等号两侧不能有空格
    3. 变量的值如果有空格,需要使用双引号或者单引号括起来
    4. 在 bash 中,变量默认都是字符串类型,无法直接进行数值运算
  3. 全局变量:
    1. 先声明一个局部变量
    2. export 局部变量就变成了全局变量。在子 shell 中修改全局变量是不会影响到外部的 shell 的。

特殊变量:

$n:

$n 其中 n 为数字,$0 代表该脚本名称,$1 - $9 代表第一到第九个参数,十以上的参数需要用到大括号 ${10}

  1. [root@CentOS-Study script]# touch parameter.sh
  2. [root@CentOS-Study script]#
  3. [root@CentOS-Study script]# vim parameter.sh
  4. #!/bin/bash
  5. echo '===================$n==============='
  6. echo $0
  7. echo $1
  8. echo $2
  9. [root@CentOS-Study script]#
  10. [root@CentOS-Study script]# chmod 777 parameter.sh
  11. [root@CentOS-Study script]# ./parameter.sh cls xz
  12. ===================$n===============
  13. ./parameter.sh
  14. cls
  15. xz
  16. [root@CentOS-Study script]#

$#:

$# 获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强交办的健壮性。

  1. [root@CentOS-Study script]# vim parameter.sh
  2. #!/bin/bash
  3. echo '===================$n==============='
  4. echo $0
  5. echo $1
  6. echo $2
  7. echo '===================$#==============='
  8. echo $#
  9. [root@CentOS-Study script]#
  10. [root@CentOS-Study script]# ./parameter.sh cls xz
  11. ===================$n===============
  12. ./parameter.sh
  13. cls
  14. xz
  15. ===================$#===============
  16. 2
  17. [root@CentOS-Study script]#

$* 和 $@:

  • $ 这个变量代表命令行中所有的参数,$ 把所有的参数看成一个整体。
  • $@ 这个变量也代表命令行中的所有参数,但 $@ 把每个参数区别对待。 ```shell [root@CentOS-Study script]# vim parameter.sh

!/bin/bash

echo ‘===================$n===============’ echo $0 echo $1 echo $2 echo ‘===================$#===============’ echo $# echo ‘===================$===============’ echo $ echo ‘===================$@===============’ echo $@

[root@CentOS-Study script]# [root@CentOS-Study script]# ./parameter.sh a b c d e f g ===================$n=============== ./parameter.sh a b ===================$#=============== 7 ===================$*=============== a b c d e f g ===================$@=============== a b c d e f g [root@CentOS-Study script]#

  1. ---
  2. <a name="yPdZK"></a>
  3. ### $?:
  4. $? 最后一次执行的命令返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量值非0(具体哪个数字由自己决定),则证明上一个命令执行不正确。
  5. ```shell
  6. [root@CentOS-Study script]# ./parameter.sh a b c d e f g
  7. ===================$n===============
  8. ./parameter.sh
  9. a
  10. b
  11. ===================$#===============
  12. 7
  13. ===================$*===============
  14. a b c d e f g
  15. ===================$@===============
  16. a b c d e f g
  17. [root@CentOS-Study script]# echo $?
  18. 0
  19. [root@CentOS-Study script]#
  20. [root@CentOS-Study script]#
  21. [root@CentOS-Study script]# parameter.sh
  22. bash: parameter.sh: command not found...
  23. [root@CentOS-Study script]# echo $?
  24. 127
  25. [root@CentOS-Study script]#

运算符:

基本语法:$((运算式))$[运算式]

  1. [root@CentOS-Study script]# touch computing.sh
  2. [root@CentOS-Study script]# vim computing.sh
  3. #!/bin/bash
  4. echo '================computing=================='
  5. echo $(($1+$2))
  6. echo $[$1-$2]
  7. echo $[($1+$2)*4]
  8. [root@CentOS-Study script]# chmod 777 computing.sh
  9. [root@CentOS-Study script]# ./computing.sh 5 6
  10. ================Count==================
  11. 11
  12. -1
  13. 44
  14. [root@CentOS-Study script]#

条件判断:

  1. 基本语法:
    1. test condition条件表达式
    2. [ condition条件表达式 ]condition 前后都要有空格’

条件非空即为 true,[XXXX] 返回 true/ 0,[ ] 返回 false/ 1

  1. 常用判断条件:
    1. 两个整数之间比较
      • -eq:等于 equal
      • -ne:不等于 no equal
      • -lt:小于 less than
      • -le:小于等于 less equal
      • -gt:大于 greater than
      • -ge:大于等于 greater equal

字符串之间的比较,用等号 “=” 判断相等;用 “!=” 判断不等。

  1. 按照文件权限进行判断:
    • -r:有读的权限 read
    • -w:有写的权限 write
    • -x:有执行的权限 execute
  2. 按照文件类型进行判断:
    • -e:文件存在 existence
    • -f:文件存在且是一个常规的文件 file
    • -d:文件存在且是一个目录 directory
    1. 多条件判断:
  3. &&:表示前一条指令执行成功,才会执行下一条指令
  4. ||:表示上一条命令执行失败,才执行下一条命令 ```shell [root@CentOS-Study script]# touch test [root@CentOS-Study script]# ll total 8 -rwxrwxrwx. 1 root root 109 Jun 13 21:28 computing.sh -rwxrwxrwx. 1 root root 236 Jun 13 21:18 parameter.sh -rw-r—r—. 1 root root 0 Jun 13 21:46 test [root@CentOS-Study script]# [root@CentOS-Study script]# [root@CentOS-Study script]# [ -r test ] [root@CentOS-Study script]# echo $? 0 [root@CentOS-Study script]# [root@CentOS-Study script]# [root@CentOS-Study script]# [ -x test ] [root@CentOS-Study script]# echo $? 1 [root@CentOS-Study script]# [ ] [root@CentOS-Study script]# echo $? 1 [root@CentOS-Study script]# [ abc ] [root@CentOS-Study script]# echo $? 0 [root@CentOS-Study script]# [root@CentOS-Study script]# [ abc ] && echo OK || echo not OK OK [root@CentOS-Study script]# [ ] && echo OK || echo not OK not OK [root@CentOS-Study script]#
  1. ---
  2. <a name="xdkJD"></a>
  3. # 流程控制:
  4. <a name="EinFc"></a>
  5. ## if 判断:
  6. 1. 基本语法:
  7. 1. 单分支:
  8. ```shell
  9. #!/bin/bash
  10. if [ condition ]; then
  11. 程序
  12. fi
  13. # =============或者=============
  14. if [ condition ]
  15. then
  16. 程序
  17. fi
  1. 多分支: ```shell

    !/bin/bash

if [ condition ]; then 程序-1 elif [ condition ]; then 程序-2 elif [ condition ]; then 程序-3 else 程序-4 fi

  1. 注意事项:
  2. 1. [ condition ] condition表达式前后都要有空格
  3. 1. if 后面要有空格
  4. ---
  5. <a name="fV1m7"></a>
  6. ## case 语句:
  7. 基本用法:
  8. ```shell
  9. #!/bin/bash
  10. case $变量名 in
  11. "值1")
  12. 程序-1
  13. ;;
  14. "值2")
  15. 程序-2
  16. ;;
  17. "值3")
  18. 程序-3
  19. ;;
  20. "值....")
  21. ....
  22. ;;
  23. *)
  24. 上述都匹配不上,最终执行的程序
  25. ;;
  26. esac
  1. case 行尾必须为单词 “in”,每一个模式匹配必须以右括号 “)” 结束
  2. 双分号 “;;” 表示命令序列结束,相当于 java 中的 break
  3. 最后的 “*)” 表示默认模式,相当于 java 中的 default

for 循环:

  1. 基本语法 1: ```shell

    !/bin/bash

for (( i=1; i <= $1; i++ )) do sum = $[ $sum + $i ] done echo $sum

  1. 2. 基本语法 2
  2. ```shell
  3. #!/bin/bash
  4. for 变量 in 值1 值2 值3 ...
  5. do
  6. 程序
  7. done
  8. --------------------------------------------------------------------------
  9. [root@CentOS-Study script]# touch parameter_for_test.sh
  10. [root@CentOS-Study script]# vim parameter_for_test.sh
  11. #!/bin/bash
  12. echo '===========$*================'
  13. for par in "$*"
  14. do
  15. echo $par
  16. done
  17. echo '===========$@================'
  18. for par in "$@"
  19. do
  20. echo $par
  21. done
  22. [root@CentOS-Study script]# chmod +x parameter_for_test.sh
  23. [root@CentOS-Study script]# ./parameter_for_test.sh a b c d
  24. ===========$*================
  25. a b c d
  26. ===========$@================
  27. a
  28. b
  29. c
  30. d
  31. [root@CentOS-Study script]#

while 循环:

基本用法:

  1. [root@CentOS-Study script]# touch parameter_while_test.sh
  2. [root@CentOS-Study script]# vim parameter_while_test.sh
  3. #!/bin/bash
  4. sum=0
  5. i=1
  6. while [ $i -le 100 ]
  7. do
  8. sum=$[$sum+$i]
  9. i=$[$i+1]
  10. done
  11. echo $sum
  12. [root@CentOS-Study script]#
  13. [root@CentOS-Study script]# chmod +x parameter_while_test.sh
  14. [root@CentOS-Study script]# ./parameter_while_test.sh
  15. 5050
  16. [root@CentOS-Study script]#

read 读取控制台输入

基本用法:read [选项] [参数]

  • 选项:
    • -p:指定读取值时的提示符
    • -t:指定读取值时等待的时间(秒),如果不加 -t 则表示一直等待
  • 参数:
    • 变量:指定读取值的变量名 ```shell [root@CentOS-Study script]# touch read_test.sh [root@CentOS-Study script]# vim read_test.sh

!/bin/bash

read -t 10 -p “please type your words: “ word echo “you wrote: $word”

[root@CentOS-Study script]# [root@CentOS-Study script]# chmod +x read_test.sh [root@CentOS-Study script]# [root@CentOS-Study script]# [root@CentOS-Study script]# ./read_test.sh please type your word: sabcd you wrote: abcd [root@CentOS-Study script]#

  1. ---
  2. <a name="JHJHa"></a>
  3. # 函数:
  4. <a name="U4tBO"></a>
  5. ## 系统函数:
  6. <a name="ZZI9T"></a>
  7. ### basename:
  8. 基本用法:`basename [string/ pathname] [suffix]`basename 命令会删掉所有的前缀包括最后一个 "/" 字符,然后将字符串显示出来。<br />其中 suffix 为后缀,如果 suffix 被置顶了,basename 会将 pathname 或者 string 中的 suffix 去掉
  9. ```shell
  10. [root@CentOS-Study script]#
  11. [root@CentOS-Study script]# pwd
  12. /root/script
  13. [root@CentOS-Study script]#
  14. [root@CentOS-Study script]# ls
  15. computing.sh parameter_for_test.sh parameter.sh parameter_while_test.sh read_test.sh test
  16. [root@CentOS-Study script]#
  17. [root@CentOS-Study script]#
  18. [root@CentOS-Study script]# basename /root/script/read_test.sh
  19. read_test.sh
  20. [root@CentOS-Study script]#
  21. [root@CentOS-Study script]# basename /root/script/read_test.sh .sh
  22. read_test
  23. [root@CentOS-Study script]#

dirname:

基本用法:dirname 文件绝对路径从给定的包含绝对路径的文件名中去除文件名(非目录部分),然后返回剩下的路径。
dirname 可以理解为取文件路径的绝对路径

  1. [root@CentOS-Study script]# dirname /root/script/read_test.sh
  2. /root/script
  3. [root@CentOS-Study script]#
  4. [root@CentOS-Study script]# dirname ./read_test.sh
  5. .
  6. [root@CentOS-Study script]#

自定义函数:

基本用法:

  1. [ function ] funname[()]
  2. {
  3. Action;
  4. [return int;]
  5. }
  1. 必须在调用函数的地方之前,先声明函数,shell 脚本是逐行运行,不悔向其他语言一样先编译。
  2. 函数返回值,只能通过 $? 系统变量获取,可以显示加 “return” 返回,如果不加,将一最后一条命令运行结果作为返回值。return 后跟数值(0-255)
  1. [root@CentOS-Study script]# touch fun_test.sh
  2. [root@CentOS-Study script]# vim fun_test.sh
  3. #!/bin/bash
  4. function sum(){
  5. s=0
  6. s=$[$1+$2]
  7. echo $s
  8. }
  9. read -p "the first number: " a
  10. read -p "the second number: " b
  11. result=$(sum $a $b)
  12. echo $result
  13. [root@CentOS-Study script]# chmod +x fun_test.sh
  14. [root@CentOS-Study script]# ./fun_test.sh
  15. the first number: 5
  16. the second number: 3
  17. 8
  18. [root@CentOS-Study script]#

正则表达式:

正则表达式使用单个字符串来描述,匹配一系列符合某个语法规则的字符串。在很多文本编辑器中,正则表达式通常用来检索,替换那些符合某个模式的文本。在 Linux 中,grep,sed ,awk 等文本处理工具都支持通过正则进行匹配。

常规匹配:

遗传不包含特殊字符的正表达式匹配他自己,他只会匹配包含自身的选项:
image.png


常用特殊字符:

字符 ^:

^ 匹配一行的开头,会匹配出所有以 a 开头的行
image.png


字符 $:

$ 匹配一行的结束,会匹配出所有以 t 结尾的行:
image.png


字符 .:

. 匹配任意一个字符,会匹配包含 r..b 形式的所有行
image.png


字符 *:

*不单独使用,一般和上一个字符连用,表示匹配一个字符 0 次或者多次
image.png


字符区间 []:

[ ] 表示匹配某个范围内的一个字符

  • [6,8]:匹配 6 或 8
  • [0-9]:匹配一个 0-9 的数字
  • [0-9]*:匹配任意长度的数字字符串
  • [a-z]:匹配一个 a-z 之间的字符
  • [a-z]*:匹配人资产固定额字母字符串
  • [a-c, e-f]:匹配 a-c 或 e-f 之间的任意字符

image.png


特殊字符 \:

\ 表示转义,并不会单独使用。由于所有特殊字符有其特定的匹配模式,当我们相匹配其自身的时候需要结束 \ 进行转移(例如,想匹配文件名带有 “$”)。进行匹配时,需要用单引号 ‘ 括起来。
image.png


文本处理工具:

cut:

cut 的工作就是 “剪”,具体的说就是在文件中负责剪切数据。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
基本用法:cut [选项参数] filename

选项 功能描述
-f 列号,提取第几列
-d 分隔符,按照指定分隔符分割列,默认是制表符 “\t”
-c 按字符进行切割,后加 n 表示取第几列

image.png


awk:

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行分析处理。

  • 基本用法:awk [选项参数] '/pattern1/{action1} /pattern2/{action2}...' filename
    • pattern:表示 awk 在数据中查找的内容,就是匹配模式
    • action:在找到匹配内容时所执行的一系列命令 | 选项 | 功能描述 | | —- | —- | | -F | 指定输入文件分割符 | | -v | 赋值一个用户定义变量 |
  1. [root@CentOS-Study etc]# cat passwd | grep ^root | cut -d ":" -f 7
  2. /bin/bash
  3. [root@CentOS-Study etc]#
  4. [root@CentOS-Study etc]#
  5. [root@CentOS-Study etc]#
  6. [root@CentOS-Study etc]# cat passwd | awk -F ":" '/^root/ {print $7}'
  7. /bin/bash
  8. [root@CentOS-Study etc]#
  9. [root@CentOS-Study etc]#
  10. [root@CentOS-Study etc]# cat passwd | awk -F ":" '/^root/ {print $1","$7}'
  11. root,/bin/bash
  12. [root@CentOS-Study etc]#