NSD SHELL DAY01
1 案例1:Shell基础应用
什么是shell?
Shell是在Linux内核与用户之间的解释器程序,通常指的是bash,负责向内核翻译及传达用户/程序指令,如图-1所示。
shell的使用方式:
1.交互执行指令:人工干预,执行效率底。
2.非交互执行指令:安静地在后台执行,执行效率高,方便写脚本。
若需要临时使用另一种Shell环境,可以直接执行对应的Shell解释器程序,比如只要执行sh可以切换到sh命令行环境。
- [root@svr7 ~]# cat /etc/shells #查看所有解释器
- [root@svr7 ~]# sh #切换成sh解释器
- sh-4.2# ls #利用sh解释器输入命令
- sh-4.2#exit #退出sh解释器
- [root@svr7 ~]#yum -y install ksh #若没有ksh解释器则安装
- [root@svr7 ~]#ksh #进入新解释器
若希望修改用户的登录Shell,管理员可以直接通过usermod(或useradd)命令设置。比如,以下操作可将用户zhangsan的登录Shell改为/bin/ksh:
- [root@svr5 ~]# usermod -s /bin/ksh zhangsan #执行修改操作
- [root@svr5 ~]# grep 'zhangsan' /etc/passwd
- zhangsan:x:516:516::/home/zhangsan:/bin/ksh #修改后
快捷键与Tab键补齐
bash可实现:Tab键、快捷键、历史命令、支持别名、管道、重定向
shell脚本:提前写好可执行的语句,可以完成特定任务的文件按顺序、批量化执行
2 案例2:简单Shell脚本的设计
2.1 问题
本案例要求编写三个脚本程序,分别实现以下目标:
- 在屏幕上输出一段文字“Hello World”
- 能够为本机快速配好Yum仓库
- 能够为本机快速装配好vsftpd服务
2.2 方案
一个规范的Shell脚本构成包括:
- 声明(需要的解释器)
- 注释信息(作者信息、步骤、思路、用途、变量含义等)
- 可执行语句(操作代码)
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:编写第一个Shell脚本,输出“Hello World”
1)根据手动任务操作编写脚本文件
- [root@svr5 ~]# vim /opt/first.sh
- #!/bin/bash
- echo 'Hello World'
- [root@svr5 ~]# chmod +x /opt/first.sh #添加可执行权限
2)执行脚本,测试效果
- [root@svr5 ~]# /opt/first.sh
- Hello World
3)Shell脚本的执行方式:
方法一,作为“命令字”:指定脚本文件的路径,前提是有 x 权限
- [root@svr5 ~]# ./first.sh #指定相对路径
- [root@svr5 ~]# /opt/first.sh #指定绝对路径
方法二,作为“参数”:使用bash、sh、source、. 来加载脚本文件
- [root@svr5 ~]# bash first.sh #开启子进程
- [root@svr5 ~]# sh first.sh #开启子进程
- [root@svr5 ~]# source first.sh #不开启子进程
- [root@svr5 ~]# . first.sh #不开启子进程
4)再修改脚本进行测试:
- [root@svr5 ~]# vim /opt/first.sh
- #!/bin/bash
- echo 'Hello World'
- exit
- [root@svr5 ~]# vim /opt/first.sh
- #!/bin/bash
- echo 'Hello World'
- mkdir /opt/abc
- cd /opt/abc
步骤二:编写为本机快速配Yum仓库的Shell脚本
1)根据参考文件的内容,编写脚本内容如下:
- cp /etc/yum.repos.d/myyum.repo /opt #可以先备份原有yum配置文件
- [root@svr5 ~]# vim /opt/myyum.sh
- #!/bin/bash
- rm -rf /etc/yum.repos.d/*.repo
- echo '[abc]
- name=abc
- baseurl=file:///misc/cd
- gpgcheck=0
- ' > /etc/yum.repos.d/abc.repo
- [root@svr5 ~]# chmod +x /opt/myyum.sh #添加可执行权限
2)执行脚本,测试效果
执行配置Yum仓库的脚本:
- [root@svr5 ~]# bash /opt/myyum.sh
检查配置结果:
- [root@svr5 ~]# ls /etc/yum.repos.d/* #仓库配置已建立
步骤三:编写快速装配vsftpd服务的Shell脚本
编写参考
> 重定向标准输出
2> 重定向错误输出
&> 重定向所有输出
脚本文件如下:
- [root@svr5 ~]# vim /opt/ftpon.sh
- #!/bin/bash
- yum -y install vsftpd &> /dev/null #将不需要的信息扔黑洞
- systemctl start vsftpd
- systemctl enable vsftpd
- cp /etc/hosts /var/ftp/pub
- #拷贝一个文件,放到FTP共享目录下
- [root@svr5 ~]# chmod +x /opt/ftpon.sh #添加可执行权限
3)执行脚本,测试效果
执行快速装配vsftpd服务的脚本:
- [root@svr5 ~]# /opt/ftpon.sh
确认脚本执行结果:
- [root@svr5 ~]# rpm -q vsftpd
- [root@svr5 ~]# systemctl status vsftpd
练习:
3 案例3:使用Shell变量
3.1 问题
本案例要求熟悉Shell变量的使用,主要练习或验证下列内容:
- 定义/赋值/查看变量
- 环境/预定义/位置变量的应用
3.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:变量的定义/赋值/查看
1)新建/赋值变量
新建变量test,赋值“hello world”,通过set命令可以检查变量设置:
- [root@svr5 ~]# a=10
2)查看变量
通过echo $变量名 可输出变量值:
- [root@svr5 ~]# echo $a
- 10
查看变量时,若变量名称与后面要输出的字符串连在一起,则应该以{}将变量名括起来以便区分:
- [root@svr5 ~]# echo $aRMB #无法识别变量名test
- [root@svr5 ~]# echo ${a}RMB #区分后可以识别
- 10RMB
3)撤销自定义变量
若要撤销已有的变量,可将变量赋值为空或使用unset命令:
- [root@svr5 ~]# unset a #撤销变量test
- [root@svr5 ~]# echo $a #查看时已无结果
步骤二:使用环境变量
1)使用环境变量
当前用户的环境变量USER记录了用户名、HOME记录了家目录、SHELL记录了登录解释器、HOSTNAME记录主机名、UID是用户的id号:
- [root@svr5 ~]# echo $USER $HOME $SHELL $UID
- root /root /bin/bash 0
- [root@svr5 ~]# echo $HOSTNAME
- svr5
环境变量PS1表示Shell环境的一级提示符,即命令行提示符(\u 用户名、\h 主机名、\W 工作目录、\$ 权限标识):
- [root@svr5 src]# echo $PS1 #查看默认的一级提示
- [\u@\h \W]\$
- [root@svr5 src]#PS1='hehe#' #修改一级提示
- hehe# #更改结果
- hehe# PS1='[\u@\h \W]\$ ' #恢复原有设置
- [root@svr5 src]#
环境变量PS2表示二级提示符,出现在强制换行场合:
- [root@svr5 ~]# echo $PS2 #查看默认的二级提示
- >
- [root@svr5 src]# cd \ #强制换行,观察提示符效果
- > /root/
- [root@svr5 ~]# PS2='=> ' #手动修改二级提示
- [root@svr5 ~]# cd \ #再次验证提示符效果
- => ~
- [root@svr5 ~]# PS2='> ' #恢复原有设置
v
可以把变量放入/etc/profile,对所有用户有效;放入~/.bash_profile,仅对指定的用户有效
使用env可查看所有环境变量,使用set可查看所有变量
步骤三:使用位置变量与预定义变量
1)创建一个测试脚本,用来展示。
- [root@svr5 ~]# vim location.sh
- #!/bin/bash
- echo $0 #脚本的名称
- echo $1 #第一个参数
- echo $2 #第二个参数
- echo $* #所有参数
- echo $# #所有参数的个数
- echo $$ #当前进程的进程号
- echo $? #上一个程序的返回状态码
- [root@svr5 ~]# chmod +x location.sh #添加可执行权限
2)执行脚本location.sh
- [root@svr5 ~]# ./location.sh a b c
步骤四:创建账户与修改密码的脚本
首先编写一个创建账户tom,密码123456的脚本,然后通过下列方式改进
1)编写脚本。
- [root@svr5 ~]# vim /opt/user.sh
- #!/bin/bash
- useradd $1
- echo "$2" |passwd --stdin $1
执行脚本测试:
- [root@svr5 ~]# ./user.sh jerry 123456
- 更改用户 jerry 的密码 。
- passwd: 所有的身份验证令牌已经成功更新。
4 案例4:变量的扩展应用
4.1 问题
本案例要求进一步熟悉Shell变量的赋值控制,主要练习或验证下列内容:
- 三种引号对赋值的影响
- 使用read命令从键盘读取变量值
- 使用export发布全局变量
4.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:三种引号对变量赋值的影响
1)双引号的应用
使用双引号可以界定一个完整字符串。
- [root@svr5 ~]# xx=a b c
- -bash: b: command not found #未界定时赋值失败
- [root@svr5 ~]# xx="a b c" #界定后成功
- [root@svr5 ~]# touch aa bb #创建了两个文件
- [root@svr5 ~]# touch "aa bb" #创建了一个文件
- [root@svr5 ~]# ls #查看结果
2)单引号的应用
界定一个完整的字符串,并且可以实现屏蔽特殊符号的功能。
- [root@svr5 ~]# test=11
- [root@svr5 ~]# echo "$test"
- [root@svr5 ~]# echo '$test'
3)反撇号或$()的应用
使用反撇号或$()时,可以将命令执行的标准输出作为字符串存储,因此称为命令替换。
- a=date #仅仅将四个字母赋值给a
- a=`date` #将date执行结果赋值给a
- a=$(date) #效果同上
- [root@svr5 ~]# tar -czf log-`date +%Y%m%d`.tar.gz /var/log
步骤二:使用read命令从键盘读取变量值
1)read基本用法
执行后从会等待并接受用户输入(无任何提示的情况),并赋值给变量str:
- [root@svr5 ~]# read str
- What's happen ? #随便输入一些文字,按Enter键提交
- [root@svr5 ~]# echo $str #查看赋值结果
- What's happen ?
为了不至于使用户不知所措、莫名其妙,推荐的做法是结合-p选项给出友好提示:
- [root@svr5 ~]# read -p "请输入一个整数:" i
- 请输入一个整数:240
- [root@svr5 ~]# echo $i
- 240
结合之前的脚本
- #!/bin/bash
- read -p "请输入用户名" u #-p是可以定义提示信息,u相当于自
- 定义变量名称,可以存储用户看到提示信息后输入的字符
- useradd $u
- read -p "请输入密码" n
- echo "$n" | passwd --stdin $u
2)stty终端显示控制
将回显功能关闭(stty -echo),(屏蔽回显)
将回显功能恢复(stty echo)。(恢复回显)
之前脚本再次改良:
- #!/bin/bash
- read -p "请输入用户名" u
- useradd $u
- stty -echo
- read -p "请输入密码" n
- stty echo
- echo "$n" | passwd --stdin $u
步骤三:使用export发布全局变量
默认情况下,自定义的变量为局部变量,只在当前Shell环境中有效,而在子Shell环境中无法直接使用。
- [root@svr5 ~]# yy="abc"
- [root@svr5 ~]# echo $yy
- [root@svr5 ~]# bash #开启bash子进程
- [root@svr5 ~]# echo $yy #查看SCHOOL变量值无结果
- [root@svr5 ~]# exit #返回原有Shell环境
- exit
- [root@svr5 ~]# echo $yy
若希望定义的变量能被子进程使用:
- [root@svr5 ~]# export yy #发布已定义的变量
验证刚刚发布的全局变量:
- [root@svr5 ~]# bash #进入bash子Shell环境
- [root@svr5 ~]# echo $yy #查看全局变量的值 .. ..
5 案例5:Shell中的数值运算
5.1 问题
本案例要求熟悉Linux Shell环境的特点,主要练习以下操作:
- 使用expr、$[ ]、let等整数运算工具:进行四则运算及求模结果
- 使用bc实现小数运算操作
5.2 步骤
实现此案例需要按照如下步骤进行。
步骤一:整数运算工具
1)使用expr命令
乘法操作应采用 \* 转义,避免被作为Shell通配符;参与运算的整数值与运算操作符之间需要以空格分开,引用变量时必须加$符号。
首先随便定义变量比如X=1234,然后分别计算与78的加减乘除和求模运算结果:
- [root@svr5 ~]# X=1234 #定义变量X
- [root@svr5 ~]# expr $X + 78 #加法
- 1312
- [root@svr5 ~]# expr $X - 78 #减法
- 1156
- [root@svr5 ~]# expr $X \* 78 #乘法,操作符应添加\转义
- 96252
- [root@svr5 ~]# expr $X / 78 #除法,仅保留整除结果
- 15
- [root@svr5 ~]# expr $X % 78 #求模
- 64
2)使用$[]或$(())表达式
乘法操作*无需转义,运算符两侧可以无空格;引用变量可省略 $ 符号;计算结果替换表达式本身,可结合echo命令输出。
同样对于变量X=1234,分别计算与78的加减乘除和求模运算结果:
- [root@svr5 ~]# X=1234
- [root@svr5 ~]# echo $[X+78]
- 1312
- [root@svr5 ~]# echo $[X-78]
- 1156
- [root@svr5 ~]# echo $[X*78]
- 96252
- [root@svr5 ~]# echo $[X/78]
- 15
- [root@svr5 ~]# echo $[X%78]
- 64
3)使用let命令
expr或$[]、$(())方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值。
- 常规写法 主流写法
- let a=a+1 let a++ #变量a加1
- let a=a-1 let a-- #变量a减1
- let a=a+10 let a+=10 #变量a加10
- let a=a-10 let a-=10 #变量a减10
- let a=a*2 let a*=2 #变量a乘以2
- let a=a/2 let a/=2 #变量a除以2
- let a=a%3 let a%=3 #变量a除以3取余数
步骤二:小数运算工具
1)bc交互式运算
先执行bc命令进入交互环境,然后再输入需要计算的表达式。
- [root@svr5 ~]# bc
2)bc非交互式运算
将需要运算的表达式通过管道操作交给bc运算。注意,小数位的长度可采用scale=N限制。
- [root@svr5 ~]#echo "1.1+1" | bc
- [root@svr5 ~]#echo "10/3" | bc
- [root@svr5 ~]#echo "scale=2;10/3" | bc #scale可以定义结果是小数点后多少位