shell脚本


由shell命令组成文本文件

输出语句的使用
echo

1.普通输出

[root@localhost ~]# echo linux
linux
[root@localhost ~]# echo "help word"
help word
[root@localhost ~]# echo -e "shell \n python"
shell 
 python
[root@localhost ~]# echo -e "shell\npython"
shell
python
[root@localhost ~]# echo -e "shell\tpython"
shell python
[root@localhost ~]# 

2.“”与‘’的区别

[root@localhost ~]# echo "oooo!!"
echo "ooooecho 'oooo!!'"
ooooecho 'oooo!!'
[root@localhost ~]# 

引号的使用

格式 作用
单引号 所有字符会被作为普通字符输出
双引号 特殊字符会被转义

”“表示重复执行历史命令的最后一行

输出多行内容 (here document )
cat

cat << 【开始符号】。。。【结束符号】

[root@localhost ~]# cat << eof
> linux
> python
> shell
> C++
> java
> eof

linux
python
shell
C++
java
[root@localhost ~]# 
[root@localhost ~]# cat << ll
> hfdasj
> .shjf
> shdujf
> ll
hfdasj
.shjf
shdujf
[root@localhost ~]# 
重定向符号
名称 文件
标准输入设备文件 /dev/stdin
标准输出设备文件 /dev/stdout
标准错误输出文件 /dev/stderr
输出重定向符号
符号 作用
> 覆盖
>> 追加
2> 仅用于重定向标准错误
&> 输出重定向,结=杰锅不会显示屏幕上
[root@localhost ~]# ls | > /dev/null 
[root@localhost ~]# ls > ./ttt.txt
[root@localhost ~]# cat ./ttt.txt 
anaconda-ks.cfg
jiaowu.sql
mysqlbak
ttt.txt
[root@localhost ~]# ls >> ./ttt.txt
[root@localhost ~]# cat ./ttt.txt 
anaconda-ks.cfg
jiaowu.sql
mysqlbak
ttt.txt
anaconda-ks.cfg
jiaowu.sql
mysqlbak
ttt.txt
输入重定向符号
[root@localhost ~]# tr 'a-z' 'A-Z' < ./ttt.txt 
ANACONDA-KS.CFG
JIAOWU.SQL
MYSQLBAK
TTT.TXT
ANACONDA-KS.CFG
JIAOWU.SQL
MYSQLBAK
TTT.TXT
变量的使用

变量名称规范

只能字母、数字、下划线
只能以字母、下划线开头
见名知义
不能shell关键字冲突

调用变量的值

$变量名称
${变量名称}

[root@localhost ~]# name=djfhkjasd
[root@localhost ~]# echo $name
djfhkjasd

[root@localhost ~]# echo my name is $name
my name is djfhkjasd

[root@localhost ~]# echo "my name is ${name}"
my name is djfhkjasd
变量的数学运算
[root@localhost ~]# a=10
[root@localhost ~]# b=20
[root@localhost ~]# c=$a+$b
[root@localhost ~]# echo $c
10+20
[root@localhost ~]# c=$((a+b))
[root@localhost ~]# echo $c
30
[root@localhost ~]# c=$a+$b
[root@localhost ~]# let c=a+b
[root@localhost ~]# echo $c
30
[root@localhost ~]# 
定义变量保存命令结果
[root@localhost ~]# result=$(ls )
[root@localhost ~]# echo $result 
anaconda-ks.cfg jiaowu.sql mysqlbak
[root@localhost ~]# 
交互式变量赋值
[root@localhost ~]# read -p "请输入密码" passwd
请输入密码123456      
[root@localhost ~]# echo $passwd 
123456
环境变量

1.查看环境变量

 [root@node01 ~]# env
 

2.定义环境变量

# export 变量名称=值 

3.定义在历史命令中显示时间

[root@localhost ~]# history 
    1  cd /etc/yum.repos.d/
    2  ls
    3  mv CentOS-Base.repo CentOS-Base.repo.bak
    4  mv CentOS-Base.repo.bak CentOS-Base.repo
    5  yum install wget
[root@localhost ~]# vim /etc/profile       
 76 unset -f pathmunge
 77 export HISTTIMEFORMAT="%F_%T"  
