目录
第 1 章 Shell 概述
Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用系统内核。
Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。
1)Linux 提供的 Shell 解析器有
[ljz@ljz-virtual-machine ~]$ cat /etc/shells/bin/sh/bin/bash/usr/bin/sh/usr/bin/bash/bin/tcsh/bin/csh
2)bash 和 sh 的关系
[ljz@ljz-virtual-machine bin]$ ll | grep bash-rwxr-xr-x. 1 root root 941880 5 月 11 2016 bashlrwxrwxrwx. 1 root root4 5 月 27 2017 sh -> bash
3)大部分Linux系统默认的解析器是 bash
[ljz@ljz-virtual-machine bin]$ echo $SHELL/bin/bash
第 2 章 Shell 脚本入门
1)脚本格式
脚本以#!/bin/bash 开头(指定解析器)
2)第一个 Shell 脚本:helloworld.sh
[ljz@ljz-virtual-machine shells]$ touch helloworld.sh[ljz@ljz-virtual-machine shells]$ vim helloworld.sh在 helloworld.sh 中输入如下内容#!/bin/bashecho "helloworld"
[ljz@ljz-virtual-machine shells]$ sh ./helloworld.shHelloworld
sh+脚本的绝对路径
[ljz@ljz-virtual-machine shells]$ sh /home/atguigu/shells/helloworld.shhelloworld
[ljz@ljz-virtual-machine shells]$ bash ./helloworld.shHelloworld
[ljz@ljz-virtual-machine shells]$ bash /home/atguigu/shells/helloworld.shHelloworld
第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
①首先要赋予 helloworld.sh 脚本的+x 权限
[ljz@ljz-virtual-machine shells]$ chmod +x helloworld.sh
②执行脚本
[ljz@ljz-virtual-machine shells]$ ./helloworld.shHelloworld
绝对路径
[ljz@ljz-virtual-machine shells]$ /home/ljz/shells/helloworld.shHelloworld
[ljz@ljz-virtual-machine shells]$ cat test.sh#!/bin/bashA=5echo $A
②分别使用 sh,bash,./ 和 . 的方式来执行,结果如下:
[ljz@ljz-virtual-machine shells]$ bash test.sh[ljz@ljz-virtual-machine shells]$ echo $A[ljz@ljz-virtual-machine shells]$ sh test.sh[ljz@ljz-virtual-machine shells]$ echo $A[ljz@ljz-virtual-machine shells]$ ./test.sh[ljz@ljz-virtual-machine shells]$ echo $A[ljz@ljz-virtual-machine shells]$ . test.sh[ljz@ljz-virtual-machine shells]$ echo $A5
第 3 章 变量
3.1 系统预定义变量
1)常用系统变量
$HOME、$PWD、$SHELL、$USER 等
2)案例实操
(1)查看系统变量的值
[ljz@ljz-virtual-machine shells]$ echo $HOME/home/atguigu
[ljz@ljz-virtual-machine shells]$ setBASH=/bin/bashBASH_ALIASES=()BASH_ARGC=()BASH_ARGV=()
3.2 自定义变量
1)基本语法
2)变量定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格
(3)在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算。
3)案例实操
(1)定义变量 A
[ljz@ljz-virtual-machine shells]$ A=5[ljz@ljz-virtual-machine shells]$ echo $A5
(2)给变量 A 重新赋值
[ljz@ljz-virtual-machine shells]$ A=8[ljz@ljz-virtual-machine shells]$ echo $A8
[ljz@ljz-virtual-machine shells]$ unset A[ljz@ljz-virtual-machine shells]$ echo $A
[ljz@ljz-virtual-machine shells]$ readonly B=2[ljz@ljz-virtual-machine shells]$ echo $B2[ljz@ljz-virtual-machine shells]$ B=9-bash: B: readonly variable
[ljz@ljz-virtual-machine shells]$ C=1+2[ljz@ljz-virtual-machine shells]$ echo $C1+2
[ljz@ljz-virtual-machine shells]$ D=I love ljz-bash: world: command not found[ljz@ljz-virtual-machine shells]$ D="I love ljz"[ljz@ljz-virtual-machine shells]$ echo $DI love ljz
export 变量名[ljz@ljz-virtual-machine shells]$ vim helloworld.sh
在 helloworld.sh 文件中增加 echo $B
#!/bin/bashecho "helloworld"echo $B[ljz@ljz-virtual-machine shells]$ ./helloworld.shHelloworld
发现并没有打印输出变量 B 的值。
[ljz@ljz-virtual-machine shells]$ export B[ljz@ljz-virtual-machine shells]$ ./helloworld.shhelloworld2
3.3 特殊变量
3.3.1 $n
1)基本语法
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch parameter.sh[ljz@ljz-virtual-machine shells]$ vim parameter.sh#!/bin/bashecho '==========$n=========='echo $0echo $1echo $2[ljz@ljz-virtual-machine shells]$ chmod 777 parameter.sh[ljz@ljz-virtual-machine shells]$ ./parameter.sh cls xz==========$n==========./parameter.shclsxz
3.3.2 $#
1)基本语法
2)案例实操
[ljz@ljz-virtual-machine shells]$ vim parameter.sh#!/bin/bashecho '==========$n=========='echo $0echo $1echo $2echo '==========$#=========='echo $#[ljz@ljz-virtual-machine shells]$ chmod 777 parameter.sh[ljz@ljz-virtual-machine shells]$ ./parameter.sh cls xz==========$n==========./parameter.shclsxz==========$#==========2
3.3.3 $*、$@
1)基本语法
2)案例实操
[ljz@ljz-virtual-machine shells]$ vim parameter.sh#!/bin/bashecho '==========$n=========='echo $0echo $1echo $2echo '==========$#=========='echo $#echo '==========$*=========='echo $*echo '==========$@=========='echo $@[ljz@ljz-virtual-machine shells]$ ./parameter.sh a b c d e f g==========$n==========./parameter.shab==========$#==========7==========$*==========a b c d e f g==========$@==========a b c d e f g
3.3.4 $?
1)基本语法
2)案例实操
[ljz@ljz-virtual-machine shells]$ ./helloworld.shhello world[ljz@ljz-virtual-machine shells]$ echo $?0
第 4 章 运算符
1)基本语法
2)案例实操:
[ljz@ljz-virtual-machine shells]# S=$[(2+3)*4][ljz@ljz-virtual-machine shells]# echo $S
第 5 章 条件判断
1)基本语法
注意:条件非空即为 true,[ ljz ]返回 true,[ ] 返回 false。
2)常用判断条件
3)案例实操
[ljz@ljz-virtual-machine shells]$ [ 23 -ge 22 ][ljz@ljz-virtual-machine shells]$ echo $?0
[ljz@ljz-virtual-machine shells]$ [ -w helloworld.sh ][ljz@ljz-virtual-machine shells]$ echo $?0
[ljz@ljz-virtual-machine shells]$ [ -e /home/ljz/cls.txt ][ljz@ljz-virtual-machine shells]$ echo $?1
[ljz@ljz-virtual-machine shells]$ [ ljz ] && echo OK || echo notOKOK[ljz@ljz-virtual-machine shells]$ [ ] && echo OK || echo notOKnotOK
第 6 章 流程控制(重点)
6.1 if 判断
1)基本语法
if [ 条件判断式 ];then程序fi
if [ 条件判断式 ]then程序fi
if [ 条件判断式 ]then程序elif [ 条件判断式 ]then程序else程序fi
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch if.sh[ljz@ljz-virtual-machine shells]$ vim if.sh#!/bin/bashif [ $1 -eq 1 ]thenecho "banzhang zhen shuai"elif [ $1 -eq 2 ]thenecho "cls zhen mei"fi[ljz@ljz-virtual-machine shells]$ chmod 777 if.sh[ljz@ljz-virtual-machine shells]$ ./if.sh 1banzhang zhen shuai
6.2 case 语句
1)基本语法
case $ 变量名 in" 值 1" )如果变量的值等于值 1 ,则执行程序 1;;" 值 2" )如果变量的值等于值 2 ,则执行程序 2;;…省略其他分支 …* )如果变量的值都不是以上的值,则执行此程序;;esac
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch case.sh[ljz@ljz-virtual-machine shells]$ vim case.sh!/bin/bashcase $1 in"1")echo "banzhang";;"2")echo "cls";;*)echo "renyao";;esac[ljz@ljz-virtual-machine shells]$ chmod 777 case.sh[ljz@ljz-virtual-machine shells]$ ./case.sh 11
6.3 for 循环
1)基本语法 1
for (( 初始值 ; 循环控制条件 ; 变量变化 ))do程序done
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch for1.sh[ljz@ljz-virtual-machine shells]$ vim for1.sh#!/bin/bashsum=0for((i=0;i<=100;i++))dosum=$[$sum+$i]doneecho $sum[ljz@ljz-virtual-machine shells]$ chmod 777 for1.sh[ljz@ljz-virtual-machine shells]$ ./for1.sh5050
3)基本语法 2
for 变量 in 值 1 值 2 值 3…do程序done
4)案例实操
[ljz@ljz-virtual-machine shells]$ touch for2.sh[ljz@ljz-virtual-machine shells]$ vim for2.sh#!/bin/bash# 打印数字for i in cls mly wlsdoecho "ban zhang love $i"done[ljz@ljz-virtual-machine shells]$ chmod 777 for2.sh[ljz@ljz-virtual-machine shells]$ ./for2.shban zhang love clsban zhang love mlyban zhang love wls
[ljz@ljz-virtual-machine shells]$ touch for3.sh[ljz@ljz-virtual-machine shells]$ vim for3.sh#!/bin/bashecho '=============$*============='for i in $*doecho "ban zhang love $i"doneecho '=============$@============='for j in $@doecho "ban zhang love $j"done[ljz@ljz-virtual-machine shells]$ chmod 777 for3.sh[ljz@ljz-virtual-machine shells]$ ./for3.sh cls mly wls=============$*=============banzhang love clsbanzhang love mlybanzhang love wls=============$@=============banzhang love clsbanzhang love mlybanzhang love wls
[ljz@ljz-virtual-machine shells]$ vim for4.sh#!/bin/bashecho '=============$*============='for i in "$*"#$* 中的所有参数看成是一个整体,所以这个 for 循环只会循环一次doecho "ban zhang love $i"doneecho '=============$@============='for j in "$@"#$@ 中的每个参数都看成是独立的,所以 “$@” 中有几个参数,就会循环几次doecho "ban zhang love $j"done[ljz@ljz-virtual-machine shells]$ chmod 777 for4.sh[ljz@ljz-virtual-machine shells]$ ./for4.sh cls mly wls=============$*=============banzhang love cls mly wls=============$@=============banzhang love clsbanzhang love mlybanzhang love wls
6.4 while 循环
1)基本语法
while [ 条件判断式 ]do程序done
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch while.sh[ljz@ljz-virtual-machine shells]$ vim while.sh
#!/bin/bashsum=0i=1while [ $i -le 100 ]dosum=$[$sum+$i]i=$[$i+1]doneecho $sum[ljz@ljz-virtual-machine shells]$ chmod 777 while.sh[ljz@ljz-virtual-machine shells]$ ./while.sh5050
第 7 章 read 读取控制台输入
1)基本语法
2)案例实操
[ljz@ljz-virtual-machine shells]$ touch read.sh[ljz@ljz-virtual-machine shells]$ vim read.sh#!/bin/bashread -t 7 -p "Enter your name in 7 seconds :" NNecho $NN[ljz@ljz-virtual-machine shells]$ ./read.shEnter your name in 7 seconds : ljzljz
第 8 章 函数
8.1 系统函数
8.1.1 basename
1)基本语法
[ljz@ljz-virtual-machine shells]$ basename /home/ljz/banzhang.txtbanzhang.txt[ljz@ljz-virtual-machine shells]$ basename /home/ljz/banzhang.txt .txtbanzhang
8.1.2 dirname
2)案例实操
[ljz@ljz-virtual-machine ~]$ dirname /home/ljz/banzhang.txt/home/ljz
8.2 自定义函数
1)基本语法
[ljz@ljz-virtual-machine shells]$ touch fun.sh[ljz@ljz-virtual-machine shells]$ vim fun.sh#!/bin/bashfunction sum(){s=0s=$[$1+$2]echo "$s"}read -p "Please input the number1: " n1;read -p "Please input the number2: " n2;sum $n1 $n2;[ljz@ljz-virtual-machine shells]$ chmod 777 fun.sh[ljz@ljz-virtual-machine shells]$ ./fun.shPlease input the number1: 2Please input the number2: 57
第 9 章 正则表达式入门
9.1 常规匹配
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep ljz
就会匹配所有包含 ljz 的行。
9.2 常用特殊字符
1)特殊字符:^
^ 匹配一行的开头,例如:
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep ^a
会匹配出所有以 a 开头的行
2)特殊字符:$
$ 匹配一行的结束,例如
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep t$
会匹配出所有以 t 结尾的行
3)特殊字符:.
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep r..t
会匹配包含 rabt,rbbt,rxdt,root 等的所有行
4)特殊字符:*
* 不单独使用,他和上一个字符连用,表示匹配上一个字符 0 次或多次,例如
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep ro*t
会匹配 rt, rot, root, rooot, roooot 等所有行
思考:.* 匹配什么?
5)字符区间(中括号):[ ]
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep r[a,b,c]*t
会匹配 rt,rat, rbt, rabt, rbact,rabccbaaacbt 等等所有行
6)特殊字符:\
[ljz@ljz-virtual-machine shells]$ cat /etc/passwd | grep ‘ a\$b ’
就会匹配所有包含 a$b 的行。注意需要使用单引号将表达式引起来。
第 10 章 文本处理工具
10.1 cut
![](https://i-blog.csdnimg.cn/blog_migrate/7eadc0f96951902af86502bea044208a.png)
3)案例实操
(1)数据准备
[ljz@ljz-virtual-machine shells]$ touch cut.txt[ljz@ljz-virtual-machine shells]$ vim cut.txtdong shenguan zhenwo wolai laile le
[ljz@ljz-virtual-machine shells]$ cut -d " " -f 1 cut.txtdongguanwolaile
[ljz@ljz-virtual-machine shells]$ cut -d " " -f 2,3 cut.txtshenzhenwolaile
[ljz@ljz-virtual-machine shells]$ cat cut.txt |grep guan | cut -d " " -f 1guan
[ljz@ljz-virtual-machine shells]$ echo $PATH/usr/local/bin:/usr/bin: /usr/local/sbin:/usr/sbin:/home/ljz/.local/bin:/home/atguigu/bin[ljz@ljz-virtual-machine shells]$ echo $PATH | cut -d ":" -f 3-/usr/local/sbin:/usr/sbin:/home/ljz/.local/bin:/home/ljz/bin
[ljz@ljz-virtual-machine shells]$ ifconfig ens33 | grep netmask | cut -d " " -f 10192.168.111.101
10.2 awk
![](https://i-blog.csdnimg.cn/blog_migrate/9e3aaee50981ecb30c739b0a2a989152.png)
[ljz@ljz-virtual-machine shells]$ sudo cp /etc/passwd ./passwd 数据的含义用户名 : 密码 ( 加密过后的 ): 用户 id: 组 id: 注释 : 用户家目录 :shell 解析器
[ljz@ljz-virtual-machine shells]$ awk -F : '/^root/{print $7}' passwd/bin/bash
[ljz@ljz-virtual-machine shells]$ awk -F : '/^root/{print $1","$7}' passwdroot,/bin/bash
[ljz@ljz-virtual-machine shells]$ awk -F : 'BEGIN{print "user, shell"} {print $1","$7}END{print "dahaige,/bin/zuishuai"}' passwduser, shellroot,/bin/bashbin,/sbin/nologin。。。ljz,/bin/bashdahaige,/bin/zuishuai
注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。
[ljz@ljz-virtual-machine shells]$ awk -v i=1 -F : '{print $3+i}' passwd1234
4)awk 的内置变量
5)案例实操
(1)统计 passwd 文件名,每行的行号,每行的列数
[ljz@ljz-virtual-machine shells]$ awk -F : '{print "filename:" FILENAME ",linenum:"NR ",col:"NF}' passwdfilename:passwd,linenum:1,col:7filename:passwd,linenum:2,col:7filename:passwd,linenum:3,col:7...
[ljz@ljz-virtual-machine shells]$ ifconfig | awk '/^$/{print NR}'91826
[ljz@ljz-virtual-machine shells]$ ifconfig ens33 | awk '/netmask/ {print $2}'192.168.6.101
第 11 章 综合应用案例
11.1 归档文件
#!/bin/bash# 首先判断输入参数个数是否为 1if [ $# -ne 1 ]thenecho "参数个数错误!应该输入一个参数,作为归档目录名 "exitfi# 从参数中获取目录名称if [ -d $1 ]thenechoelseechoecho "目录不存在! "echoexitfiDIR_NAME=$(basename $1)DIR_PATH=$(cd $(dirname $1); pwd)# 获取当前日期DATE=$(date +%y%m%d)# 定义生成的归档文件名称FILE=archive_${DIR_NAME}_$DATE.tar.gzDEST=/root/archive/$FILE# 开始归档目录文件echo " 开始归档 ..."echotar -czf $DEST $DIR_PATH/$DIR_NAMEif [ $? -eq 0 ]thenechoecho "归档成功! "echo "归档文件为: $DEST"echoelseecho "归档出现问题! "echofiexit
11.2 发送消息
#!/bin/bashlogin_user=$(who | grep -i -m 1 $1 | awk '{print $1}')if [ -z $login_user ]thenecho "$1 不在线! "echo "脚本退出 .."exitfiis_allowed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')if [ $is_allowed != "+" ]thenecho "$1 没有开启消息功能 "echo "脚本退出 .."exitfiif [ -z $2 ]thenecho "没有消息发出 "echo "脚本退出 .."exitfiwhole_msg=$(echo $* | cut -d " " -f 2- )user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')echo $whole_msg | write $login_user $user_terminalif [ $? != 0 ]thenecho "发送失败! "elseecho "发送成功! "fiexit