概述:
1.什么是shell?
shell是linux的一个外壳,它包在linux内核的外面,为用户和内核之间的交互提供了一个接口。
当用户下达指令给该操作系统的时候,实际上是把指令告诉shell,经过shell解释,处理后让内核做出相应的动作。
系统的回应和输出的信息也由shell处理,然后显示在用户的屏幕上
2.什么是shell脚本?
简单的来说,当命令或者程序不在命令行执行,而是通过一个程序文件来执行,这个程序就称为为shell脚本
也就是在shell脚本里内置了多条命令,语句,循环控制,然后将这些命令一次性执行完毕,这种通过文件执行命令的方式称为非交互式
3.为什么使用shell脚本?
(1)适合处理操作系统底层的业务,有众多系统命令为其做支撑(还有文本处理三兄弟:grep,sed,awk)
(2)适合处理纯文本文件,linux中许多服务配置文件,启动脚本,都是纯文本文件(如:httpd,nfs,mysql,nginx,lvs)
(3)linux系统脚本用shell开发更简单,简言之,shell脚本操作更加方便,快捷,高效。
4.shell脚本与编程语言的区别?
shell脚本是能运行的文本,它包含命令和运行逻辑关系 。与C语言、C++、C#等编程语言不同。
shell脚本不需要编译、连接及生成可执行文件,直接由相应的解释器(最常用的解释器为bash) 解释执行即可。
它的优点是可批量,多次执行(使用)。简言之,shell脚本是解释性语言,而c语言则是编译性语言。
面试题1:如何查看系统默认shell?
##方法1:
root@localhost ~]# echo $SHELL
/bin/bash
##方法2:
[root@localhost ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
1.编写一个简单的shell脚本
第一行:
#!/bin/bash ##指定解释器:由哪个程序来执行脚本内容;#!表示幻数
注意:#!/bin/bash必须写在第一行,否则会被认为是注释
编写脚本:输出hello word!
[root@localhost ~]# cd /mnt
##编写脚本;一般脚本均以.sh结尾
[root@localhost mnt]# vim hello.sh
#####################
#!/bin/bash ##幻数
echo hello word!
##方式1:
[root@localhost mnt]# sh hello.sh
hello word!
##方式2:
[root@localhost mnt]# ll hello.sh
-rw-r--r--. 1 root root 29 Dec 22 20:34 hello.sh
[root@localhost mnt]# /mnt/hello.sh
-bash: /mnt/hello.sh: Permission denied
##1.给脚本一个可执行权限
[root@localhost mnt]# chmod +x /mnt/hello.sh
##2.绝对路径的方式调用
[root@localhost mnt]# /mnt/hello.sh
hello word!
注意: #!/bin/bash必须写在第一行,否则会被认为是注释
[root@localhost mnt]# vim hello.sh
#####################
#!/bin/bash
echo hello word!
#!/bin/bash ##只有写在第一行才生效,其他位置均视为注释
echo hello linux!
[root@localhost mnt]# sh hello.sh
hello word!
hello linux!
示例1:清空/var/log/messages日志
方法1:
#编写脚本
[root@localhost mnt]# vim log_clean.sh
#####################
#!/bin/bash
cd /var/log
> messages
echo "Logs cleaned up...."
##执行脚本
[root@localhost mnt]# sh log_clean.sh
Logs cleaned up....
##测试
[root@localhost mnt]# cat /var/log/messages
##先重启服务产生日志,便于之后的测试
[root@localhost mnt]# rpm -q httpd
httpd-2.4.6-40.el7.x86_64
[root@localhost mnt]# systemctl restart httpd
[root@localhost mnt]# cat /var/log/messages
##编写脚本
[root@localhost mnt]# vim log_clean.sh
#####################
#!/bin/bash
cat /dev/null > /var/log/messages
echo "Logs cleaned up...."
##执行脚本
[root@localhost mnt]# sh log_clean.sh
Logs cleaned up....
##测试
[root@localhost mnt]# cat /var/log/messages
注意:若用echo方式清空文件会给文件添加一个空行,故而不提倡用它来清空日志
[root@localhost mnt]# vim linux
[root@localhost mnt]# cat linux
westos
linux
root
[root@localhost mnt]# echo > westos
[root@localhost mnt]# cat westos
这个脚本的缺陷?
(1)没有用户判断,任何用户都可以执行这个脚本
(2)没有流程控制,只是把简单的命令进行顺序操作,没有成功与否的判断
[root@localhost mnt]# vim log_clean.sh
#####################
#!/bin/bash
LOG_DIR=/var/log ##定义存放日志的变量
ROOT_UID=0 ##定义存放超级用户uid的变量(root用户的uid为0)
if [ "$UID" -ne "$ROOT_UID" ];then ##判断用户是否为超级用户;设定仅超级用户才能清空日志
echo "EROOR: Permission denied!"
exit 1
fi
cd $LOG_DIR || { ##判断能否成功进入日志目录
echo "Cannot access to directory!"
exit 1
}
cat /dev/null > messages && { ##判断能否成功删除清空日志
echo "Logs cleaned up...."
exit 0
}|| {
echo "Logs cleaned fialed...."
exit 1
}
##执行脚本
[root@localhost mnt]# sh log_clean.sh
Logs cleaned up....
##切换到普通用户
[root@localhost mnt]# su - student
Last login: Sat Dec 22 21:36:37 CST 2018 on pts/0
[student@localhost ~]$ sh log_clean.sh
sh: log_clean.sh: No such file or directory
[student@localhost ~]$ sh /mnt/log_clean.sh
EROOR: Permission denied!
练习1:写一个安装,启动并开机自启动httpd的脚本
前提:yum源已经配置好
[root@localhost mnt]# vim apache.sh
#####################
#!/bin/bash
yum install httpd -y > /dev/null ##安装apache
systemctl start httpd ##开启apache
systemctl enable httpd &> /dev/null ##设定开机自启
echo "httpd has installed...."
[root@localhost mnt]# sh apache.sh
httpd has installed....
2.脚本的执行过程
(1)先加载系统环境变量,查看系统环境变量:env
(2)一条一条命令执行,遇到子脚本,先执行子脚本,然后返回父脚本继续执行
##查看系统的环境变量
[root@localhost ~]# env
(1) sh方式
sh script.sh 或者 bash script.sh ##当脚本没有执行权限时
(2) 绝对路径
path/script.sh 或者 ./script.sh ##绝对路径,或当前目录下
(3) source方式
source script.sh 或者 . script.sh ##需要传递变量或函数时使用;这种方式会使用source或.号来读如指定shell文件,并会把其他shell中的变量值或函数返回给父shell继续使用
实验:
##编写脚本
[root@localhost mnt]# vim style.sh
#####################
#!/bin/bash
echo "hello linux"
##执行脚本
方式1:
[root@localhost mnt]# sh style.sh
hello linux
[root@localhost mnt]# bash style.sh
hello linux
方式2:
[root@localhost mnt]# chmod +x /mnt/style.sh
[root@localhost mnt]# /mnt/style.sh
hello linux
[root@localhost mnt]# ./style.sh
hello linux
方式3:
[root@localhost mnt]# source style.sh
hello linux
[root@localhost mnt]# . style.sh
hello linux
三种方式的区别:
[root@localhost mnt]# whoami
root
[root@localhost mnt]# vim difference.sh
#####################
#!/bin/bash
username=`whoami`
[root@localhost mnt]# sh difference.sh
[root@localhost mnt]# echo $username
[root@localhost mnt]# bash difference.sh
[root@localhost mnt]# echo $username
[root@localhost mnt]# chmod +x difference.sh
[root@localhost mnt]# /mnt/difference.sh
[root@localhost mnt]# echo $username
[root@localhost mnt]# ./difference.sh
[root@localhost mnt]# echo $username
##只有source方式才能输出传递变量的值
[root@localhost mnt]# source difference.sh
[root@localhost mnt]# echo $username
root
面试题2:echo $username命令的输出结果是什么?
[root@foundation0 ~]# cat test.sh
username=`whoami`
[root@foundation0 ~]# sh test.sh
[root@foundation0 ~]# echo $username
问题:echo $username命令的输出结果是什么? ( c )
a)当前用户
b)root
c)空(无输出)
4.shell脚本开发规范
(1)注释:可以命令后,也可以自成一行
(2)脚本信息:
#!/bin/bash ##指定解释器;#!表示幻数
#Date:2018-12-14 ##日期
#Author:westos-wsp ##作者
#Mail:[email protected] ##邮箱
#Desc:This script is for... ##描述
#Version:1.0 ##版本
(3)脚本名称: 最好以.sh结尾
如何自动生成脚本的说明?
[root@localhost mnt]# vim /etc/vimrc
#####################
"map ms:call WESTOS()'s
autocmd BufNewFile *.sh exec ":call WESTOS()"
func WESTOS()
call append(0,"#########################################")
call append(1,"# Author: lee".(" #"))
call append(2,"# Viersion: ".(" #"))
call append(3,"# Mail: ".(" #"))
call append(4,"# Date: ".strftime("%Y-%m-%d").(" #"))
call append(5,"# Description: ".(" #"))
call append(6,"# ".(" #"))
call append(7,"#########################################")
call append(8," ")
call append(9,"#!/bin/bash")
endfunc
[root@localhost mnt]# vim file.sh