Shell概述
Shell是一门编程语言,如:C C++ java php 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 word
echo hello word

#赋予执行权限
[root@localhost ~]# chmod u+x hello.sh

#执行脚本
[root@localhost ~]# /root/hello.sh
hello word

编写创建用户脚本
[root@localhost ~]# vim user.sh
#!/bin/bash
useradd abc
passwd abc

[root@localhost ~]# chmod u+x user.sh

#非交互
[root@localhost ~]# vim user.sh 
#!/bin/bash
useradd yyyy
echo 1 | passwd --stdin yyyy

[root@localhost ~]# ./user.sh 
更改用户 yyyy 的密码。 
passwd:所有的身份验证令牌已经成功更新。

编写批量查看系统信息脚本
#查看系统版本信息,查看系统内核信息,查看系统内存信息,查看系统网卡信 息,查看当前主机名
[root@localhost ~]# vim info.sh
cat /etc/redhat-release
uname -r
free -h
ifconfig ens32
hostname

#赋予执行权限
[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
buff/cache   available
Mem:           972M        480M
     344M        260M
free shared
147M 16M
Swap:          2.0G        239M        1.8G
ens32: 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 0
localhost.localdomain

编写搭建本地软件仓库的脚本
#编写搭建本地yum仓库脚本【版1,丢人版】 
[root@localhost ~]# vim yum.sh 
#!/bin/bash
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >> /etc/fstab
rm -rf /etc/yum.repos.d/*
touch  /etc/yum.repos.d/local.repo
echo "[local]" > /etc/yum.repos.d/local.repo
echo "name=local_centos" >> /etc/yum.repos.d/local.repo
echo "baseurl=file:///mnt/centos" >>
/etc/yum.repos.d/local.repo
echo "enabled=1" >> /etc/yum.repos.d/local.repo
echo "gpgcheck=0" >> /etc/yum.repos.d/local.repo

#编写搭建本地yum仓库脚本【版2,标准版】 
[root@localhost ~]# vim yum.sh 
#!/bin/bash
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >>
/etc/fstab
mount -a
rm -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/bash
echo "正在配置本地yum仓库..." 
mkdir /mnt/centos
mount /dev/cdrom /mnt/centos &> /dev/null
echo '/dev/cdrom /mnt/centos iso9660 defaults 0 0' >>
/etc/fstab
mount -a
rm -rf /etc/yum.repos.d/*
echo "[local]
name=local_centos
baseurl=file:///mnt/centos
enabled=1
gpgcheck=0" > /etc/yum.repos.d/local.repo 
echo "本地yum仓库配置以完成..."
yum clean all &> /dev/null
yum repolist | tail -1

#执行脚本
[root@localhost ~]# ./yum.sh 
正在配置本地yum仓库... 
本地yum仓库配置以完成... 
repolist: 4,021

#带进度条版本
#!/bin/bash
echo "====正在搭建本地软件仓库====" 
b=''
for ((i=0;$i<=20;i++))
do
let jinshu=$i*5
printf "[%-20s]%d%%\r" $b $jinshu 
sleep 0.1
b=#$b
done
echo

rm -rf /etc/yum.repos.d/*
echo "[local]
name=local-centos-7.6
baseurl=file:///mnt/centos
enabled=1
gpgcheck=0" > /etc/yum.repos.d/centos.repo 
x=`yum repolist | tail -1 | awk '{print $2}'` 
echo "软件包数量为:$x"

脚本的执行方式
执行一个脚本的方法有很多种
方法一:赋予脚本执行权限后,可用绝对路径或者当前路径执行
方法二:调用解释器执行脚本文件
#绝对路径执行脚本
[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.sh 
hello word

[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
[root@localhost ~]# sh hello.sh
hello word
[root@localhost ~]# tcsh hello.sh
hello word
[root@localhost ~]# csh hello.sh
hello 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.txt
2021-05-09-abc.txt

#``取命令结果作为参数
[root@localhost ~]# tar -czf "`date "+%F %X"`_log.tar.gz" /var/log/*.log

变量
以固定的名称存放可能变化的值,提高脚本的灵活度来适应多变的环境 定义变量:变量名=变量值,如:i=abc(等号两边不要有空格) 定义变量注意事项:
变量名由字母/数字/下划线组成,区分大小写,不能以数字开头,
   不要使用命令和特殊符号
  若指定的变量名已经存在,相当于为此变量重新赋值
取消变量:unset 变量名
[root@localhost ~]# x=haha

[root@localhost ~]# echo xx
xx

[root@localhost ~]# echo $xx
haha

[root@localhost ~]# xx=abcd
[root@localhost ~]# echo $xx
abcd

[root@localhost ~]# xx=5
[root@localhost ~]# echo $xx
5
[root@localhost ~]# echo $[xx+5]
10

#通过变量定义用户名 
[root@localhost ~]# vim user.sh
#!/bin/bash
user=wangxin
useradd $user
echo 1 | passwd --stdin $user

[root@localhost ~]# ./user.sh 
更改用户 wangxin 的密码。 
passwd:所有的身份验证令牌已经成功更新。

[root@localhost ~]# vim user.sh
#!/bin/bash
user=jiumei
useradd $user
echo 1 | passwd --stdin $user

[root@localhost ~]# ./user.sh 
更改用户 jiumei 的密码。 
passwd:所有的身份验证令牌已经成功更新。

[root@localhost ~]# vim user.sh
#!/bin/bash
user=panghu
useradd $user
echo "用户$user创建成功"
echo 1 | passwd --stdin $user &> /dev/null 
echo "用户$user密码设置成功"

[root@localhost ~]# ./user.sh 
用户panghu创建成功 
用户panghu密码设置成功

read标准输入取值
read 读取用户在键盘上输入的内容,并把内容存放在变量里,可以降低脚本的使用难度
命令格式:read -p “提示信息” 变量名
[root@localhost ~]# vim user.sh 
#!/bin/bash
read -p '请输入用户名:' user
useradd $user 
echo "用户$user创建成功"
read -p '请设置用户密码:' pass
echo $pass | passwd --stdin $user &> /dev/null
echo "用户$user密码设置成功"

[root@localhost ~]# ./user.sh 
请输入用户名:wuhan
用户wuhan创建成功
请设置用户密码:1
用户wuhan密码设置成功

[root@localhost ~]# ./user.sh 
请输入用户名:liangjing
用户liangjing创建成功
请设置用户密码:xxoo
用户liangjing密码设置成功

变量种类
- 环境变量:变量名一般都大写,用来设置用户/系统环境
- 位置变量:bash内置,存储执行脚本时提供的命令参数
- 预定义变量:bash内置,可直接调用的特殊值,不能直接修改
- 自定义变量:用户自定义
- env 命令查看系统所有环境变量
- set  命令查看系统所有变量,包括用户自定义变量

环境变量
[root@localhost etc]# env
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=zh_CN.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
XDG_DATA_DIRS=/root/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
SSH_CONNECTION=192.168.0.1 51791 192.168.0.100 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
DISPLAY=localhost:10.0
_=/usr/bin/env
OLDPWD=/root

#获取变量值
[root@localhost etc]# echo $SHELL
/bin/bash

[root@localhost ~]# echo $PWD
/root

#查看系统所有变量
[root@localhost ~]# set
[root@localhost ~]# set | grep $a

位置变量
  $0    #脚本名称
  $1    #第一个参数   
  $2    #第二个参数
  $3    #第三个参数
  $4    #第四个参数
  $n… #第n个参数

预定义变量
  $0 #代表脚本本身
  $* #显示所有参数内容
  $# #显示有多少个参数
  $? #显示上一条命令的执行结果(0代表正确,非0代表错误)
  $$ #显示脚本进程号(PID)

[root@localhost ~]# vim test.sh 
#!/bin/bash
echo $0
echo $1
echo $2
echo $3
echo $*
echo $#
echo $$
echo $?

#赋予执行权限,执行脚本
[root@localhost ~]# ./test.sh xx oo dd
./test.sh  $0
xx         $1
oo         $2
dd         $3
xx oo dd   $*
3          $#
15594      $$
0          $?

#通过位置变量创建用户并设置密码
#!/bin/bash
useradd $1 &> /dev/null
echo "用户$1创建成功"
echo  $2 | passwd --stdin $1 &> /dev/null
echo "用户$1的密码设置成功,密码为$2"

判断文件状态
- -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

常用数值运算方式
- $[]    #四则运算(+ - * / % 取余数) 
- $(())   #数值运算工具
- expr  #数值运算工具
- let     #数值运算工具

[root@localhost ~]# echo $[10+5]
15
[root@localhost ~]# echo $[10-5]
5
[root@localhost ~]# echo $[10*5]
50
[root@localhost ~]# echo $[10/5]
2
[root@localhost ~]# echo $[10%3]
1

#$(())做数值运算
[root@localhost ~]# echo $((10+5))
15
[root@localhost ~]# echo $((10-5))
5
[root@localhost ~]# echo $((10*5))
50
[root@localhost ~]# echo $((10/5))
2
[root@localhost ~]# echo $((10%3))
1

#expr做数值运算
[root@localhost ~]# echo expr 2+3
expr 2+3
[root@localhost ~]# echo `expr 2+3`
2+3

#要求每一部分都要有空格
[root@localhost ~]# echo `expr 2 + 3`
5
[root@localhost ~]# echo `expr 10 - 3`
7

#当进行乘法运算时,需要实用“\”转义掉*的特殊功能
[root@localhost ~]# echo `expr 10 * 3`
expr: 语法错误

[root@localhost ~]# echo `expr 10 \* 3`
30
[root@localhost ~]# echo `expr 10 / 3`
3

#let做数值运算
[root@localhost ~]# let 1+1

#需要将运算的结果赋予一个变量存储
[root@localhost ~]# let x=1+1
[root@localhost ~]# echo $x
2
[root@localhost ~]# let a=10+5
[root@localhost ~]# echo $a
15

#通过变量的值进行运算
[root@localhost ~]# let b=a+x
[root@localhost ~]# echo $b
17

#let简写表达式	     #let完整表达式
let i++      		let i=i+1
[root@localhost ~]# i=10
[root@localhost ~]# let i++
[root@localhost ~]# echo $i
11

let i--        		let i=i-1
[root@localhost ~]# let i--
[root@localhost ~]# echo $i
10

let i+=2    		let i=i+2
[root@localhost ~]# let i+=2
[root@localhost ~]# echo $i
12

let i-=2     		let i=i-2
[root@localhost ~]# let i-=2
[root@localhost ~]# echo $i
10

let i*=2			let i=i*2
[root@localhost ~]# let i*=2
[root@localhost ~]# echo $i
20

let i/=2			let i=i/2
[root@localhost ~]# let i/=2
[root@localhost ~]# echo $i
10

let i%=2			let i=1%2
[root@localhost ~]# let i%=3
[root@localhost ~]# echo $i
1

字符串判断
- -z   #字符串的值为空为真
- -n   #字符串的值非空为真(相当于 ! -z)

#判断文件为空为真
[root@localhost ~]# [-z /etc/passwd]
bash: [-z: 未找到命令...

#判断时每一部分要有空格
[root@localhost ~]# [ -z /etc/passwd ]
[root@localhost ~]# echo $?
1

#判断文件非空为真
[root@localhost ~]# [ -n /etc/passwd ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ -z $i ]
[root@localhost ~]# echo $?
1

[root@localhost ~]# [ -n $i ]
[root@localhost ~]# echo $?
0

[root@localhost ~]# [ ! -z $i ]
[root@localhost ~]# echo $?
0
上一篇 下一篇