shell概述
- shell是一个程序,它连接了用户和Linux内核,它可以解释用户输入的命令传递给内核,让用户可以更加方便的使用Linux系统
- shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序
- shell具备编程的能力,shell也是一种语言,C,C++,java,Python,Go等
- 语言分为编译型语言,C,C++,Go,需要提前编译,编译语言都有编译器
- 解释型语言,shell,Python,php,不需要提前编译,一边执行,一边编译,每种解释型语言都有解释器
- shell语言支持大部分编程语言都具备的功能:if判断,for循环,变量,数组,函数,加减乘除,逻辑运算
规范shell脚本组成
[root@test ~]# vim user.sh#!/bin/bash(环境声明)#注释信息可执行代码…
如何写好一个shell脚本
- 明确任务需求
- 按需求整理好每一个步骤,先做什么,后做什么
- 运行脚本,并根据运行结果排除错误
- 优化脚本并达到最终效果
编写脚本
编写第一个脚本
[root@localhost ~]# vim hello.sh#!/bin/bash#hello wordecho hello word#赋予执行权限[root@localhost ~]# chmod u+x hello.sh#执行脚本[root@localhost ~]# /root/hello.sh hello word
编写创建用户脚本
[root@localhost ~]# vim user.sh#!/bin/bashuseradd abc passwd abc[root@localhost ~]# chmod u+x user.sh #非交互[root@localhost ~]# vim user.sh#!/bin/bashuseradd yyyyecho 1 | passwd --stdin yyyy[root@localhost ~]# ./user.sh 更改用户 yyyy 的密码 。passwd:所有的身份验证令牌已经成功更新。
编写批量查看脚本
#查看系统版本信息,查看系统内核信息,查看系统内存信息,查看系统网卡信息,查看当前主机名[root@localhost ~]# vim info.shcat /etc/redhat-releaseuname -rfree -hifconfig ens32hostname#赋予执行权限[root@localhost ~]# chmod u+x info.sh #执行脚本[root@localhost ~]# ./info.sh CentOS Linux release 7.6.1810 (Core) 3.10.0-957.el7.x86_64 total used free shared buff/cache availableMem: 972M 480M 147M 16M 344M 260MSwap: 2.0G 239M 1.8Gens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.100 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::8903:cb8:127b:dbc8 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:a0:e8:12 txqueuelen 1000 (Ethernet) RX packets 230110 bytes 325471733 (310.3 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 20635 bytes 1385581 (1.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0localhost.localdomain
编写配置本地yum源脚本
#编写搭建本地yum仓库脚本【版1,丢人版】[root@localhost ~]# vim yum.sh #!/bin/bashmkdir /mnt/centosmount /dev/cdrom /mnt/centosecho '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstabrm -rf /etc/yum.repos.d/*touch /etc/yum.repos.d/local.repoecho "[local]" > /etc/yum.repos.d/local.repoecho "name=local_centos" >> /etc/yum.repos.d/local.repoecho "baseurl=file:///mnt/centos" >> /etc/yum.repos.d/local.repoecho "enabled=1" >> /etc/yum.repos.d/local.repoecho "gpgcheck=0" >> /etc/yum.repos.d/local.repo#编写搭建本地yum仓库脚本【版2,正常版】[root@localhost ~]# vim yum.sh #!/bin/bashmkdir /mnt/centosmount /dev/cdrom /mnt/centosecho '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstabmount -arm -rf /etc/yum.repos.d/*echo "[local] name=local_centos baseurl=file:///mnt/centos enabled=1 gpgcheck=0" > /etc/yum.repos.d/local.repo#编写搭建本地yum仓库脚本【升级版】[root@localhost ~]# vim yum.sh #!/bin/bashecho "正在配置本地yum仓库..."mkdir /mnt/centosmount /dev/cdrom /mnt/centos &> /dev/nullecho '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstabmount -arm -rf /etc/yum.repos.d/*echo "[local] name=local_centos baseurl=file:///mnt/centos enabled=1 gpgcheck=0" > /etc/yum.repos.d/local.repoecho "本地yum仓库配置以完成..."yum clean all &> /dev/nullecho "仓库软件包数量"yum repolist | tail -1#执行脚本[root@localhost ~]# ./yum.sh正在配置本地yum仓库...本地yum仓库配置以完成...repolist: 4,021仓库软件包数量
脚本的执行方式
- 执行一个脚本的方法有很多种
- 方法一:赋予脚本执行权限后,可用绝对路径或者当前路径执行
- 方法二:调用解释器执行脚本文件
#绝对路径执行脚本[root@localhost ~]# /root/hello.sh #相对路径执行脚本[root@localhost ~]# ./hello.sh #去除执行权限[root@localhost ~]# chmod u-x hello.sh #执行脚本[root@localhost ~]# /root/hello.sh-bash: /root/hello.sh: 权限不够[root@localhost ~]# ./hello.sh-bash: ./hello.sh: 权限不够#调用解释器执行脚本[root@localhost ~]# bash hello.shhello word[root@localhost ~]# cat /etc/shells /bin/sh/bin/bash/usr/bin/sh/usr/bin/bash/bin/tcsh/bin/csh[root@localhost ~]# sh hello.shhello word[root@localhost ~]# tcsh hello.shhello word[root@localhost ~]# csh hello.shhello word
常用特殊符号补充
- “ “ #双引号,引用整体
- ‘ ’ #单引号,引用整体并取消所有特殊字符含义
- $[] #四则运算(+ - * / % 取余数)
- $() #将命令的输出结果作为参数
- #反撇 `` 将命令的输出结果作为参数
#引用整体,不屏蔽特殊符号的功能[root@localhost ~]# echo "$PATH"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin#引用整体,屏蔽特殊符号的功能[root@localhost ~]# echo '$PATH'$PATH#没有特殊符号单引双引都可以[root@localhost ~]# echo "xxoo"xxoo[root@localhost ~]# echo 'xxoo'xxoo#四则运算[root@localhost ~]# echo $[1+1]2[root@localhost ~]# echo $[1+5]6[root@localhost ~]# echo $[10-5]5[root@localhost ~]# echo $[10*5]50[root@localhost ~]# echo $[10/5]2[root@localhost ~]# echo $[1+3+4+5+7]20[root@localhost ~]# echo $[10/3]3[root@localhost ~]# echo $[10%3]1#$()取命令结果作为参数root@localhost ~]# touch $(date +%F)-abc.txt2021-05-09-abc.txt #``取命令结果作为参数[root@localhost ~]# touch `date +%F`-xxoo.txt2021-05-09-xxoo.txt
变量
- 以固定的名称存放可能变化的值,提高脚本的灵活度来适应多变的环境
- 定义变量:变量名=变量值,如:a1=abc(等号两边不要有空格)
- 取消变量:unset 变量名
- 定义变量注意事项:
- 变量名由字母/数字/下划线组成,区分大小写,不能以数字开头,不要使用命令和特殊符号
- 若指定的变量名已经存在,相当于为此变量重新赋值
root@localhost ~]# xx=haha[root@localhost ~]# echo $xxhaha[root@localhost ~]# xx=abcd[root@localhost ~]# echo $xxabcd[root@localhost ~]# xx=5[root@localhost ~]# echo $xx5[root@localhost ~]# echo $[xx+5]10#通过变量定义用户名[root@localhost ~]# vim user.sh #!/bin/bashuser=wangxinuseradd $user echo 1 | passwd --stdin $user[root@localhost ~]# ./user.sh 更改用户 wangxin 的密码 。passwd:所有的身份验证令牌已经成功更新。[root@localhost ~]# vim user.sh #!/bin/bashuser=sdduseradd $userecho 1 | passwd --stdin $user[root@localhost ~]# ./user.sh 更改用户 sdd 的密码 。passwd:所有的身份验证令牌已经成功更新。[root@localhost ~]# vim user.sh #!/bin/bashuser=panghuuseradd $userecho "用户$user创建成功"echo 1 | passwd --stdin $user &> /dev/nullecho "用户$user密码设置成功"[root@localhost ~]# ./user.sh 用户panghu创建成功用户panghu密码设置成功
read标准输入取值
- read 读取用户在键盘上输入的内容,并把内容存放在变量里,可以降低脚本的使用难度
- 命令格式:read -p “提示信息” 变量名
[root@localhost ~]# vim user.sh #!/bin/bashread -p '请输入用户名:' useruseradd $user echo "用户$user创建成功"read -p '请设置用户密码:' passecho $pass | passwd --stdin $user &> /dev/nullecho "用户$user密码设置成功"[root@localhost ~]# ./user.sh 请输入用户名:wuhan用户wuhan创建成功请设置用户密码:1用户wuhan密码设置成功[root@localhost ~]# ./user.sh 请输入用户名:liangjing用户liangjing创建成功请设置用户密码:xxoo用户liangjing密码设置成功
变量种类
- 环境变量:变量名一般都大写,用来设置用户/系统环境
- 位置变量:bash内置,存储执行脚本时提供的命令参数
- 预定义变量:bash内置,可直接调用的特殊值,不能直接修改
- 自定义变量:用户自定义
- env 命令查看系统所有环境变量
- set 命令查看系统所有变量,包括用户自定义变量
- 环境变量
[root@localhost etc]# envMAIL=/var/spool/mail/rootPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/binPWD=/rootLANG=zh_CN.UTF-8SELINUX_LEVEL_REQUESTED=HISTCONTROL=ignoredupsSHLVL=1HOME=/rootLOGNAME=rootXDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/shareSSH_CONNECTION=192.168.0.1 51791 192.168.0.100 22LESSOPEN=||/usr/bin/lesspipe.sh %sXDG_RUNTIME_DIR=/run/user/0DISPLAY=localhost:10.0_=/usr/bin/envOLDPWD=/root#获取变量值[root@localhost etc]# echo $SHELL/bin/bash[root@localhost ~]# echo $PWD/root#查看系统所有变量[root@localhost ~]# set[root@localhost ~]# set | grep $a
判断文件状态[ 参数 ]
- -e #判断文档(文件/目录)是否存在,存在为真
- -d #判断目录是否存在,存在为真
- -f #判断文件是否存在,存在为真
- -r #可读为真
- -w #可写为真
- -x #可执行为真
#判断文档是否存在[root@localhost ~]# [ -e /etc/ ][root@localhost ~]# echo $?0 #为真#判断目录是否存在[root@localhost ~]# [ -d /opt ][root@localhost ~]# echo $?0[root@localhost ~]# [ -d /etc/passwd ][root@localhost ~]# echo $?1[root@localhost ~]# [ -f /etc/passwd ][root@localhost ~]# echo $?0#判断是否可读(以当前用户身份判断)[root@localhost ~]# [ -r /etc/passwd ][root@localhost ~]# echo $?0#判断是否可写[root@localhost ~]# [ -w /etc/passwd ][root@localhost ~]# echo $?0#判断是否可执行[root@localhost ~]# [ -x /etc/passwd ][root@localhost ~]# echo $?1[root@localhost ~]# ll /etc/passwd-rw-r--r--. 1 root root 3294 5月 9 16:43 /etc/passwd
整数比较
- -gt 大于
- -ge 大于等于
- -eq 等于
- -lt 小于
- -le 小于等于
- -ne 不等于
[root@localhost ~]# [ 1 -gt 1 ][root@localhost ~]# echo $?1[root@localhost ~]# [ 1 -eq 1 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 1 -ge 1 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 1 -ge 2 ][root@localhost ~]# echo $?1[root@localhost ~]# [ 1 -lt 2 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 1 -le 2 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 1 -le 10 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 10 -le 10 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 1 -ne 2 ][root@localhost ~]# echo $?0[root@localhost ~]# [ 2 -ne 2 ][root@localhost ~]# echo $?1
字符串对比
[root@localhost ~]# [ root == xxoo ][root@localhost ~]# echo $?1[root@localhost ~]# [ root == $USER ][root@localhost ~]# echo $?0[root@localhost ~]# [ $USER == root ][root@localhost ~]# echo $?0[root@localhost ~]# [ abc == bcd ][root@localhost ~]# echo $?1[root@localhost ~]# [ abc != bcd ][root@localhost ~]# echo $?0[root@localhost ~]# [ $USER != root ][root@localhost ~]# echo $?1