shell 脚本规范
**脚本名称规范:
文件名以.sh结尾,方便识别。**
脚本的执行方式
指定路径去执行文件,文件需要有执行权限。
- 绝对路径。如:/root/hello.sh
- 相对路径。如:./hello.sh
[root@localhost ~]# chmod +x hello.sh
[root@localhost ~]# /root/hello.sh //使用绝对路径执行脚本
hello stars
[root@localhost ~]# ./hello.sh //使用相对路径执行脚本
hello stars
脚本错误调试
脚本错误类型:
- 命令错误: 命令错误不会影响接下来的命令,之后的命令会继续执行。
- 语法错误: 会导致后续的命令不执行。造成脚本中一部分命令已执行,一部分未执行。
- 逻辑错误: 执行后的效果不是自己想要的。需要自己去排查。
调试方法:
bash -n 脚本名称 //只检查语法错误,不真正执行脚本。定位的错误行可能不准确。
bash -x 脚本名称 //显示每个命令的执行过程,方便发现逻辑错误
重定向与管道符
标准输入与输出
当执行shell命令时,会默认打开3个文件,每个文件有对应的文件描述符来方便我们使用:
类型 | 设备文件 | 文件描述符 | 默认情况 | 对应文件句柄位置 |
---|---|---|---|---|
标准输入 | /dev/stdin | 0 | 从键盘获得输入 | /proc/self/fd/0 |
标准输出 | /dev/stdout | 1 | 输出到屏幕(即控制台) | /proc/self/fd/1 |
错误输出 | /dev/stderr | 2 | 输出到屏幕(即控制台) | /proc/self/fd/2 |
交互式硬件设备:
- 标准输入:从该设备接收用户输入数据。
- 标准输出:通过该设备想用户输出数据。
- 标准错误:通过该设备报告执行出错信息。
重定向
重定向的意思就是,不通过标准输出到默认屏幕上,而是输出到你指定的位置。
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定的文件读取数据,而不是从键盘输入 |
重定向输出 | > | 将输出结果保存到指定的文件(覆盖原有内容) |
重定向追加 | >> | 将输出结果追加到指定的文件尾部 |
标准错误输出 | 2> | 将错误信息保存到指定的文件(覆盖原有内容) |
标准错误追加 | 2>> | 将错误信息追加到指定的文件中 |
混合输出 | &> | 将错误输出、标准错误的内容保存到同一个文件中 |
- 命令 > 文件 2>&1,表示把错误输出2重定向给前面的标准输出1 (前面的1被省略了),即将错误输出和标准输出保存到同一个文件中。
管道符
管道符的作用是连接两个命令,将第一个命令的标准输出作为第二个命令的标准输入。 同一行命令中可以使用多个管道符。
linux下的管道符使用"竖杠"表示:| 。
格式:命令A | 命令B
如果管道符右边是一定需要执行对象的命令,则管道符号后面要有 xargs 命令来传递执行参数
[root@localhost ~]# ps aux | wc -l
178
[root@localhost ~]# echo "123123" | passwd --stdin 111
更改用户 111 的密码 。
passwd:所有的身份验证令牌已经成功更新。
变量
变量的作用:
用来存放系统和用户需要使用的特定参数(值)。
- 变量名:使用固定的名称,由系统预设或用户定义。
- 变量值:能够根据用户设置、系统环境的变化而变化。
变量类型
变量赋值:
变量名=变量值(name=value)
bash变量类型:
-
自定义变量:由用户自己定义、修改和使用。
-
特殊变量:
-
- 环境变量(全局变量):全局生效,在任何bash环境中都可以识别。:
-
- 只读变量:read only, 只可以读取不可以更改 。
-
- 位置变量: 通过命令行给脚本传递参数 。n(n是正整数),n(n是正整数),n(n是正整数),{10} 要加花括号。
-
-
预定义变量:用来保持脚本程序的执行信息。
-
$0 :当前脚本名称(如果是软链接,显示当前软链接文件名)。
-
$? :查看上一次命令的执行状态,返回0为正常,非0为错误。
-
$* :返回所有参数,当整体返回。
-
$@ :返回所有参数,当个体返回。
-
$# :获取当前shell命令行中参数的总个数。
-
变量的命名要求
只能使用数字、字母及下划线,且不能以数字开头
环境变量
使用env命令查看所有环境变量:
[root@localhost ~]# env //查看所有环境变量,这里只截取部分进行展示
XDG_SESSION_ID=1
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.72.100 55445 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
常用环境变量:
- $PATH 表示可执行文件的默认路径
- $USER 表示用户名称
- $HOME 表示用户的宿主目录
- $LANG 表示语言和字符集
- $PWD 表示当前所在工作目录
全局配置文件:
- /etc/profile,修改此文件会作用于所有用户。
用户独立的配置文件:
- ~/.bash_profile,修改这个文件只作用于当前用户。
示例:
将脚本文件所在目录添加进可执行文件的默认路径PATH中,则可直接通过文件名称执行该程序。
[root@localhost ~]# echo "echo '111'" > 111.sh //写一个脚本
[root@localhost ~]# cat 111.sh
echo '111'
[root@localhost ~]# chmod +x 111.sh //为脚本增加执行权限
[root@localhost ~]# vim /etc/profile //编辑全局配置文件
export PATH=$PATH:/root
[root@localhost ~]# source /etc/profile //刷新文件,使立即生效
[root@localhost ~]# echo $PATH //现在可直接使用文件名执行该脚本
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root
[root@localhost ~]# 111.sh
111
只读变量
我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。
只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。
[root@localhost ~]# name=222 //定义一个变量
[root@localhost ~]# readonly name //使用 readonly 修饰该变量 ,表明只读
[root@localhost ~]# echo $name
222
[root@localhost ~]# name=333 //无法重新赋值
-bash: name: 只读变量
[root@localhost ~]# unset name //无法使用unset删除
-bash: unset: name: 无法反设定: 只读 variable
预定义变量
预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。
可以直接使用这些变量,不能直接为这些变量赋值。
变量 | 作用 |
---|---|
$? | 表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。 |
$* | 表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词) |
$@ | 表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体) |
$# | 表示命令行中位置参数的总个数。 |
$0 | 表示当前脚本名称(如果是软链接,显示当前软链接文件名)。 |
$*
和$@
的区别:
- 不加双引号的话,
$*
和$@
都代表脚本后面跟的所有参数。- 加上双引号的话,"
$*
"会把所有参数当作一个整体去看待(此时参数数量为1),"$@
"会把脚本后面跟的每一个参数当作一个个体去看待。
Shell中的算术运算
运算表达式:
1. expr 变量1 运算符 变量2 [运算符 变量3]...
2. let 变量=算术表达式
3.((变量=算术表达式))
4. $((数值 运算符 数值))
5.$[数值 运算符 数值]
6. echo '浮点算术表达式' | bc
7.awk 'BEGIN {print 浮点算术表达式}'
运算符:
- 加法 +
- 减法 -
- 乘法 \ *
- 除法 /
- 取余 (取模)%
运算法则:
- 加法: num1 + num2
- 减法:num1 - num2
- 乘法:num1 \ * num2
- 整除:num1 / num2
- 取余(求模):num1 % num2 (求 num1 除以 num2 的余数)
运算演示
expr
expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串。
- 变量和运算符之间,要用空格隔开。
- 用反斜杠 \ 放在 shell 特定的字符前面;
- 对包含空格和其他特殊字符的字符串要用引号括起来
示例
[root@localhost ~]# expr 2 + 3
5
[root@localhost ~]# expr 3 - 2
1
[root@localhost ~]# expr 2 * 3 //乘号前要加反斜杠
expr: 语法错误
[root@localhost ~]# expr 2 \* 3
6
[root@localhost ~]# expr 4 / 2
2
[root@localhost ~]# expr 5 % 2 //5除以2取余数
1
[root@localhost ~]# expr 2 + 3 \* 2 //先乘除,再加减
8
let 和 (( ))
let var=算术表达式 和 ((var=算术表达式)) 效果等同。
两者都不返回结果,需要借助echo命令。
示例
[root@localhost ~]# let a=2+3
[root@localhost ~]# echo $a
5
[root@localhost ~]# ((b=2+3))
[root@localhost ~]# echo $b
5
$[ ]
和$(( ))
$[ ]
和 $(( ))
效果相同,且都支持对变量进行运算
[root@localhost ~]# echo $[2+3]
5
[root@localhost ~]# echo $[2*3]
6
[root@localhost ~]# echo $[4/2]
2
[root@localhost ~]# echo $[5%2]
1
[root@localhost ~]# echo $((3+2))
5
[root@localhost ~]# echo $((3*2))
6
awk命令
使用awk进行浮点数的运算,运算结果最多显示6个有效数字。
格式:awk "BEGIN{print 算术表达式}"
示例:
[root@localhost ~]# awk "BEGIN{print 6.5+3.4}"
9.9
[root@localhost ~]# awk "BEGIN{print 6.5-3.4}"
3.1
[root@localhost ~]# awk "BEGIN{print 6.5*3.4}"
22.1
[root@localhost ~]# awk "BEGIN{print 6.5/3.4}"
1.91176
[root@localhost ~]# awk "BEGIN{print (6.5-3.4)*7}" //混合运算
21.7
变量的自增和自减
简写表达式 | 等同于 |
---|---|
let i++ | i=$[$i+1] |
let i-- | i=$[$i-1] |
let i+=2 | i=$[$i+2] |
let i-=2 | i=$[$i-2] |
let i*=2 | i=$[$i*2] |
let i/=2 | i=$[$i/2] |
let i%=2 | i=$[$i%2] |
示例:
使用分号,可以在一行执行多个命令。
[root@localhost ~]# i=1
[root@localhost ~]# let i++ //i加1
[root@localhost ~]# echo $i
2
[root@localhost ~]# let i-- //i减1
[root@localhost ~]# echo $i
1
[root@localhost ~]# let i+=2 //i加2
[root@localhost ~]# echo $i
3
[root@localhost ~]# let i*=3;echo $i //i乘3
9
[root@localhost ~]# let i/=3;echo $i //i除以3
3
[root@localhost ~]# let i%=2;echo $i //i除以2后取余数
1