什么是 shell
- shell 也是操作系统中的一个软件,它包在 linux 内核的外面,为用户和内核之间的交互提供了一个接口。系统中的命令用 shell 去解释shell接收系统回应的输出并显示其到屏幕中。
- bash = GNU Bourne-Again Shell
交互式shell和非交互式shell
- 交互式模式就是shell等待你的输入,并且执行你提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当你签退后,shell也终止了。
- shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。
shell的类型
在UNIX中主要有:
- Bourne shell (包括 sh,ksh,and bash)
- Bourne shell (sh)
- Korn shell ( ksh)
- Bourne Again shell ( bash)
- POSIX shell ( sh)
- C shell (包括 csh and tcsh)
- C shell ( csh)
- TENEX/TOPS C shell ( tcsh)
具体信息点击百科 shell
什么是shell脚本
Shell Script ,Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处理更强大,比用其他编程程序编辑的程序效率更高,它使用了Linux/Unix下的命令。
- 脚本是一种解释型语言
- 用 shell 脚本保存执行动作
- 用脚本判定命令的执行条件
- 用脚本来实现动作的批量执行
shell与shell脚本的区别
shell和shell脚本有什么区别?
确切一点说,Shell就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。它为用户提供了一个向Linux发送请求以便运行程序的接口系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。
如何创建新 shell 脚本
vim script.sh | 用 vim 编写脚本 |
---|---|
#!/bin/bash | 脚本使用的解释器,通常用幻数 “#!” 指定 |
#AUTHOR | 脚本作者 |
#DATE | 脚本创作时间 |
脚本作者联系方式 | |
#VERSION | 脚本的版本 |
给shell添加表头的设置
在vim编辑器的配置文件/etc/vimrc中的最后一行添加下面内容,可以在新建一个.sh文件时自动添加你所设置的表头信息:
- 进入.sh文件后按快捷键添加
map <F9> ms:call WESTOS()<cr>'s
function WESTOS()
call append(0,"####################################")
call append(1,"# Author: #")
call append(2,"# Create_Time: ".strftime("%Y-%m-%d")." #")
call append(3,"# Version: #")
call append(4,"# Mail: #")
call append(5,"# Description: #")
call append(6,"# #")
call append(7,"# #")
call append(8,"####################################")
call append(9,"")
call append(10,"#!/bin/bash")
endfunction
funtion ()定义一个函数
call调用
0 第一行
endfunction
map 快捷键
cr 关闭属性
两段 .
三段 . .
- 自动添加,即新打开一个.sh文件或.script文件,自动加入下面内容的设置:
autocmd BufNewFile *.sh,*.script exec ":call WESTOS()"
function WESTOS()
call append(0,"####################################")
call append(1,"# Author: #")
call append(2,"# Create_Time: ".strftime("%Y-%m-%d")." #")
call append(3,"# Version: #")
call append(4,"# Mail: #")
call append(5,"# Description: #")
call append(6,"# #")
call append(7,"# #")
call append(8,"####################################")
call append(9,"")
call append(10,"#!/bin/bash")
endfunction
vim 里一个tab键默认是8个空格,在/etc/vimrc中可以修改
buf 新属性
exec 执行,打开一个新的.sh,会自动执行
.script,第二次打开会识别
设置完成的效果如下:
脚本示例
vim hello.sh
#!/bin/bash
#AUTHOR:zhangyiwen
#VERSION:1.0
#MAIL:zhangyiwen@westos.org
#DATE:2019-06-10
echo "hello world!"
执行结果:
脚本的调试
Shell本身提供一些调试方法选项:
参数 | 说明 | 应用 |
---|---|---|
-n | 只读取shell脚本,但不实际执行 | 测试shell脚本是否存在语法错误 |
-x | 进入跟踪方式,显示所执行的每一条命令 | 使shell在执行脚本的过程中把它实际执行的每一个命令行显示出来 |
-c | 从strings中读取命令 | 临时测试一小段脚本的执行结果 |
-v | 一边执行脚本,一边将执行过的脚本命令打印到标准输出。 |
sh -x scritps.sh
vim scripts.sh 适用于所有 shell 脚本
#!/bin/bash -x shell 脚本必须有x权限
举例:
vim hiya.sh
ech0 hiya ##ech0为错误的命令
shell 脚本的执行
- 5种方法:
sh script.sh
source script.sh
. script.sh
chmod +x script.sh
./script.sh
举例:
我们在真机的/mnt下写一个这样的脚本:
vim test.sh
#!/bin/tcsh
watch -n 1 date
chmod +x test.sh 给脚本添加执行权限
我们分别用5种方法来执行:
1> sh
2>source test.sh
source 是 Shell 内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。
3> . test.sh
4> . /test.sh
. / 表示当前目录,意思是执行当前目录下的 test.sh 脚本。如果不写. /,Linux 会到系统路径(由 PATH 环境变量指定)下查找 test.sh,而系统路径下显然不存在这个脚本,所以会执行失败。
通过这种方式运行脚本,脚本文件第一行的解释器一定要写对,好让系统查找到正确的解释器。
5> /mnt/test.sh
再举一个例子:
总结:
source 在当前的shell中生效
sh test.sh 开启一个新的shell
./test.sh = /mnt/test.sh 开启一个新的shell,文件第一行写的
source test.sh = . test.sh source运行脚本可以不加第一行,不过只能在shell中运行。
脚本练习
1.执行 ip_show.sh,显示当前主机的 ip 地址
在虚拟机中执行 ip_show.sh eth0,可以显示 eth0 的信息。
思考:如果没有 eth0
代码如下:
#!/bin/bash
[ -z "$1" ] && {
echo : "Error:Please input device name!"
exit
}
ifconfig $1 &> /dev/null || {
echo "$1 is not exist"
exit
}
ifconfig $1 | awk '/inet\>/{print $2}'
2.执行 user_show.sh,显示当前主机中能登陆系统的用户
在虚拟机中执行 user_show.sh,显示当前系统中可以登陆的用户名称
思考:能登陆系统的用户的特性是什么。
/etc/passwd文件最后一列以sh结尾的用户都可以登陆系统。
第1种.
#!/bin/bash
awk -F : '/sh$/{print $1}' /etc/passwd
第2种.
#!/bin/bash
grep sh$ /etc/passwd | cut -d : -f 1
第3种.
#/bin/bash
sed -n '/sh$/p' /etc/passwd | awk -F : '{print $1}'
3.执行 host_message.sh,显示当前主机的名称, ip ,以及能够登陆系统的用户
在虚拟机中执行 host_message.sh
显示当前系统 ip ,当前用户名称,当前目录,当前主机名称
#!/bin/bash
ifconfig eth0 | awk '/inet\>/{print $2}'
echo $USER
pwd
hostname
执行如下:
4.执行clear_log.sh,执行命令后可以清空日志
在虚拟机中执行 clear_log.sh,脚本执行后系统日志清空
日志文件在这里: /etc/rsyslog.conf
为了证明所有日志文件都被清空,我们在 /etc/rsyslog.conf下指定,将所有类型所有级别的日志都定向采集到/mnt/westos下,修改后重启服务。
vim /etc/rsyslog.conf
systemctl restart rsyslog.service
#!/bin/bash
Max_Line=`sed -n '$=' /etc/rsyslog.conf`
Target_Log=`grep RULES /etc/rsyslog.conf -A $Max_Line | awk '!/^#/&&!/^$/{print $2}'|sed '/^:/d;s/-//g'`
echo $Target_Log
for Log_File in $Target_Log
do
> $Log_File && {
echo $Log_File is clear !!
}
done
升级版,判断用户的身份,只有root用户可以清空日志
[ "$USER" = "root" ] ||{
echo "Error : This script must run as root !!"
exit
}
Max_Line=`sed -n '$=' /etc/rsyslog.conf`
Target_Log=`grep RULES /etc/rsyslog.conf -A $Max_Line | awk '!/^#/&&!/^$/{print $2}'|sed '/^:/d;s/-//g'`
echo $Target_Log
for Log_File in $Target_Log
do
> $Log_File && {
echo $Log_File is clear !!
}
done