Shell脚本概述
Shell脚本的概念
将要执行的命令按顺序保存到一个文本文件
给该文件可执行权限
可结合各种Shell控制语句以完成更复杂的操作
Shell脚本应用场景
重复性操作
交互性任务
批量事务处理
服务运行状态监控
定时任务执行
shell脚本编程规范与变量
1、什么是shell?
shell是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户。这种对话方式可是交互也可以是非交互式的,我们所输入的命令计算机是不识别的,这时就需要一种程序来帮助我们进行翻译,变成计算机能识别的二进制程序,同时又把计算机生成的结返回给我们
2、shell的作用
1) shell 的作用
Linux系统中的shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执给内核执行,并输出执行结果。
常见的shell解释器程序有很多种,使用不同的shell时,其内部指令、命令行提示符等方面会存在一些区别。通过/etc/shells文件可以了解当前系统所支持的shell脚本种类。
[root@localhost ~]# cat letc/ shells
/bin/sh #是bash命令的软链接(已经被/bin/bash所替换)
/ bin/bash #基准于GNU的框架下发展出的shell。
/usr/bin/sh #已经被bash所替换。
/usr/bin/bash #centos和redhat系统默认使用bash shell
/bin/tcsh #csh的增强版,与csh完全兼容整合了csh,提供更多的功能。
/bin/csh #已经被/bin/bash所替换―(整合C shell,提供更多的功能)
注: noloain:奇怪的shell,这个shell可以让用户无法登录主机。
bash (/bin/bash)是目前大多数linux版本采用的默认Shell
为什么我们的系统上合法的shell要写入/etc/shells这个文件?
这是因为系统某些服务在运行过程中,会去检查用户能够使用的shells,而这些shell的查询就是借由/etc/shells这个文件。
用户什么时候可以取得shell来工作?还有我这个默认会取得哪一个shell?
当我登录的时候,系统就会给我shell让我来工作,而这个登录取得的shell就记录在/etc/passwd这个文件内。
不同的shell具备不同的功能,shell还决定了Linux中默认的shell是/bin/bash,流行的shell有ash、bash、ksh、csh、zsh等,不同的shell都有自己的特点以及用途
目前大多数linux系统默认使用的是bash shell,默认登陆shell是/bin/bash,可以查看/etc/passwd文件里
注明:
这个shell是针对用户而言的,可以查看/etc/passwd里面的最后的字段使用的是哪个shell,如果想要修改可以用chmod -s或者chsh -s来重新指定
2 ) shell脚本是什么
shell脚本就是说我们把原来 linux
命令或语句放在一个文件中,然后通过这个程序文件去执行时,我们就说这个程序为 shell脚本或shell
程序;我们可以在脚本中输入一系统的命令以及相关的语法语句组合,比如变量,流程控制语句等,把他们有机结合起来就形成了一个功能强大的shell脚本
总结:将需要执行的命令保存到一个文件中,按照顺序执行,它不需要编译,它是解释型的
3) shell脚本能干什么
自动化完成软件的安装部署,如安装部署LAMP架构服务
自动化完成系统的管理,如批量添加用户
自动化充成备份,如数据库定时备份
自动化的分析处理,如网站访问量
4 ) shell脚本使用场景
在需要完成大量复杂、重复性的工作时,不需要在命令行重复执行命令,直接运行shell脚本即可,大大的节省了时间提高了效率
5 )如何学习shell脚本
熟悉掌握各种linux命令
掌握脚本的标准格式
掌握脚本的基本语法
编写Shell脚本
shell脚本的构成
第一行为"#!/bin/bash" ,脚本申明(默认解释器)﹔表示此行以下的代码语句是通过/bin/bash程序来执行。还有其他类型的解释器,
比如#! /usr/bin/python、# ! /usr/bin/expect
注释信息:以"#”开头的语句表示为注释信息,被注释的语句在脚本运行时不会被执行可执行语句:如echo命令,用于输出""之间的字符串
开始编写脚本
例1
vim first.sh
cd /boot/
pwd
ls -lh vml*
例2
#!/ bin/ bash
#This is my first shell-script.
cd /boot
echo "当前的目录位于:"
pwd
echo "其中以vml开头的文件包括:”
ls -lh vml*
创建shell程序的步骤:
第一步:创建一个包含命令和控制结构的文件。
第二步:修改这个文件的权限使它可以执行 #使用chmod +x test.sh
第三步:检测语法错误
第四步:执行 ./first .sh
shell脚本执行
shell 脚本的执行通常有以下几种方式
方法一:当前路径(决定路径与相对路径)下执行脚本(要有执行权限)/ home/ first.sh或者./first.sh
方法二:sh . bash脚本文件路劲(这种方式可以不对脚本文件添加执行权限)bash first.sh或sh first.sh
方法三: source脚本文件路劲(可以没有执行权限)source first.sh
方法四:其他方法
sh < first.sh或者cat first.sh |sh (bash)
shell脚本执行
shell 脚本的执行通常有以下几种方式
方法一:当前路径(决定路径与相对路径)下执行脚本(要有执行权限)
/home/first.sh或者./first.sh
方法二: sh . bash脚本文件路劲(这种方式可以不对脚本文件添加执行权限)
bash first.sh或sh first.sh
方法三: source 脚本文件路劲(可以没有执行权限)
source first.sh
方法四:其他方法
sh < first.sh或者 cat first.sh | sh (bash)
重定向与管道操作
交互式硬件设备
标准输入:从该设备接收用户输入的数据
标准输出:通过该设备向用户输出数据
标准错误:通过该设备报告执行出错信息
重定向与管道操作
重定向:
用户通过操作系统处理信息的过程中,包括以下几类交互设备文件
标准输入(STDIN):默认的设备是键盘,文件编号为
0,命令将从标准输入文件中读取在执行过程中需要的输入数据。
标准输出(STDOUT) :默认的设备是显示器,文件编号为
1,命令将执行后的输出结果发送到标准输出文件。
标准错误(STDERR):默认的设备是显示器,文件编号为
2,命令将执行期间的各种错误信息发送到标准错误文件。
从键盘接收用户输入的各种命令字串、辅助控制信息,并将命令结果输出到屏幕上;如果命令执行出错,也会将错误信息反馈到屏幕上
1)重定向输出
重定向输出指的是将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上。
重定向输出使用">"或">>"操作符号,分别用于覆盖或追加文件
若重定向输出的目标文件不存在,则会新建该文件,然后将前面命令的输出结果保存到该文件中﹔若目标文件已经存在,则将输出结果覆盖或追加到文件中。
>意思是当原来文件中有内容的话,原来的内容会被覆盖掉
>>意思是当原来文件中有内容的话,新加的内容会追加到里面而不会覆盖原来的内容
列1
uname -p > kernel.txt
2)重定向输入
重定向输入指的是将命令中接收输入的途径由默认的键盘改为指定的文件,而不是等待从键盘输入。重定向输入使用“<操作符。
通过重定向输入可以使一些交互式操作过程能够通过读取文件来完成。例如,使用passwd命令为用户设置密码时,每次都必须根据提示输入两次密码字串,非常烦琐,若改
用重定向输入将可以省略交互式的过程,而自动完成密码设置(结合passwd命令的”--stdin”选项来识别标准输入)。
列1
#添加初始密码串内容"123456"
vim pass.txt
#从pass.txt读入密码给paswd命令而不是等待用户从键盘输入123456
passwd --stdin jerry < pass.txt
例2:
[root@localhost ~]# cat 1.txt //以键盘为输入设备,这也是系统默认的
1234
1234
[root@localhost ~]# cat <1.txt /跟cat 1.txt
结果是一样的,但是这是以1.txt文件作为输入设备了
1234
1234
默认情况下, cat
命令会接受标准输入设备(键盘)的输入,并显示到控制台,但如果用文件代替键盘作为输入设备,那么该命令会以指定的文件作为输入设备,并将文件中的内容读取并显示到控制台
[ root@localhost ~]cat <<0
//以0作为分界符,只要不输入0就会一直输入数据从而显示到屏幕
> 123
>456>0
123
456
[ root@localhost ~].cat << 0 > a.txt
//可以把输入重定向和输出重定向结合使用,把从屏幕输出的内容保存到文件
>123
>456
>0
[root@localhost ~]# cat a.txt
123
456
3)错误重定向
错误重定向指的是将执行命令过程中出现的错误信息(如选项或参数错误等)保存到指定的文件,而不是直接显示在屏幕上。错误重定向使用"2>"操作符
2个作用:
在实际应用中,错误重定向可用来收集程序执行的错误信息,为排错提供依据
还可以将无关紧要的错误信息重定向到空文件/dev/null 中,以保持脚本输出的简洁
使用"2>"操作符时,会像使用">"操作符一样覆盖目标文件的内容,若要追加内容而不是覆盖文件,则应改用"2>>"操作符
当命令输出的结果可能既包括标准输出(正常执行)信息,又包括错误输出信息时,可
以使用操作符">""2>"将两类输出信息分别保存到不同的文件,也可以使用"&>"操作符将两类输出信息保存到同一个文件
/ dev/null:把它看作"黑洞",所有写入它的内容都会永远丢失.
而尝试从它那儿读取内容则什么也读不到.然而/dev/null对命令行和脚本都非常的有用echo kgc > /dev/null
cat /dev/null #什么信息也看不到
&>和>&符号
&表示等同于的意思
例1:把正确和错误的消息输入到相同的位置
1>&2把标准输出重定向到标准错误
列1:
将错误显示的内容和正确显示的内容分开
ls /etc/passwd xxxx
ls: 无法访问xxx:没有那个文件或目录
etc/passwd
ls /etc/passwd xxx > a.txt
ls:无法访问xxx:没有那个文件或目录
cat a.txt
/etc/passwd
ls /etc/passwd xxx 2> a.txt
/etc/passwd
cat a.txt
ls: 无法访问xxx:没有那个文件或目录
注:使用2>操作符时,会像使用>一样覆盖目标文件的内容,若追加而不覆盖文件的内容即可使用2>>操作符
列2
tar jcf /nonedir/etc.tgz /etc/ 2>error.log
cat /error.log
例3,
在编译源码包的自动化脚本中,若要忽略make、make install等操作过程信息,则可以将其定向到空文件/dev/ null。
#!/ bin/ bash #自动编译安装httpd 服务器的脚本
cd /usr/ src/httpd-2.4.25/
./ configure --prefix=/usr/local/httpd --enable-so &> /dev/null
make &>/dev/null
make install &> /dev/null #/dev/null等同于make install > /dev/null 2>&1
4)管道操作
管道(pipe)操作为不同命令之间的协同工作提供了一种机制,位于管道符号" |"左侧的命令输出的结果,将作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。
在 shell脚本应用中,管道操作通常用来过滤所需要的关键信息。
$bash $表示系统提示符,$表示此用户为普通用户,超级用户的提示符是#,bash是shell的一种,是linux下最常用的一种shell
$bash的意思是执行一个子shell,此子shell为bash。
列1:
rpm -qa | grep httpd
grep "/bin/bash$" /etc/passwd | awk -F: '{print $1,$7}'
列2
df -hT l grep "/$" l awk ' { print $6}'
总结:
重定向与管道操作是shell
环境中十分常用的功能,若能够熟练掌握并灵活运用,将有助于编写代码简洁但功能强大的shell脚本程序
Shell变量的作用、类型
变量的作用
用来存放系统和用户需要使用的特定参数(值)
变量名:使用固定的名称,由系统预设或用户定义
变量值:能够根据用户设置、系统环境的变化而变化
变量的类型
自定义变量:由用户自己定义、修改和使用
特殊变量:环境变量,只读变量,位置变量,预定义变量
shell变量及赋值
shell的变量
变量是用来临时保存数据的,并且该数据时可以变化的,任何一个语言都离不开变量,如果某个内容需要多次使用并且会重复出现,这样就可以使用变量了,如果需要修改直接修改变量就可以了
常见 shell变量的类型包括自定义变量、环境变量、只读变量、位置变量、预定义变量
自定义变量
1、变量的定义
Bash中的变量操作相对比较简单,不像其他高级编程语言(如C/C++、Java等)那么复杂。在定义一个新的变量时,一般不需要提前进行声明而是直接指定变量名称并赋给初始值(内容)即可
格式:变量名=变量值
变量名:临时存放数据的地方
变量值:临时的可变化的数据
等号两边没有空格。变量名称需以字母或下划线开头,名称中不要包含特殊字符(如+、-、*、/、 .、 ?、%、&、#等)
用echo查看和引用变量的值
通过在变量名称前添加前导符号"$,可以引用一个变量的值,使用echo命令可以查看变量,可以在一条echo 命令中同时查看多个变量值
列1
Product=Python
version=2.7.13
echo $Productsversion
当变量名称容易和紧跟其后的其他字符相混淆时,需要添加大括号"{ }"将其括起来,否则将无法确定正确的变量名称。对于未定义的变量,将显示为空值
举例说明
列2
{ }引用变量
echo $ { Product}2.5
echo $ {test ] RMB
echo选项
echo -n 表示不换行输出
使用echo -e输出转义字符,将转义后的内容输出到屏幕上
常用的转义字符如下:
\c不换行输出,在"\c"后面不存在字符的情况下,作用相当于echo -n
\n换行
\t转义后表示插入tab,即制表符
注: \转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\s将输出"s"符号,而不当做是变量引用
特殊操作
还有一些特殊的赋值操作,可以更灵活地为变量赋值,以便适用于各种复杂的管理任务
双引号(")
双引号主要起界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来;其他情况下号通常可以省略
1、当内容中有空格
echo "hello world”
echo nihao
2、当以变量的值进行赋值
[root0localhost ~]#version=2
[root@localhost ~] # pyver="python $version"
[root@localhost ~]f echo $pyver
python 2
单引号 ( ')
当要赋值的内容中包含$、"、\等具有特殊含义的字符时,应使用单引号括起来。
在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。输入什么就显示什么但赋值内容中包含单引号(')时,需使用'符号进行转义,以免冲突。
[root@localhost~]. test=123
[root@localhost ~]. echo "$test"
123
[root@localhost ~]. echo ' $test'
$stest
反撇号( ')
反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。
反撇号括起来的范围内必须是能够执行的命令行,否则将会出错
ls -lh which useradd
先通过 which useradd 命令查找出 useradd命令的程序位置,然后根据查找结果列出文件属性
date +%Y-%m-%d
[root@localhost ~]# time= "date +号T`
[root@localhost ~]# echo $time
04:23:22
使用反撇号难以在一行命令中实现嵌套命令替换操作,这时可以改用
"$()"来代替反撇号操作,以解决嵌套的问题
rpm -qc $ (rpm -qf $ ( which useradd) )
赋值时使用引号
双引号:允许通过$符号引用其他变量值
单引号:禁止引用其他变量值,$视为普通字符
反撇号:命令替换,提取命令执行后的输出结果
从键盘输入内容为变量赋值
read [ -p“提示信息" ]变量名
交互式定义变量
read 命令
除了上述赋值操作以外,还可以使用Bash 的内置命令read来给变量赋值。
用来提示用户输入信息,从而实现简单的交互过程。执行时将从标准输入设备(键盘)读入一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量(多余的内容赋值给最后一个变量)。若指定的变量只有一个,则将整行内容赋值给此变量。
[ root@localhost ~]# read test
123 //等待用户输入,把输入的值赋子test变量
[ root@localhost ~]# echo $test
123
一般来说为了使交互式操作的界面更加友好,提高易用性,read
命令可以结合"-p"选项来设置提示信息,以便告知用户应该输入什么内容等相关事项
[root@localhost ~]# read -p "请输入你的姓名:" name
请输入你的姓名: humajun
[ root@localhost ~].echo $name
wangsihao
交互式定义变量(read)
-p提示用户的信息
-n定义字符数
-s不显示用户输入的内容,常用于输入密码 read -s -p "input your password:" pass
-t定义超时时间,超过多长时间没输自动退出
从文件读取内容赋值给变量
[root@server myscripts] #echo 192.168.100.100 > ip.txt
[ root@server myscripts] # cat ip.txt
192.168.100.100
[root@server myscripts]# read -p "input your ip:" IP < ip.txt
[root@server myscripts]#echo $IP
192.168.100.100
stty -echo //关闭屏幕回显
stty echo //开启屏幕回显
变量的作用范围
默认情况下,新定义的变量只在当前的 shell 环境中有效,因此称为局部变量,当进入子程序或新的子Shell 环境时,局部变量将无法再使用
[root@localhost ~]# bash #进入子shell环境
[root@localhost ~]#
[ root@localhost ~]# echo $name
[ root@localhost ~]# echo $test
export命令
为了使用户定义的变量在所有的子 shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export
将指定的变量导出为全局变量。用户可以同时指定多个变量名称作为参数(无须使用"$"符号),变量名之间以空格分隔
[ root@localhost ~]# exit
exit
[root@localhost ~]# export name test
[root@localhost ~]# bash
[root@localhost ~]# echo $name $testexit
humajun 123
或
[root@localhost ~]# echo "$Product $Version"
Benet 6.0
[root@localhost ~]# export Product version #导出为全局变量
[root@localhost ~]# bash
[root@localhost ~]# echo "$Product $Version” #子程序引用全局变量Benet 6.0
[root@localhost ~]# exit
使用 export 导出全局变量的同时,也可以为变量进行赋值,这样在新定义全局变量时就不需要提前进行赋值了
env查看用户当前环境变量
export ABC=123
再次env就能看到了
export -n ABC 取消定义的全局变量变成局部变量