[root@localhost ~]# source /etc/profile
[root@localhost ~]# history 
    1  2020-09-22_04:37:47cd /etc/yum.repos.d/
    2  2020-09-22_04:37:47ls
    3  2020-09-22_04:37:47mv CentOS-Base.repo CentOS-Base.repo.bak
    4  2020-09-22_04:37:47mv CentOS-Base.repo.bak CentOS-Base.repo
    5  2020-09-22_04:37:47yum install wget
    6  2020-09-22_04:37:47yum install vim
    7  2020-09-22_04:37:47cd 
    8  2020-09-22_04:37:47systemctl disable firewalld
    9  2020-09-22_04:37:47cd /etc/selinux/
   10  2020-09-22_04:37:47ls

简单的脚本设计

1.设计一个创建用户的脚本

[root@localhost shell]# vim useradd.sh
in/bash
  2 
  3 
  4 useradd liuyan
  5 echo "ly"|passwd --stdin liuyan &> /etc/null
  6                                                                                                                
  7 
[root@localhost shell]# bash ./useradd.sh 
[root@localhost shell]# id liuyan
uid=1000(liuyan) gid=1000(liuyan) groups=1000(liuyan)

2.设计一个交互式创建用户脚本

[root@localhost shell]# vim ./useradd.sh 
in/bash
  2 
  3 read -p "用户名:" name
  4 read -p "密码:" password
  5 
  6 
  7 
  8 
  9 useradd $name
 10 
 11 echo "$password"|passwd --stdin $name &> /etc/null
 12 
 13 
 14 echo "用户创建完成"                                                                                            
 15 
 16 
[root@localhost shell]# userdel liuyan
[root@localhost shell]# 
[root@localhost shell]# 
[root@localhost shell]# 
[root@localhost shell]# id liuyan
id: liuyan: no such user
[root@localhost shell]# 
[root@localhost shell]# 
[root@localhost shell]# 
[root@localhost shell]# bash ./useradd.sh 
用户名:liuyan
密码:ly
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
Creating mailbox file: File exists
用户创建完成
[root@localhost shell]# 
逻辑控制语句——if语句

语法

if 条件; then
执行的操作
执行的操作
fi

数字表达式

表达式 作用
[ number1 -eq number2 ] 等于
[ number1 -ne number2 ] 不等于
[ number1 -gt number2 ] 大于
[ number1 -ge number2 ] 大于等于
[ number1 -lt number2 ] 小于
[ number1 -le number2 ] 小于等

1.设计一个简单的创建用户脚本

[root@localhost shell]# vim checkuser.sh
Error detected while processing /root/.vimrc:
line    1:
E518: Unknown option: #行号
line    2:
E518: Unknown option: #行标准线
line    3:
E518: Unknown option: #自动缩进
line    4:
E518: Unknown option: #tab标准
Press ENTER or type command to continue
  1 #!/bin/bash
  2 
  3 read -p "用户名:" name
  4 id $name &> /dev/null
  5 
  6 
  7 if [ $? -ne 0 ]; then                                                                                          
  8 useradd $name
  9 echo "$name" |passwd -stdin $name &> /dev/null
 10 echo "用户$name 已经创建,初始密码是用户名"
 11 
 12 
 13 else
 14 echo "创建失败"
 15 fi
逻辑控制语句——case语句

语法

case 变量 in
值1)
执行操作
执行操作
;;
值2)
执行操作
执行操作
;;

示例一

[root@localhost shell]# vim case.sh
 1 #!/bin/bash
  2 
  3 read -p "请输入:" data
  4    case $data in
  5    linux|Linux)
  6    echo "Centos"
  7    ;;
  8    windows)
  9    echo "Windows10"
 10    ;;
 11    *)
 12    echo "NO"
 13    ;;
 14 esac
位置变量

$1, $2, $3…$9, ${10} $1:第一个参数

$0
命令本身

$#
参数个数

示例一

[root@localhost shell]# vim case.sh

  1 #!/bin/bash
  2 
  3    case $1 in                                                                                                  
  4    linux)
  5    echo "Centos"
  6    ;;
  7    windows)
  8    echo "Windows10"
  9    ;;
 10    *)
 11    echo "NO"
 12    ;;
 13 esac
[root@localhost shell]# chmod a+x ./case.sh 
[root@localhost shell]# 
[root@localhost shell]# 
[root@localhost shell]# ./case.sh lll
NO

示例二

