shell概述

  • shell是一个程序,它连接了用户和Linux内核,它可以解释用户输入的命令传递给内核,让用户可以更加方便的使用Linux系统
  • shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序
  • shell具备编程的能力,shell也是一种语言,C,C++,java,Python,Go等
  • 语言分为编译型语言,C,C++,Go,需要提前编译,编译语言都有编译器
  • 解释型语言,shell,Python,php,不需要提前编译,一边执行,一边编译,每种解释型语言都有解释器
  • shell语言支持大部分编程语言都具备的功能:if判断,for循环,变量,数组,函数,加减乘除,逻辑运算

规范shell脚本组成

  1. [root@test ~]# vim user.sh
  2. #!/bin/bash(环境声明)
  3. #注释信息
  4. 可执行代码…

如何写好一个shell脚本

  • 明确任务需求
  • 按需求整理好每一个步骤,先做什么,后做什么
  • 运行脚本,并根据运行结果排除错误
  • 优化脚本并达到最终效果

编写脚本

编写第一个脚本

  1. [root@localhost ~]# vim hello.sh
  2. #!/bin/bash
  3. #hello word
  4. echo hello word
  5. #赋予执行权限
  6. [root@localhost ~]# chmod u+x hello.sh
  7. #执行脚本
  8. [root@localhost ~]# /root/hello.sh
  9. hello word

编写创建用户脚本

  1. [root@localhost ~]# vim user.sh
  2. #!/bin/bash
  3. useradd abc
  4. passwd abc
  5. [root@localhost ~]# chmod u+x user.sh
  6. #非交互
  7. [root@localhost ~]# vim user.sh
  8. #!/bin/bash
  9. useradd yyyy
  10. echo 1 | passwd --stdin yyyy
  11. [root@localhost ~]# ./user.sh
  12. 更改用户 yyyy 的密码
  13. passwd:所有的身份验证令牌已经成功更新。

编写批量查看脚本

  1. #查看系统版本信息,查看系统内核信息,查看系统内存信息,查看系统网卡信息,查看当前主机名
  2. [root@localhost ~]# vim info.sh
  3. cat /etc/redhat-release
  4. uname -r
  5. free -h
  6. ifconfig ens32
  7. hostname
  8. #赋予执行权限
  9. [root@localhost ~]# chmod u+x info.sh
  10. #执行脚本
  11. [root@localhost ~]# ./info.sh
  12. CentOS Linux release 7.6.1810 (Core)
  13. 3.10.0-957.el7.x86_64
  14. total used free shared buff/cache available
  15. Mem: 972M 480M 147M 16M 344M 260M
  16. Swap: 2.0G 239M 1.8G
  17. ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
  18. inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255
  19. inet6 fe80::8903:cb8:127b:dbc8 prefixlen 64 scopeid 0x20<link>
  20. ether 00:0c:29:a0:e8:12 txqueuelen 1000 (Ethernet)
  21. RX packets 230110 bytes 325471733 (310.3 MiB)
  22. RX errors 0 dropped 0 overruns 0 frame 0
  23. TX packets 20635 bytes 1385581 (1.3 MiB)
  24. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  25. localhost.localdomain

