一、Shell的概念
1、什么是shell?
Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈个用户,这种对话方式可是交互也可是非交互的,我们所输入的命令计算机是不是别的,这是就需要一种程序来帮助我们进行翻译,编号才能计算机能识别的二进制程序,同时又把计算机生成的结果返回给我们。
2、Shell的作用
linux系统中的shell是一个特殊的应用程序,它介于 操作系统和用户的之间,充当一个”命令解释器“的角色,负责输入的操作指令,并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
常见的shell解器有很多中,使用不同的shell,其内部指令、命令性提示符等方面会存在一些区别,通过/etc/shells 文件可以了解当前系统所支持的shell脚本种类。
为什么我们的系统上合法的shell要写入/etc/shells这个文件?
答:系统某些服务要运行的时候,会去检查用户能够使用的shells,而这些shell的查询就是借由/etc/shells这个文件。
用户什么时候可以取得shell来工作?系统默认的shell是哪个?
答: 登录系统时,系统就会加载shell来工作,而登录取得的shell在/etc/passwd这个文件。
shell的种类 | shell的功能 |
---|---|
/usr/bin/sh | 已被/bin/bash替换 |
/bin/sh | 是shell命令的软链接(已被/bin/bash所替换) |
/usr/bin/bash | centos 和redhat 系统默认使用的bash |
/bin/bash | 基准于FNU的框架下发展出的shell |
/usr/sbin/nologin | 让用户无法登陆主机 |
/sbin/nologin | 软连接 |
/bin/csh | 已经被/bin/bash所替换(整个c shell ,提供更多的功能) |
/bin/tcsh | csh的增强版,与csh完全兼容,整合了csh,提供更多的功能 |
3、shell脚本是什么?
shell脚本就是把原来的linux命令或语句放在一个文件中,然后通过这个程序文件去执行,我们就说这个程序为shell 或者脚本。
将需要执行的命令保存到一个文件中,按照顺序执行,它不需要编译,它是解释型的。
4、shell 的能做什么(初步理解)
- 自动化完成软件的安装部署
- 自动化完成系统的管理,如批量添加用户
- 自动化完成备份,如数据库定时备份
- 自动化的分析处理,如网站访问量
应用场景
- 重复性操作、交互性任务、批量事务处理、服务运行状态监控、定时任务执行
二、shell的编程规范
1、shell脚本的构成
第一行为 “ #!/bin/bash ” ,脚本申明(默认解释器)
- 表示此行以下的代码语句是通过/bin/bash程序来执行的,还有其它类型的解释器,比如 : #!/bin/python 、 #!/usr/bin/pxpect
注释信息
- 以“ # ”开头的语句表示为注释信息,被注释的语句在脚本运行时不会执行
可执行语句
- 如echo 命令,用于输出“ ” 之间的字符串。
创建shell程序的步骤
第一步:创建一个包含命令和控制结构的文件
第二步:修改这个文件的权限使它可以执行。(chmod +x 123.sh)
第三步:检测语法错误
第四步:执行脚本
输出结果如下:
2、shell脚本执行
写好shell脚本之后可以进行脚本的调试
- bash -x: 显示执行过程,通常当脚本很长的时候便于定位
- bash -n: 检查语法 如果用vim编写的话,正常的话会变色
2.1 路径执行
- 路径(绝对路径或相对路径)下执行脚本,但是需要给脚本执行权限。
2.2 sh或bash执行
- 使用sh 或 bash 开头进行执行脚本,这种不需要给脚本执行权限
2.3 source 执行
- 使用soure开头进行执行脚本,(可以没有执行权限)
2.4 其它方法
也不需要执行权限
sh < ceshi.sh
cat ceshi.sh | sh(或者bash)
三、重定向与管道操作
1、重定向
用户通过操作系统处理信息的过程,包括以下几类交互设备文件
- 标准输入(STDIN):默认的设备是键盘, 文件编号为0 ,命令将从标准输入文件中读取在执行过程中需要的输入数据
- 标准输出(STDOUT):默认的设备是显示器, 文件编号为1 ,命令将执行后的输出结果发送到标准输出文件。
- 标准错误输出(STDERR):默认的设备是显示器, 文件编号为2 ,命令将执行期间的各种错误信息发送到标准错误文件。
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定文件读取数据 |
输入完后停止指定符号停止 | << | 在向文件输入内容时,加上此符号可定义输入结束的符号(符号基本为EOF) |
重定向输出 | > | 将输出结果保存到指定文件(覆盖原有内容) |
>> | 将输出结果追加到指定文件尾部 | |
标准错误输入 | 2> | 将错误信息保存到指定文件(覆盖原有内容) |
2>> | 将错误信息追加到指定文件 | |
混合输出 | &> | 将标准输出、错误输出的内容保存到同一文件 |
1.1 重定向输出
-
重定向输出指的是将命令的正常输出结果保存到指定的文件中,而不是直接在显示器的屏幕上。
-
重定向输出使用“ > ” 或 “ >> ” 操作符号,分别用于覆盖或追加文件。
-
若重定向输出的目标文件不存在,则会新建该文件,然后将前面命令输出结果保存到该文件中,若目标文件已存在,则将输出结果覆盖或追加到文件中
cat配合重定向输出
cat原本的功能:以标准方式 加载/读取 ,原本的输出位置:屏幕/用户终端界面
,加了重定向输出 “ > ” 和 “ >> ”之后,原本输出的位置,就发生了改变,可以理解为,就是对stdout输出到的位置进行改写。
1.2 重定向输入
-
重定向输入指的是将命令中接收输入的途径由默认的键盘改为 指定的文件 ,而不是等待从键盘输入。
-
重定向输入使用 “ < ” 操作符,通过重定向输入可以使得一些交互式操作过程能够通过读取文件来完成。
解释: 就是使用了重定向输入,可以将一个文件的内容输入到别你想要接收的地方,不需要再进行手动输入。
例1:免交互修改密码
例2:与cat命令结合使用
将某个文件的内容输入到cat的标准输入中,cat获取到后,再显示到终端上。
1.3 错误重定向
错误重定向指的是将执行命令过程中出现的错误信息(如选项获参数错误等)保存到指定的文件,而不是直接显示在屏幕上,错误重定向使用“ 2> ” 操作符。
作用
- 在实际应用中,错误重定向可用来收集程序执行的错误信息,为排错提供依据。
- 还可以将无关紧要的错误信息重定向到空文件/dev/null 中,以保持脚本的输出简洁
PS:/dev/null:把它看做黑洞,所有写入它的内容都会永远丢失,而尝试从它哪里读取内容,则什么也读不到。
&> 和 >& 符号
- &表示混合的意思
例1:输出错误消息到指定文件中
例2:把正确和错误的消息输入到相同的位置
- 1>&2 把标准输出重定向到标准错误
- 2>&1 把标准错误重定向到标准输出
把标准输出,重定向到错误输出里面
把错误输出重定向到标准输出里面
2、管道操作
管道(pipe)操作为不同命令之间的协同工作提供了一种机制,位于管道符号 “ | ” 左侧的命令输出的结果 ,将作为 **右侧命令的输入 **(处理对象),同一命令中可以使用多个管道。
例1:过滤出http://192.168.226.128/noindex/css/open-sans.css中的
协议名:httpd
以及ip地址:192.168.226.128
绝对路径:/usr/local/httpd/htdocs/noindex/css/open-sans.css
相对路径:noindex/css/open-sans.css
四、Shell变量作用类型
1、变量的作用和类型
变量的作用 :用来存放系统和用户需要使用的特定参数(或值)
- 变量名: 使用固定的名称,由系统预设或用户定义
- 变量值: 能够根据用户设置、系统环境的变化而变化
变量的类型
- 自定义变量: 有用户自己定义、修改和使用
- 特殊变量: 环境变量、只读变量、位置变量、预定义变量
2、自定义变量
2.1 变量的定义
格式:变量名=变量值(注意=两边不要有空格)
取消变量的定义:unset 变量名
变量名称需要以字母或下划线开头,名称不要包含特殊字符(如:+、-、*、/、.、?、%、&、#等)
通过在变量名称前添加前导符号 “ $” ,可以引用一个变量的值,使用echo命令查看变量,也可以同时查看多个变量值。
2.2 echo 输出变量值
当变量名称容易跟紧跟其后其它字符混淆时,需要添加大括号“ {} ”,将其括起来,否则无法确定正确的变量,对于未定义的变量,将显示为空值。
echo常用的选项
-
-n : 表示不换行输出
-
-e : 输出转义字符,将转义后的内容输出到屏幕上
-
-
转义字符如下:
-
\c: 不换行输出
-
\n: 换行
-
\t: 转义后表示插入tab,即制表符(多个空格位)
-
例1:使用-n不换行输出
例2:使用-e 输出“双引导”里面的转义字符内容
例3:转义符演示
2.3 单引号、双引号和反撇号
2.3.1 双引号
允许通过$符号引用其它变量值
双引号主要为界定字符串的作用,特别是当要赋值的内容中包含空格时,必须以双引号括,其它情况下通常可以省略
2.3.2 单引号
-
当要赋值的内容中包含$、“ 、\ 等具有特殊含义的字符时,应使用单引号括起来。
-
在单引号的范围内,将无法引用其它变量的值,任何字符均作为普通字符看待,输入什么就显示什么,
-
但是赋值内容中包含单引号时,需要使用 \ 符号进行转移,以免冲突。
2.3.3 反撇号
-
反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值个变量
-
反撇号括起来的范围内必须是能够执行的命令行,否则将会出错
!!注意:上面的反撇号可以使用可以将一个可执行的命令行赋值给到一个变量,但是在一行命令中无法形成嵌套替换的操作,这时可以改用“ $() ”来代替反撇号,以解决嵌套的问题。
2.4 交互式定义变量(read)
可以定义一个变量,将这个变量改为用户输入的值。
常用选项
选项 | 功能 |
---|---|
-p | 提示用户的信息 |
-n | 定义字符数 |
-s | 不显示用户输入的内容,常用于输入密码 |
-t | 定义超时时间,超过多长时间没输就自动退出 |
使用脚本进行解释 -p选项
使用脚本解释-p和-t结合使用
2.5 变量的作用范围
默认的情况下,新定义的变量只是在当前的shell环境中有效,因此是局部变量,当进入子程序或子shell环境时,局部变量将无法再使用。
为了使用用户定义的变量在所有的子shell环境中能够继续使用,减少重复设置功能,可以通过内部命令export将制定的变量到处为全局变量,用户可以同时指定多个变量名称作为参数(无须使用" $ "符号),多个变量名之间以空格分隔
使用export导入为全局变量时,也可以为变量进行复制,这样就有新定义全局变量时就不需要提前进行复制了,
- env 查看用户当前环境变量
3、特殊变量
3.1 环境变量
-
环境变量指的是处于运行需要而由Linux系统提前创建的一类变量,主要用于设置用户的工作环境,会随着用户状态的改变而改变。
-
使用env 命令可查看到当前工作环境下的环境变量,对于常见的一些环境变量应了解其各自的用途
-
USER: 表示用户名称; HOME: 表示用户的宿主目录; LANG: 表示语言和字符集; PWD: 表示当前所在的工作目录; PATH: 表示命令搜索路径等; RANDOM: 表示随机数,会返回0-32767的整数。
PATH 变量
用于设置可执行的默认搜索路径,当仅指定文件名称来执行命令程序时,Linux系统将在PATH变量指定的目录范围查找对应的可执行文件。
解释:就是说有执行文件的话,想要直接执行这个文件,那么这个文件的路径需要在$PATH里面,如果不在,想要执行,必须加上路径才可执行。
想要直接的执行的话,有两种方法
- 方法一:将脚本目录放在$PATH里面
- 方法二:将自己写的脚本放到$PATH中的某个目录中
注意:修改$PATH需要谨慎操作,如果找不到了会影响其它命令的使用!!
3.2 只读变量
-
shell变量中有一种特殊情况,一经设定,其值是不可改变的,这种变量被称为只读变量。
-
在创建的时候可以将其设置为只读属性,也可以将已存在的变量设置为只读属性,只读变量主要用于变量值不允许被修改,不能被删除。
3.3 位置变量
-
当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次复制给位置变量。
-
位置变量也称位置参数,使用$1、$2、$3、$4…$9表示,命令或脚本本身的名称使用" $0"表示
使用脚本写一个创建用户并且修改密码。
例2:使用脚本写一个加法运算,值需要用户输入
3.4 预定义变量
预定义变量是由Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接预定义变量赋值,预定义变量使用“ $ ”符号和另一个符号组合表示。
预定义变量 | 功能 |
---|---|
$# | 表示命令行中位置参数的个数 |
$* | 表示所有位置的内容,这些内容当做一个整体 |
$@ | 表示列出所有位置参数,但是是以单个的形式列出 |
$? | 表前一条命令执行后的返回状态,返回值为0,表示执行正确,返回任何非0值均表示执行出现异常 |
$0 | 表示当前执行的脚本或程序的名称 |
$$ | 表示返回当前进行的进程号 |
$! | 返回最后一个后台进程的进程号 |
例1:根据一个简单的脚本来理解每个预定义和位置变量的含义
例2: 将脚本进行优化输出
理解 “ $ ” 和 “ $@ ” 的区别*
- $*: 把所有参数看成以空格分隔的一个字符串整体(单字符串),代表“$1 $2 $3 $4”
- $@ : 把各个参数加上双引号分隔成n份的参数列表,每个参数做为一个字符串返回,代表“$1" “$2” “$3"”$4"
五、变量运算
在Bash Shell 环境中,只能进行简单的整数运算,不支持小数运算。
- 运算内容: 加(+)、减(-)、乘(*)、除(/)、取余(%)
- 运算符号: $(()) 和 $[]
- 运算命令: expr 和 let
- 运算工具: bc(系统自带)
1、expr命令
整数值的运算主要通过内部命令expr进行, 运算符与变量之间,必须有至少一个空格 ,不仅可以进行运算,还支持输出到屏幕
常量运算
变量运算
脚本执行运算
2、运算符号
$(()) 和 $ [] 必须要和echo在一起用 ,因为它只能运算无法输出结果,这两个运算符号之间,不需要使用$符号引用变量,可直接使用表达式。
2.1 $(( )) 符号的使用
2.2 $[] 符号的使用
3、let 命令
let的运算可以改变变量本身的值,但是不显示结果,需要echo。
4、bc 命令
使用bc进行运算,支持小数运算,但是在脚本中不可直接使用,否则会进入交互界面,可以使用echo结合管道使用。
支持小数运算,但是在脚本中不能直接使用,否则进入了交互界面,所以在使用时,需要加入echo 表达式 + 管道符 + bc 。还可以使用scale 命令表示保留多少位小数,直接scale=2,表示保留两位小数。加入到表达式中,也就是: echo ”scale=2;表达式“ | bc
常量的运算
变量的运算
bc做逻辑判断
使用脚本写出,写出求当前内存的使用率的带下,并且与%50比较,小于的话,输出内存较小
六、总结
shell的作用:主要是为了自动化操作
1、shell的编程规范
注意shell的命令,要以.sh结尾,在脚本中需要注入解析器,默认的解析器为:#!/bin/bash,shell的执行有多种方式,可以使用绝对路径或相对路径进行执行脚本,但是此方法需要加上执行权限,如果不加执行权限,可以使用bash、sh、source命令进行执行
2、重定向和管道符操作
重定向
-
有标准输入(stdin)、标准输出(stout)、错误输出(stderr)
-
" > ": 表示标准重定向输出,可以结合cat手动输入一些信息,输入完,会覆盖以前的内容
-
“ >> ”:表示重定向输出,将手动输入的内容重定向追加到文件中
-
“ < ” :表示重定向输入,结合cat使用时,可以将文件中的内容输入到cat中,然后cat将内容输出
-
“ << ” :表示以设么字符进行结尾,大部分使用的是EOF
-
“1>&2” :表示将标准输出,混合到错误输出里面
-
“2>&1” :表示将错误输出,混合到标准输出里面
管道符号 “ | ”
- 表示将管道符号前面的执行结果,输出到管道符后面进行执行
3、shell 变量
自定义变量
可以使用echo 加参数进行输出。有时候变量输出要和普通内容在一起输出,可以使用${} 将变量名进行引用用于区别的内容。
单引号的作用( ‘ ’ ) : 表示引号的内容就是要输出的内容,不会转变引号的内部
双引号的作用(“ ”): 表示引号的内容进行输出,但是内部的变量会进行输出,echo默认就是双引号,平常echo输出的内容有空格时,可以加上双引号标注。
单撇号的作用(``): 表示单撇号中的内容,必须是可执行的命令,但是这种无法进行嵌套,所以还可以使用$() 进项嵌套输出,从内往外进行输出。
交互式定义变量: 使用read 可以将变量从用户手从获取到,与用户进行交互,加上-p 可以输入交互提示信息,-t,用户输入变量内容时,不显示出来
**变量的作用范围: **变量作用范围,在当前的shell环境中,如果使用bash开启一个子shell,那么它的父进程shell的变量将无法使用,可以使用命令export 将局部变量加入到全局变量中,
特殊变量
- 环境变量: 为系统自动生成的变量名,不同的变量名代表不同的含义,且跟随用户状态而改变,其中 $ PATH表示命令可以生成的变量路径,当我么执行一个命令的同时,他会搜索$PATH下的命令
- 只读变量: 变量只能读取不能修改或删除,可以使用readonly 加上变量名即可生成
- 位置变量: 使用$1 ,$2 ,$3…等表示位置变量,$0表示脚本名称,位置变量需要用户在执行脚本的时候进行输入。
- 预定义变量: $#:表示位置变量的个数, ∗ : 表 示 位 置 变 量 的 内 容 , 放 在 一 起 输 出 , *:表示位置变量的内容,放在一起输出, ∗:表示位置变量的内容,放在一起输出,@:表示位置变量的内容,分开显示输出,$?:表示上一条命令执行是否正确,$0:表示脚本名称
4、变量运算
expr命令: 不仅可以进行运算,还可以进行显示输出,需要注意的是,运算符两边需要有空格,不然会进行报错。
使用expr命令,基本进行,+、-、*、/、%、操作
运算符号运算: $[] 或者 $ (( )) 这两个括号内容都可以进行运算,但是它只会进行运算,不能输出结果,所以需要结合echo 进行输出。并且括号中可以不用使用$符号进行申明变量,可直接使用变量值。
let命令: let命令可以进行改变量值的本身,相当于对变量自身做出运算,然后再赋值给自身,
但是不能进行输出,也需要借助echo进行输出,
bc命令: 支持小数运算,但是在脚本中不能直接使用,否则进入了交互界面,所以在使用时,需要加入echo 表达式 + 管道符 + bc 。还可以使用scale 命令表示保留多少位小数,直接scale=2,表示保留两位小数。加入到表达式中,也就是: echo ”scale=2;表达式“ | bc