什么是Shell

工作在Linux内核与用户之间的解释程序
-相当于操作系统的“外壳”
-向Linux内核传达用户指令的“翻译官”
-通常指 BASH (/bin/bash )
•Windows下的Shell解释器
-C:\Windows\System32\cmd.exe
image.png

登录Shell环境

作为用户登录后的第一个程序
-即最常见的“Linux命令行”环境
-以交互方式运行,用户每输入一个命令行,立即解释并执行
Red Hat Enterprise Linux Server release 6.5 (Santiago)
Kernel 2.6.32-431.el6.x86_64 on an x86_64
svr5 login: root
Password:
Last login: SunJan 18 18:18:18 on tty2
[root@svr5~]#echo $SHELL(查看当前用户使用的那个登录Shell)
/bin/bash

手动选择Shell环境

直接执行指定的解释器程序
-常见的Shell:bash、zsh、tcsh
-相当于新建一个子环境(父–>子进程)
[root@svr5~]# tcsh
[root@svr5~]# bash
[root@svr5~]# pstree | grep login

l- login–bash–tcsh—bash—grep

交互式 vs 非交互式

•交互式
-人工干预、智能化程度高
-逐条解释执行、效率低
•非交互式
-需要提前设计、智能化难度大
-批量执行、效率高
一方面在后台静悄悄地运行

什么是脚本?

提前写好可执行代码,用来完成特定任务的文件
-顺序、批处理
-解释型程序
image.png

脚本的创建过程

如何写出自己的第一个Shell脚本?

  • 1.理清任务 ——自然语言:步骤拆分、顺序化整理
  • 2.编写可执行语句 ——脚本语言:各步骤如何实现
  • 3.完善脚本 界面友好/结构规范/代码的优化

1.理清任务

•案例需求
-新建一个名为AB的本地用户
-此用户能正常登录,其密码为 1234567
[root@svr5~]# vim /root/du.sh
第一步:新建用户账号
第二步:将用户的登录密码设为1234567

2.编写可执行语句

•第一、二、………步依次如何实现?
-使用 useradd、passwd 命令完成相应的任务步骤
-自然语言–>可执行的命令行
[root@svr5~]# vim /root/du.sh
第一步:新建用户账号
useradd AB
第二步:将用户的登录密码设为1234567
passwd AB

3.完善脚本

•脚本优化目标
-界面友好、易读懂、易使用
-符合规范、方便协作/移植及代码重用
-代码简洁、执行效率高
[root@svr5~]# vim /root/du.sh
#!/bin/bash
#第一步:新建用户账号 //添加代码注释
useradd AB
#第二步:将用户的登录密码设为1234567
passwd AB

如何运行Shell脚本?

•方法1:作为指定Shell解释程序的参数

  • sh 代码文件路径 === bash 代码文件路径
    -.代码文件路径 === source 代码文件路径
    [root@svr5 ~]# sh /root/du.sh //指定由/bin/sh程序来解析代码
    更改用户AB的密码。
    新的密码:
    重新输入新的密码:
    passwd:所有的身份验证令牌已经成功更新。

如何运行Shell脚本?

方法2:作为可独立运行的脚本程序
-为Shell代码文件添加 x 权限
-指定脚本路径即可运行
[root@svr5~]# chmod +x /root/du.sh //添加可执行权限
[root@svr5~]#/root/du.sh //运行指定的脚本程序
useradd: user 'AB’already exists//用户已经创建过了
更改用户AB的密码。
新的密码:
重新输入新的密码:
passwd:所有的身份验证令牌已经成功更新

调试Shell脚本

直接观察执行过程
-执行中的命令输出、报错信息
-与用户的交互
•开启调试模式
-sh -X 脚本文件
[root@svr5~]# sh -X /root/du.sh //以调试模式执行脚本

  • useradd AB //语句1
    useradd: user ‘AB’ already exists //语句1 输出
  • passwd AB //语句2
    更改用户AB 的密码。 //语句2 输出
    新的密码:

插入echo断点

  • echo’提示信息’.…
    -echo’Hello World’
    [root@svr5~]# vim /root/first.sh
    #!/bin/bash
    #第一步:新建用户账号
    echo’正在创建用户… //给出友好提示
    useradd zengye
    #第二步:将用户的登录密码设为 1234567
    passwd AB

免交互处理

•需要输入交互的可执行操作

  • passwd改密码
  • ssh远程登录
    -vim文本编辑器
    -图形化的安装/配置过程

passwd改密码的免交互