编写配置本地yum源脚本

  1. #编写搭建本地yum仓库脚本【版1,丢人版】
  2. [root@localhost ~]# vim yum.sh
  3. #!/bin/bash
  4. mkdir /mnt/centos
  5. mount /dev/cdrom /mnt/centos
  6. echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
  7. rm -rf /etc/yum.repos.d/*
  8. touch /etc/yum.repos.d/local.repo
  9. echo "[local]" > /etc/yum.repos.d/local.repo
  10. echo "name=local_centos" >> /etc/yum.repos.d/local.repo
  11. echo "baseurl=file:///mnt/centos" >> /etc/yum.repos.d/local.repo
  12. echo "enabled=1" >> /etc/yum.repos.d/local.repo
  13. echo "gpgcheck=0" >> /etc/yum.repos.d/local.repo
  14. #编写搭建本地yum仓库脚本【版2,正常版】
  15. [root@localhost ~]# vim yum.sh
  16. #!/bin/bash
  17. mkdir /mnt/centos
  18. mount /dev/cdrom /mnt/centos
  19. echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
  20. mount -a
  21. rm -rf /etc/yum.repos.d/*
  22. echo "[local]
  23. name=local_centos
  24. baseurl=file:///mnt/centos
  25. enabled=1
  26. gpgcheck=0" > /etc/yum.repos.d/local.repo
  27. #编写搭建本地yum仓库脚本【升级版】
  28. [root@localhost ~]# vim yum.sh
  29. #!/bin/bash
  30. echo "正在配置本地yum仓库..."
  31. mkdir /mnt/centos
  32. mount /dev/cdrom /mnt/centos &> /dev/null
  33. echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
  34. mount -a
  35. rm -rf /etc/yum.repos.d/*
  36. echo "[local]
  37. name=local_centos
  38. baseurl=file:///mnt/centos
  39. enabled=1
  40. gpgcheck=0" > /etc/yum.repos.d/local.repo
  41. echo "本地yum仓库配置以完成..."
  42. yum clean all &> /dev/null
  43. echo "仓库软件包数量"
  44. yum repolist | tail -1
  45. #执行脚本
  46. [root@localhost ~]# ./yum.sh
  47. 正在配置本地yum仓库...
  48. 本地yum仓库配置以完成...
  49. repolist: 4,021
  50. 仓库软件包数量

脚本的执行方式

  • 执行一个脚本的方法有很多种
  • 方法一:赋予脚本执行权限后,可用绝对路径或者当前路径执行
  • 方法二:调用解释器执行脚本文件
  1. #绝对路径执行脚本
  2. [root@localhost ~]# /root/hello.sh
  3. #相对路径执行脚本
  4. [root@localhost ~]# ./hello.sh
  5. #去除执行权限
  6. [root@localhost ~]# chmod u-x hello.sh
  7. #执行脚本
  8. [root@localhost ~]# /root/hello.sh
  9. -bash: /root/hello.sh: 权限不够
  10. [root@localhost ~]# ./hello.sh
  11. -bash: ./hello.sh: 权限不够
  12. #调用解释器执行脚本
  13. [root@localhost ~]# bash hello.sh
  14. hello word
  15. [root@localhost ~]# cat /etc/shells
  16. /bin/sh
  17. /bin/bash
  18. /usr/bin/sh
  19. /usr/bin/bash
  20. /bin/tcsh
  21. /bin/csh
  22. [root@localhost ~]# sh hello.sh
  23. hello word
  24. [root@localhost ~]# tcsh hello.sh
  25. hello word
  26. [root@localhost ~]# csh hello.sh
  27. hello word

常用特殊符号补充

  • “ “ #双引号,引用整体
  • ‘ ’ #单引号,引用整体并取消所有特殊字符含义
  • $[] #四则运算(+ - * / % 取余数)
  • $() #将命令的输出结果作为参数
  • #反撇 `` 将命令的输出结果作为参数
  1. #引用整体,不屏蔽特殊符号的功能
  2. [root@localhost ~]# echo "$PATH"
  3. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  4. #引用整体,屏蔽特殊符号的功能
  5. [root@localhost ~]# echo '$PATH'
  6. $PATH
  7. #没有特殊符号单引双引都可以
  8. [root@localhost ~]# echo "xxoo"
  9. xxoo
  10. [root@localhost ~]# echo 'xxoo'
  11. xxoo
  12. #四则运算
  13. [root@localhost ~]# echo $[1+1]
  14. 2
  15. [root@localhost ~]# echo $[1+5]
  16. 6
  17. [root@localhost ~]# echo $[10-5]
  18. 5
  19. [root@localhost ~]# echo $[10*5]
  20. 50
  21. [root@localhost ~]# echo $[10/5]
  22. 2
  23. [root@localhost ~]# echo $[1+3+4+5+7]
  24. 20
  25. [root@localhost ~]# echo $[10/3]
  26. 3
  27. [root@localhost ~]# echo $[10%3]
  28. 1
  29. #$()取命令结果作为参数
  30. root@localhost ~]# touch $(date +%F)-abc.txt
  31. 2021-05-09-abc.txt
  32. #``取命令结果作为参数
  33. [root@localhost ~]# touch `date +%F`-xxoo.txt
  34. 2021-05-09-xxoo.txt

变量

  • 以固定的名称存放可能变化的值,提高脚本的灵活度来适应多变的环境
  • 定义变量:变量名=变量值,如:a1=abc(等号两边不要有空格)
  • 取消变量:unset 变量名
  • 定义变量注意事项:
    • 变量名由字母/数字/下划线组成,区分大小写,不能以数字开头,不要使用命令和特殊符号
    • 若指定的变量名已经存在,相当于为此变量重新赋值
  1. root@localhost ~]# xx=haha
  2. [root@localhost ~]# echo $xx
  3. haha
  4. [root@localhost ~]# xx=abcd
  5. [root@localhost ~]# echo $xx
  6. abcd
  7. [root@localhost ~]# xx=5
  8. [root@localhost ~]# echo $xx
  9. 5
  10. [root@localhost ~]# echo $[xx+5]
  11. 10
  12. #通过变量定义用户名
  13. [root@localhost ~]# vim user.sh
  14. #!/bin/bash
  15. user=wangxin
  16. useradd $user
  17. echo 1 | passwd --stdin $user
  18. [root@localhost ~]# ./user.sh
  19. 更改用户 wangxin 的密码
  20. passwd:所有的身份验证令牌已经成功更新。
  21. [root@localhost ~]# vim user.sh
  22. #!/bin/bash
  23. user=sdd
  24. useradd $user
  25. echo 1 | passwd --stdin $user
  26. [root@localhost ~]# ./user.sh
  27. 更改用户 sdd 的密码
  28. passwd:所有的身份验证令牌已经成功更新。
  29. [root@localhost ~]# vim user.sh
  30. #!/bin/bash
  31. user=panghu
  32. useradd $user
  33. echo "用户$user创建成功"
  34. echo 1 | passwd --stdin $user &> /dev/null
  35. echo "用户$user密码设置成功"
  36. [root@localhost ~]# ./user.sh
  37. 用户panghu创建成功
  38. 用户panghu密码设置成功

read标准输入取值

  • read 读取用户在键盘上输入的内容,并把内容存放在变量里,可以降低脚本的使用难度
  • 命令格式:read -p “提示信息” 变量名
  1. [root@localhost ~]# vim user.sh
  2. #!/bin/bash
  3. read -p '请输入用户名:' user
  4. useradd $user
  5. echo "用户$user创建成功"
  6. read -p '请设置用户密码:' pass
  7. echo $pass | passwd --stdin $user &> /dev/null
  8. echo "用户$user密码设置成功"
  9. [root@localhost ~]# ./user.sh
  10. 请输入用户名:wuhan
  11. 用户wuhan创建成功
  12. 请设置用户密码:1
  13. 用户wuhan密码设置成功
  14. [root@localhost ~]# ./user.sh
  15. 请输入用户名:liangjing
  16. 用户liangjing创建成功
  17. 请设置用户密码:xxoo
  18. 用户liangjing密码设置成功

变量种类

  • 环境变量:变量名一般都大写,用来设置用户/系统环境
  • 位置变量:bash内置,存储执行脚本时提供的命令参数
  • 预定义变量:bash内置,可直接调用的特殊值,不能直接修改
  • 自定义变量:用户自定义
  • env 命令查看系统所有环境变量
  • set 命令查看系统所有变量,包括用户自定义变量
  • 环境变量
  1. [root@localhost etc]# env
  2. MAIL=/var/spool/mail/root
  3. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  4. PWD=/root
  5. LANG=zh_CN.UTF-8
  6. SELINUX_LEVEL_REQUESTED=
  7. HISTCONTROL=ignoredups
  8. SHLVL=1
  9. HOME=/root
  10. LOGNAME=root
  11. XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
  12. SSH_CONNECTION=192.168.0.1 51791 192.168.0.100 22
  13. LESSOPEN=||/usr/bin/lesspipe.sh %s
  14. XDG_RUNTIME_DIR=/run/user/0
  15. DISPLAY=localhost:10.0
  16. _=/usr/bin/env
  17. OLDPWD=/root
  18. #获取变量值
  19. [root@localhost etc]# echo $SHELL
  20. /bin/bash
  21. [root@localhost ~]# echo $PWD
  22. /root
  23. #查看系统所有变量
  24. [root@localhost ~]# set
  25. [root@localhost ~]# set | grep $a
  • 位置变量
    $0 #脚本名称
    $1 #第一个参数
    $2 #第二个参数
    $3 #第三个参数
    $4 #第四个参数
    $n… #第n个参数
  • 预定义变量
    $0 #代表脚本本身
    $* #显示所有参数内容
    $# #显示有多少个参数
    $? #显示上一条命令的执行结果(0代表正确,非0代表错误)
    1. [root@localhost ~]# vim test.sh
    2. #!/bin/bash
    3. echo $0
    4. echo $1
    5. echo $2
    6. echo $3
    7. echo $*
    8. echo $#
    9. echo $$
    10. echo $?
    11. #赋予执行权限,执行脚本
    12. [root@localhost ~]# ./test.sh xx oo dd
    13. ./test.sh $0
    14. xx $1
    15. oo $2
    16. dd $3
    17. xx oo dd $*
    18. 3 $#
    19. 15594 $$
    20. 0 $?

判断文件状态[ 参数 ]

  • -e #判断文档(文件/目录)是否存在,存在为真
  • -d #判断目录是否存在,存在为真
  • -f #判断文件是否存在,存在为真
  • -r #可读为真
  • -w #可写为真
  • -x #可执行为真
  1. #判断文档是否存在
  2. [root@localhost ~]# [ -e /etc/ ]
  3. [root@localhost ~]# echo $?
  4. 0 #为真
  5. #判断目录是否存在
  6. [root@localhost ~]# [ -d /opt ]
  7. [root@localhost ~]# echo $?
  8. 0
  9. [root@localhost ~]# [ -d /etc/passwd ]
  10. [root@localhost ~]# echo $?
  11. 1
  12. [root@localhost ~]# [ -f /etc/passwd ]
  13. [root@localhost ~]# echo $?
  14. 0
  15. #判断是否可读(以当前用户身份判断)
  16. [root@localhost ~]# [ -r /etc/passwd ]
  17. [root@localhost ~]# echo $?
  18. 0
  19. #判断是否可写
  20. [root@localhost ~]# [ -w /etc/passwd ]
  21. [root@localhost ~]# echo $?
  22. 0
  23. #判断是否可执行
  24. [root@localhost ~]# [ -x /etc/passwd ]
  25. [root@localhost ~]# echo $?
  26. 1
  27. [root@localhost ~]# ll /etc/passwd
  28. -rw-r--r--. 1 root root 3294 5 9 16:43 /etc/passwd

整数比较

  • -gt 大于
  • -ge 大于等于
  • -eq 等于
  • -lt 小于
  • -le 小于等于
  • -ne 不等于
  1. [root@localhost ~]# [ 1 -gt 1 ]
  2. [root@localhost ~]# echo $?
  3. 1
  4. [root@localhost ~]# [ 1 -eq 1 ]
  5. [root@localhost ~]# echo $?
  6. 0
  7. [root@localhost ~]# [ 1 -ge 1 ]
  8. [root@localhost ~]# echo $?
  9. 0
  10. [root@localhost ~]# [ 1 -ge 2 ]
  11. [root@localhost ~]# echo $?
  12. 1
  13. [root@localhost ~]# [ 1 -lt 2 ]
  14. [root@localhost ~]# echo $?
  15. 0
  16. [root@localhost ~]# [ 1 -le 2 ]
  17. [root@localhost ~]# echo $?
  18. 0
  19. [root@localhost ~]# [ 1 -le 10 ]
  20. [root@localhost ~]# echo $?
  21. 0
  22. [root@localhost ~]# [ 10 -le 10 ]
  23. [root@localhost ~]# echo $?
  24. 0
  25. [root@localhost ~]# [ 1 -ne 2 ]
  26. [root@localhost ~]# echo $?
  27. 0
  28. [root@localhost ~]# [ 2 -ne 2 ]
  29. [root@localhost ~]# echo $?
  30. 1

字符串对比

  • == 相等
  • != 不相等
  1. [root@localhost ~]# [ root == xxoo ]
  2. [root@localhost ~]# echo $?
  3. 1
  4. [root@localhost ~]# [ root == $USER ]
  5. [root@localhost ~]# echo $?
  6. 0
  7. [root@localhost ~]# [ $USER == root ]
  8. [root@localhost ~]# echo $?
  9. 0
  10. [root@localhost ~]# [ abc == bcd ]
  11. [root@localhost ~]# echo $?
  12. 1
  13. [root@localhost ~]# [ abc != bcd ]
  14. [root@localhost ~]# echo $?
  15. 0
  16. [root@localhost ~]# [ $USER != root ]
  17. [root@localhost ~]# echo $?
  18. 1