[root@localhost shell]# vim case.sh

  1 #!/bin/bash
  2 
  3 if [ $# == 0 ]; then                                                                                           
  4     echo "error"
  5     exit 10
  6 fi
  7 
  8 
  9    case $1 in
 10    linux)
 11    echo "Centos"
 12    ;;
 13    windows)
 14    echo "Windows10"
 15    ;;
 16    *)
 17    echo "NO"
 18    ;;
 19 esac
 20 
[root@localhost shell]# ./case.sh dsf
NO
[root@localhost shell]# ./case.sh linux
Centos
[root@localhost shell]# ./case.sh 
error
利用脚本进行nginx测试

1.安装nginx

[root@bogon data]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
--2020-10-01 22:45:37--  http://nginx.org/download/nginx-1.18.0.tar.gz
Resolving nginx.org (nginx.org)... 52.58.199.22, 3.125.197.172, 2a05:d014:edb:5704::6, ...
Connecting to nginx.org (nginx.org)|52.58.199.22|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1039530 (1015K) [application/octet-stream]
Saving to: ‘nginx-1.18.0.tar.gz’


[root@bogon data]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.huaweicloud.com
 * extras: mirrors.huaweicloud.com
 * updates: mirrors.ustc.edu.cn

[root@bogon data]# tar -xvf nginx-1.18.0.tar.gz
nginx-1.18.0/
nginx-1.18.0/auto/
nginx-1.18.0/conf/
nginx-1.18.0/contrib/
nginx-1.18.0/src/
nginx-1.18.0/configure

[root@bogon ~]# cd /usr/local/
[root@bogon local]# ls
bin  etc  games  include  lib  lib64  libexec  sbin  share  src
[root@bogon local]# cp  -r /root/data/nginx ./
[root@bogon local]# ls
bin  etc  games  include  lib  lib64  libexec  nginx  sbin  share  src