选项–stdin
-从标准输入读取密码字串
-可以从键盘、也可以由另一个命令给出
[root@svr5~]# passwd --stdin AB //从键盘读入
更改用户AB的密码。
1234567
passwd:所有的身份验证令牌已经成功更新。
[root@svr5 ~]#
[root@svr5~]#echo 1234567| passwd --stdin AB //由echo命令给出
更改用户AB 的密码。
passwd:所有的身份验证令牌已经成功更新。

忽略无关输出

在命令后面&> /dev/null(没有输出,直接在后台都把命令运行完成)
•黑洞设备/dev/null
-相当于只能写入、不能读出的单向文件
-存放到其中的数据都会丢失
-用法:可执行语句&>/dev/null
[root@svr5~]# echo 1234567| passwd --stdin AB
更改用户 zengye 的密码。
passwd:所有的身份验证令牌已经成功更新。
[root@svr5 ~]# echo 1234567| passwd–stdin AB &>/dev/null

记录错误输出

•根据需要,可以将出错信息保存到指定文件
-针对后台脚本的有效排错手段
-适用于不便交互但又需要查看报错的情况
-用法:可执行语句 2>/路径/文件,
[root@svr5~]# useradd AB //报错情况
useradd: user ‘AB’ already exists
[root@svr5~]# useradd AB 2> /路径/文件 //保存报错信息
[root@svr5~# cat /路径/文件 //查看记录的结果
useradd: user ‘AB’ already exists

对第一个Shell脚本的完善

•免交互处理、友好输出
-批量应用时方便在后台执行
[root@svr5~]# vim /root/du.sh
#!/bin/bash
#第一步:新建用户账号
echo’1.创建名为AB 的用户账号!
useradd AB 2> /tmp/du
#第二步:将用户的登录密码设为 1234567
echo’2.为用户 AB 设置好密码’
echo “1234567” | passwd --stdin AB &> /dev/null

顺序分隔

•使用分号
-命令1 ;命令2;命令3 …
一依次执行,只有先后、没有逻辑关系
[root@svr5~]# X=123; Y=456 //依次赋值变量X、Y
[root@svr5 ~]# mkdir /123 ;cd /123 //新建目录,再进入此目录
[root@svr5 123]#
•典型应用
-开启某个服务,并将此服务设为开机自启动
[root@svr5 ~]# systemctl restart httpd.service;systemctl enable httpd.service

逻辑“与”分隔

•使用&&
-命令1 &&命令2&8命令3…
-逻辑关系为“而且”(and),期望所有的命令都能够执行成功
-—旦出现失败,后续命令不再执行
[root@svr5~]# echo “萝卜”&& echo"白莱"
萝下
白菜
•典型应用
-源代码编译安装软件包时,编译、安装过程
[root@svr5~]# make && make install

逻辑“或”分隔

•使用|
-命令1||命令2 ||命令3…
-逻辑关系为“或者”(or),任何一条命令成功都符合期望
-只在前面的命令失败时,后续命令才会执行
[root@svr5~]# echo “萝卜”|| echo “白菜”
萝下
•典型应用
-针对前置命令失败的情况,设置补充任务
[root@svr5~]# id mickey ll useradd mickey //若无此用户,则创建此用户
id: mickey:无此用户

简单的判断操作

•组合逻辑分隔
-命令1 && 命令2 || 命令3
-当命令1执行成功时,会继续执行命令2(忽略命令3)
-当命令1执行失败时,会继续执行命令3(放弃命令2)
[root@svr5~]# id yezeng &>/dev/null && echo YES II echo No
NO //判断用户是否存在
[root@svr5~]# grep -q -e ‘vmx/svm’/proc/cpuinfo && echo YES Il echo No
Yes //判断CPU是否支持虚拟化

管道的作用

•将命令的屏幕输出交给另一端的命令处理
-命令1 |命令2 |命令3…
-后续命令要能正确处理传来的文本,否则无意义

应用示例

•分屏浏览所有的网络设备信息
一命令1:使用ifconfig列出所有的连接信息
-命令2:将列出的信息交给less命令进行分页查看
[root@svr5~]# ifconfig -a l less
etho Link encap:Ethernet HWaddr00:0C:29:65:21:3C
inet addr:192.168.4.5 Bcast:192.168.4.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe65:213c/64Scope:Link

应用示例

•计算配置目录/etc 下包括多少个普通文件
-命令1:使用find在/etc 目录下递归查找,列出所有普通文件
一命令2:将查找结果交给wc统计行数
[root@svr5~]# find /etc -typef Iwc -1
1691

应用示例

•统计正处于监听状态的TCP端口数
-命令1:使用netstat命令列出所有的TCP连接信息
一命令2:将查找结果交给grep过滤,计算状态为LISTEN的连接数
[root@svr5~]# netstat -anpt I grep -c"UISTEN"
8