规范很重要!!学Shell编程之前不得不了解的一些规则
Posted ‘朱砂痣’、
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了规范很重要!!学Shell编程之前不得不了解的一些规则相关的知识,希望对你有一定的参考价值。
Shell编程规范和变量
一、Shell脚本概述
1.1、Shell脚本的概念
- 将要执行的命令按顺序保存到一个文本文件;
- 给该文件可执行权限;
- 可结合各种Shell控制语句以完成更复杂的操作。
1.2、Shell脚本应用场景
- 重复性操作
- 交互性任务
- 批量事务处理
- 服务运行状态监控
- 定时任务执行
- 。。。。。。
1.3、Shell的作用----命令解释器,“翻译官”
Shell (壳程序)是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器"的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
简单说:
- Shell是一个特殊的应用程序,介于系统内核与用户之间,充当解释器,负责解释命令行
- 将用户输入的指令进行解释,传递给内核执行,然后输出结果
- 大多数默认Shell是Bash(bin/bash)
1.4、用户的登录shell
- 登录后默认使用的Shell程序,一般为/bin/bash
- 不同Shell的内部指令、运行环境等会有所区别
查看Shell程序:在/etc/shells里面,以及每个shell程序的作用
[root@localhost shell]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
#####################各个shell程序的作用
bash:基于GNU的框架下发展出的Shell
csh:语法有点类似C语言的Shell
tcsh:整合了csh,提供了更多的功能
sh:已经被bash所替代
nologin:奇怪的shell,这个shell可以让用户无法登录主机
补充:为什么系统上合法的shell要写入/etc/shells这个文件呢?
因为系统中某些服务运行过程中,会去检查用户用户能够使用的shell,而检查的文件程序就借/etc/shells这个文件
用户什么时候可以取得shell来工作?用户默认会取得那个shell?
当用户登录的时候就用到了shell,并且登录取得的shell记录在/etc/passwd文件里
Shell是一个面向字符串的编程语言,可以跟Python之类的编程语言结合起来,比如某个复杂的功能使用一个python脚本来实现,然后在shell中调用这个脚本来实现较复杂的功能,或者反过来,在python脚本中调用外部的shell脚本来提高自动化效率,也是可以的
1.5、shell脚本的作用
- 自动化运维
- 批量化重复操作可以编写脚本结合计划任务自动周期运行
- 减轻管理员工作量
- 提高处理文本的速度
- 避免配置出错
1.6、Shell脚本的构成
- 脚本申明(解释器):也就是这个脚本用哪个shell来执行,默认的是 #!/bin/bash这个解释器。还有其他类型的解释器,如#!/usr/bin/python,#!/usr/bin/expect
- 注释信息:以#开头,不会在脚本中执行,写注释是个好习惯
- 执行语句:
例如:
查看python解释器程序
- 编写第一个shell脚本
1.7、shell脚本的执行以及每种执行方法的区别
方法一:指定路径
指定路径的命令,要求文件必须要有#x(执行)权限
chmod u+x /root/shell01.sh #默认是u,可以省略
即:
chmod +x /root/shell01.sh
指定绝对路径:/root/first.sh
指定相对路径:./first.sh
方法二:指定Shell
指定Shell来解释脚本,不要求文件有x权限
1、sh 脚本路径:shell01.sh
2、source 脚本路径:.shell01.sh 或者 source shell01.sh
注:降低权限的方法:chmod -x shell01.sh
二、重定向和管道操作
2.1、交互式硬件设备
- 标准输入:从该设备接收用户输入的数据
- 标准输出:通过该设备向用户输出数据
- 标准错误:通过该设备报告执行出错信息
类型 | 设备文件 | 文件描述编号 | 默认设备 |
---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误 | /dev/stderr | 2 | 显示器 |
2.2、重定向操作
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定文件读取数据,而不是从键盘输入 |
重定向输出 | > | 将输出结果保存到指定文件(覆盖原有文件) |
>> | 将输出结果追加到指定文件的尾部 | |
标准错误输出 | 2> | 将错误信息保存到指定文件(覆盖原有文件) |
2>> | 将错误信息追加到指定文件的尾部 | |
混合输出 | &> | 将标准输出,标准错误的内容保存到同一个文件中 |
2>&1 | 将标准错误输出重定向到标准输出 |
注意:重定向输出指定的文件如果不存在会自动创建这个文件
重定向输入操作演示:
[root@localhost shell02]# echo 123456 >pass.txt
[root@localhost shell02]# ls
\\ pass.txt shell01-1.sh shell01.sh shell02-2.sh shell02.sh shell03.sh shell04.sh shell05.sh test.sh
[root@localhost shell02]# useradd zhangsan
[root@localhost shell02]# passwd --stdin zhangsan < pass.txt
更改用户 zhangsan 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@localhost shell02]# su zhangsan
[zhangsan@localhost shell02]$ su
密码:
[root@localhost shell02]# su lisi
[lisi@localhost shell02]$ su zhangsan
密码:
[zhangsan@localhost shell02]$
注意:如果出现鉴定错误,可以关闭防火墙,setenforce 0
重定向输出操作演示:
[root@localhost ~]# echo abc > abc.txt
[root@localhost ~]# cat abc.txt
abc
[root@localhost ~]# echo 123 > abc.txt
[root@localhost ~]# cat abc.txt
123
[root@localhost ~]# echo zcq >> abc.txt
[root@localhost ~]# cat abc.txt
123
zcq
[root@localhost ~]#
标准错误输出演示:
[root@localhost ~]# ech 0 2> abc.txt
[root@localhost ~]# cat abc.txt
bash: ech: 未找到命令...
[root@localhost ~]# ecoh 0 2>> abc.txt
[root@localhost ~]# cat abc.txt
bash: ech: 未找到命令...
bash: ecoh: 未找到命令...
相似命令是: 'echo'
[root@localhost ~]# echo 123 2>> abc.txt
123
[root@localhost ~]# cat abc.txt
bash: ech: 未找到命令...
bash: ecoh: 未找到命令...
相似命令是: 'echo'
[root@localhost ~]#
混合输出演示:
[root@localhost ~]# ecoh 0 &> abc.txt
[root@localhost ~]# cat abc.txt
bash: ecoh: 未找到命令...
相似命令是: 'echo'
将ls -lh现实的结果输出到文件里:
[root@localhost ~]# ls -lh > log.txt
[root@localhost ~]# cat log.txt
代码执行过程:
ls -lh > log.txt 等同于 ls -lh &> log.txt
本来是标准输出,要输入到屏幕 就是:本来1-->屏幕(1指向屏幕)
执行>log 后,1-->log.txt (1指向log.txt)
执行2>&1后,2--> (而1指向log.txt,因此2也指向了log.txt)
2.3、管道操作
- 管道操作符:|
功能:将左侧的命令输出结果,作为右侧命令的处理对象
cmd1 | cmd2 | cmd3 .......
[root@localhost ~]# grep "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
zhang:x:1000:1000:zhang:/home/zhang:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
zhangsan:x:1002:1002::/home/zhangsan:/bin/bash
[root@localhost ~]# grep "bash$" /etc/passwd | awk -F: '{print $1,$7}'
root /bin/bash
zhang /bin/bash
lisi /bin/bash
zhangsan /bin/bash
[root@localhost ~]#
管道符“|”与xargs的区别:
- 管道符 将 “|” 之前的命令标准输出,作为之后命令的标准输入。
- xargs 将上一命令的标准输出,作为后面命令的参数args。
三、Shell脚本变量
3.1、变量的作用
用来存放系统和用户需要使用的特定参数(值)
- 变量名:使用固定的名称,由系统预设或用户定义
- 变量值:能够根据用户设置、系统环境的变化而变化
3.2、变量的分类
- 自定义变量:由用户自己定义、修改和使用
- 特殊变量
- 环境变量:由系统维护,用于设置工作环境
- 只读变量:用于变量值不允许被修改的情况
- 位置变量:通过命令行给脚本程序传递参数
- 预定义变量:bash中内置的一类变量,不能直接修改
3.3、自定义变量
格式:
变量名=变量值
注意:==变量名以字母或下划线开头,区分大小写,建议全大写==
查看变量的值:echo $变量名
示例:
- 赋值时使用引号
双引号:允许通过$符号引用其他变量值
单引号: 禁止引用其他变量值,$视为普通字符
反撇号: 命令替换,提取命令执行后的输出结果
错误示范:
正确示范:
- 从键盘输入内容为变量赋值
read [-p “提示信息”] 变量名
- 设置变量的作用范围
格式1:export 变量名
格式2:export 变量名=变量值
示例:
- 整数变量的运算
expr 变量1 运算符 变量2 [运算符 变量3]
常用运算 | 对应的运算符 |
---|---|
加法运算 | + |
减法运算 | - |
乘法运算 | * |
除法运算 | / |
求模(取余)运算 | % |
五种运算的操作示例:
- 运算总结
- 变量值与运算符号之间要有空格
- 乘法运算要用KaTeX parse error: Undefined control sequence: \\* at position 1: \\̲*̲
- 将变量值赋给变量名的时候,要用进行引用变量,如:$zz
3.4、特殊变量
3.4.1、环境变量
由系统提前创建,用来设置用户的工作环境
配置文件:/etc/profile、~/.bash_profile
放在这里的环境变量才能一直有效
常见的环境变量有:
PWD、PATH
USER、SHELL、HOME
export PATH定义的变量全局有效,不过重启之后就没有了作用
######临时设置
export PATH="$PATH:/root"
env查看当前工作环境下的环境变量
3.4.2、只读变量
作用:用于变量值不允许被修改的情况
总结:只读变量只能查看,不能修改,不能删除
3.4.3、位置变量
表示为$n,n为1~9之间的数字
如果是$10的话就是$1表示的参数后面跟个0
如果非要把第十一个参数显示出来的话可以用${11}
==注意:$11 ==
与${11}的区别
3.4.4、预定义变量
$*、$@:表示命令或脚本要处理的参数。
$*:把所有参数看成以空格分隔的一个==字符串整体==,代表"$1 $2 $3 $4"。
$@:把各个参数加上双引号==分隔成n份==的参数列表,每个参数是独立 的,代表"$1" "$2" "$3" "$4"。
$#:表示命令或脚本要处理的参数的个数。
$0:表示当前执行的脚本或命令的名称
$?:表示前一条命令或脚本执行后的返回状态码,返回值为0表示执行正确,返回任何非0值均表示执行出现异常
$*
$@区别
操作:in后面不加双引号的情况,两者没有区别
结果:
操作:in后面的变量加双引号之后的情况,功能不同了
结果:
四、3种整数运算
4.1、expr运算
格式:
######第一种
expr 变量1 运算符 变量2
########常用的运算表达式
i=$(expr 12 \\* 5) ### ==expr和变量之间要有空格==
常用的运算表达式:
[root@localhost ~]# a=$(expr 12 \\* 5)
[root@localhost ~]# b=$((12\\*5))
-bash: 12\\*5: 语法错误: 无效的算术运算符 (错误符号是 "\\*5")
[root@localhost ~]# b=$((12*5))
[root@localhost ~]# c=$[12*5]
[root@localhost ~]# let d=12*5
[root@localhost ~]# echo $a $b $c $d
60 60 60 60
注:只有在expr中,乘法才用==“反斜杠加*”==
4.2、let运算
格式:
[root@localhost ~]# let d=12*5
[root@localhost ~]# echo $d
60
4.3、自增自减
i++相当于 i=$[$i+1]
i--相当于 i=$[$i-1]
i+=2相当于 i=$[$i+2]
[root@localhost ~]# let d++
[root@localhost ~]# echo $d
61
[root@localhost ~]# let d++
[root@localhost ~]# echo $d
62
[root@localhost ~]# let d--
[root@localhost ~]# echo $d
61
[root@localhost ~]# let d+=2
[root@localhost ~]# echo $d
63
[root@localhost ~]#
注意:bash 不支持浮点运算,如果要进行浮点运算,需要借助bc,awk处理(bc工具要安装),awk功能非常强大
4.4、运用bc工具进行浮点运算
格式:
#!/bin/bash
#+
a=$(echo "4.3 + 2.5"|bc)
echo "4.3+2.5=$a"
#-
b=$(echo "4.3 - 2.5"|bc )
echo "4.3-2.5=$b"
#*
c=$(echo "4.30 * 2.50"|bc)
echo "4.30*2.50=$c"
#/
d=$(echo "scale=3;4.3 / 2.5"|bc)
echo "4.3/2.5=$d"
#混合运算
e=$(echo "2.2/(2.2-1.1)*2+1.1"|bc)
echo "2.2/(2.2-1.1)*2+1.1=$e"
4.5、运用awk文本工具进行浮点运算
格式:
#!/bin/bash
#awk工具进行浮点运算
#+
a=$(awk 'BEGIN{print 4.5 + 3.4}')
echo "4.5+3.4=$a"
#-
b=$(awk 'BEGIN{print 4.5 - 3.4}')
echo "4.5-3.4=$b"
#*
c=$(awk 'BEGIN{print 4.5 * 3.4}')
echo "4.5*3.4=$c"
#/
d=$(awk 'BEGIN{print 4.5 / 3.4}')
echo "4.5/3.4=$d"
#混合运算
e=$(awk 'BEGIN{print (4.5 - 3.4)*2+3}')
echo "(4.5-3.4)*2+3=$e"
总结:三种符号的区别以及作用
单引号:$当作普通字符输出
双引号:当成变量输出
反撇号: 命令替换,提取命令执行后的输出结果
还有就是shell重要的一点就是语法错误,shell脚本是一行一行执行,注意一个符号或者一个空格错了都执行不了。
以上是关于规范很重要!!学Shell编程之前不得不了解的一些规则的主要内容,如果未能解决你的问题,请参考以下文章