[root@bogon nginx-1.18.0]# ./configure 
checking for OS
 + Linux 3.10.0-327.el7.x86_64 x86_64
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 4.8.5 20150623 (Red H
[root@bogon nginx-1.18.0]# make
make -f objs/Makefile
make[1]: Entering directory `/usr/local/nginx/nginx-1.18.0'
cc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  -I src/core -I src/event -I src/event/modules -I src/os/unix -I

[root@bogon nginx-1.18.0]# make install
make -f objs/Makefile install
make[1]: Entering director

[root@bogon nginx]# ls
conf  html  logs  nginx-1.18.0  sbin
[root@bogon nginx]# cd sbin/
[root@bogon sbin]# ls
nginx

2.利用脚本控制nginx

[root@bogon shell]# vim nginxctl
  1#!bin/bash
  2 
  3 
  4 nginx=/usr/local/nginx/sbin/nginx
  5 
  6 #检测参数是否存在
  7 if [ $# == 0 ]; then
  8     echo "请输入参数"
  9     exit 10
 10 fi
 11 
 12 case $1 in 
 13     start)
 14     $nginx
 15         if [ $? == 0 ]; then
 16             echo "nginx启动成功"
 17         fi
 18     ;;
 19     stop)
 20     $nginx -s stop
 21         if [ $? == 0 ]; then
 22             echo "nginx关闭成功"
 23         fi
 24     ;;
 25     restart)
 26     $nginx -s stop
 27         if [ $? == 0 ]; then
 28             sleep 1
 29             $nginx
 30         else
 31             echo "执行失败"
 32         fi
 33     ;;                                                                                                         
 34 esac
 35 
 36 
 37 

[root@bogon shell]# bash ./nginxctl.sh
请输入参数
[root@bogon shell]# bash ./nginxctl.sh start
nginx启动成功
[root@bogon shell]# bash ./nginxctl.sh stop
nginx关闭成功
逻辑控制语句——for语句

语法:

for 变量 in 取值列表; do
执行的操作
执行的操作
done

[root@bogon shell]# vim for.sh
  1#!bin/bash
  2 
  3 for i in {1..10}; do
  4     echo "$i"
  5     done
  [root@bogon shell]# bash ./for.sh 
1
2
3
4
5
6
7
8
9
10
 
   1 #!/bin/bash
  2 
  3 for i in $(seq 10); do                                                                                         
  4     echo "$i"
  5     done
  [root@bogon shell]# bash ./for.sh 
1
2
3
4
5
6
7
8
9
10
  1 #!/bin/bash
  2 
  3 for i in $(seq 2 10); do                                                                                       
  4     echo "$i"
  5     done
[root@bogon shell]# bash ./for.sh 
2
3
4
5
6
7
8
9
10


  1 #!/bin/bash
  2 
  3 for i in $(seq 1 2 10); do                                                                                     
  4     echo "$i"
  5     done
[root@bogon shell]# bash ./for.sh 
1
3
5
7
9
               
#!/bin/bash
#
for i in $(seq 20); do
if id user$i &> /dev/null; then
echo "用户user$i存在"
else
useradd user$i
echo "redhat" | passwd ‐‐stdin user$i &> /dev/null 
echo "用户user$i创建完成, 初始密码为redhat"
fi
done
中断语句

continue 中断本次循环, 立刻开始执行下一次循环

break 中断整体循环

1#!/bin/bash 
2 #
3
4 for i in $(seq 5); do 
5  echo "第$i次循环开始" 
6  if [ $i ‐eq 2 ]; then 
7  continue 
8  fi 
9  echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" 
10  echo "第$i次循环结束" 
11 done 
1 #!/bin/bash 
2 #
3 
4 for i in $(seq 5); do 
5  echo "第$i次循环开始" 
6  if [ $i ‐eq 2 ]; then 
7  break 
8  fi 
9  echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐" 
10  echo "第$i次循环结束" 
11 done
[root@localhost shell]# vim ping.sh
  1 #!/bin/bash
  2 
  3 
  4 net=192.168.122.
  5 for i in $(seq 254); do
  6     if ping -c 1 -W 1 $net$i &> /dev/null; then
  7     echo "$net$i 正常"
  8     fi
  9 done
[root@localhost shell]# bash ./ping.sh 
192.168.122.1 正常
192.168.122.2 正常
192.168.122.10 正常
                                                                                                           

截取IP和MAC地址

2 #!/bin/bash 
3 #
4 
5 local_ip=$(ifconfig ens33 | grep "netmask" | awk '{print $2}') 6 local_mac=$(ifconfig ens33 | grep "ether" | awk '{print $2}')
7 
8 echo "本地IP地址: $local_ip 本地MAC地址: $local_mac"
9
10 
11 for i in $(seq 254); do 
12  if [ $i ‐eq 10 ]; then 
13  continue 
14  fi
15 
16  if ping 192.168.183.$i &> /dev/null; then 
17  mac_addr=$(arping ‐I ens33 ‐c 1 ‐w 1 192.168.183.$i | grep "Unicast" | awk '{print $5}') 
18  echo "IP地址: 192.168.183.$i MAC地址: $mac_addr" 
19  fi 
20 done
shell中的字符串处理

[root@node01 ~]# str01=linux       
[root@node01 ~]# echo ${#str01}    #字符串长度
 5 
[root@node01 ~]# echo ${str01:1:2}     #从字符串第号开始到第二号结束
 in 
[root@node01 ~]# echo ${str01:1:3}    #从字符串第号开始到第三号结束
 inu 
[root@node01 ~]# echo ${str01:2}    #从字符串第二号开始到结尾
 nux

替换

[root@node01 ~]# filename=/opt/bj/a.txt 
[root@node01 ~]#  
[root@node01 ~]# echo ${filename/bj/sh} 
/opt/sh/a.txt 
[root@node01 ~]# str01="linux linux mac linux" 
[root@node01 ~]# echo ${str01//linux/IBM}
IBM IBM mac IBM 

大小写替换

[root@node01 ~]# str01="AbCd" 
[root@node01 ~]# echo ${str01,} 
abCd 
[root@node01 ~]# echo ${str01,,} 
abcd 
[root@node01 ~]# str01="aBcD" 
[root@node01 ~]# echo ${str01^} 
ABcD 
[root@node01 ~]# echo ${str01^^}
ABCD

文件校验脚本

[root@localhost shell]# vim testfile.sh 
in/bash
  2 
  3 for sname in $(find /root/shell - name "*.*"); do
  4     dname=${sname/shell/shellbak}                                                                              
  5     if [ ! -e $dname ]; then 
  6         echo "文件$dname丢失"
  7     else
  8         smd5=$(md5sum $sname |awk '{print $1}')
  9         dmd5=$(md5sum $dname |awk '{print $1}')
 10         if [ $smd5 != $dmd5 ]; then
 11             echo "文件$dname数据错误"
 12         fi
 13     fi
 14 done
~                                 
逻辑控制语句——while语句

语法
while 条件; do
执行的操作
执行的操作
改变条件真假的语句
done

1 #!/bin/bash 
2 #
3 
4 network=192.168.183.
5 
6 i=1
7 
8 while [ $i ‐le 254 ]; do 
9  if ping ‐c 1 ‐W 1 $network$i &> /dev/null; then 
10  echo "Host $network$i is up" 
11  fi 
12  let i++ 
13 done
1 #!/bin/bash 
2 #
3 
4 while read line; do 
5  name=$(echo $line | awk ‐F: '{print $1}') 
6  user_id=$(echo $line | awk ‐F: '{print $3}') 
7  group_id=$(echo $line | awk ‐F: '{print $4}') 
8  comment=$(echo $line | awk ‐F: '{print $5}') 
9  home_dir=$(echo $line | awk ‐F: '{print $6}') 
10  sh_name=$(echo $line | awk ‐F: '{print $7}')
11 
12  mysql ‐uroot ‐e "insert into testdb.userInfo(name,user_id,group_id,comm ent,home_dir,sh_name) values('$name',$user_id,$group_id,'$comment','$home_d ir','$sh_name')" 
13 done < /etc/passwd

应用案例

1 #!/bin/bash 
2 #
3 
4 l_number=0 5 e_number=0
6 
7 while read line; do 
8  status=$(echo $line | awk '{print $6}') 
9  if [ $status == "LISTEN" ]; then 
10  let l_number++ 
11  elif [ $status == "ESTABLISHED" ]; then 12  let e_number++ 13  fi 
14 done < <(netstat ‐antp | grep "^tcp")
15 
16 echo "Listen状态数量: $l_number
函数的相关学习

优势:

1. 方便功能的重复使用
2. 方便二次修改

语法1:

1 函数名称()
{ 2 … 3 … 4 … 5 }

语法2:

1 function 函数名称()
{ 2 … 3 … 4 … 5 }

1 #!/bin/bash 
2 #
3 
4 # 添加用户 
5 createUser() { 
6  read ‐p "用户名:" username 
7  if id $username &> /dev/null; then 
8  echo "用户$username存在" 
9  else 
10  useradd $username 
11  echo "用户$username创建完成" 
12  fi 
13 }
14
15 
16 # 删除用户 $1 用户名 
17 removeUser() { 
18  if id $1 &> /dev/null; then 
19  userdel ‐r $1 
20  echo "用户$1删除成功" 
21  else 
22  echo "用户$1不存在"
23  fi 
24 }
25 
26 # 修改用户shell, $1用户名 $2 shell名称 
27 modifyUser() { 
28  if id $1 &> /dev/null; then 
29  old_sh_name=$(grep "^$1:" /etc/passwd | awk ‐F: '{print $7}') 
30  echo "用户$1当前使用的shell为: $old_sh_name" 
31  usermod ‐s $2 $1 
32  echo "用户$1的shell被修改为$2" 
33  fi
34 
35 }
36 
37 cat << eof 
38 ‐‐‐‐用户管理‐‐‐‐
39 1. 添加用户 
40 2. 删除用户 
41 3. 修改用户信息 
42 4. 退出 
43 eof
44 
45 while true; do 
46  read ‐p "选择: " choice 
47  case $choice in 
48  1) 
49  createUser 
50  ;; 
51  2) 
52  read ‐p "用户名: " username 
53  removeUser $username 
54  ;; 
55  3) 
56  read ‐p "用户名: " username 
57  read ‐p "shell名称: " sh_name 
58  modifyUser $username $sh_name 
59  ;; 
60  4) 
61  echo "Bye‐‐bye " 
62  exit 8
expect工具的使用

作用:捕获交互式的输出,根据输出自动发送参数

1.捕获远程拷贝文件的命令相关信息(scp)

1 #!/usr/bin/expect 
2 #
3 
4 set timeout 3
5 
6 spawn scp /etc/fstab root@192.168.183.11:/tmp 
7 expect " password:" 
8 send "redhat\n"
9 
10 expect eof
[root@localhost ~]# expect ./text

2.结合shell脚本使用expect

1 #!/bin/bash 
2 #
3 
4 read ‐p "文件名称: " file_name
5 
6 if [ ‐e $file_name ]; then 
7 /usr/bin/expect << eof 
8 set timeout 3 
9 spawn scp $file_name root@192.168.183.11:/tmp 
10 expect "password:" 
11 send "redhat\n" 
12 expect eof 
13 eof 
14 fi
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