SHELL脚本
SHELL脚本
1 SHELL脚本基本知识
1.1 SHELL脚本的基本构成
打开文本编辑器,创建一个文本,在linux系统当中文本的后缀不影响
脚本的执行,但是为了使用区分,一般shell脚本文件都以.sh结尾。
第一个shell脚本编辑为:
#!/bin/bash
echo "Hello World !"
编辑完成后,保存该文件为test.sh,第一行的#!
是一个约定的标记,告诉系统该脚本用什么解释器执行。
1.2 脚本的执行
一般脚本的执行方式有两种:
- 路径+脚本名 (脚本文件对于属主应有执行权限)
- bash 脚本名 (直接使用解释器运行脚本,不需要权限)
[root@localhost data]# bash test.sh
Hello world
[root@localhost data]# ./test.sh
-bash: ./test.sh: Permission denied ##由于没权限导致无法执行
[root@localhost data]# chmod +x ./test.sh ##为文件加上执行权限
[root@localhost data]# ./test.sh
Hello world
如果希望直接用脚本名称执行脚本,则需要将该脚本放入到PATH中,PATH是系统变量,系统中运行的命令都是通过PATH路径找到的可执行程序,在PATH中的命令可以通过
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#用户自定义由管理员才能执行的命令/用户自定义由普通用户可以执行的命令/系统定义由管理员执行的命令
为方便管理各种命令,系统默认PATH,不同命令是放在不同路径下的
- /usr/local/sbin:用户自定义由管理员才能执行的命令
- /usr/local/bin:用户自定义由普通用户可以执行的命令
- /usr/sbin:系统定义由管理员执行的命令
- /usr/bin:系统定义由普通用户也可执行的命令
- /root/bin:root用户执行的命令
使用脚本名执行脚本需要将脚本放入以上几个目录中,或者将脚本所在目录加入到PATH中,推荐将需要的脚本使用软连接加入到上述目录中。
1.3 管道与重定向
1.3.1 管道
管道操作符:“|”: 将管道符号“|"左侧的命令输出的结果,作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道.
[root@localhost data]# cat /etc/passwd | wc -l ##统计passwd文件有多少行数据
42
如果一行容得下整个管道操作,那么将整个管道操作写在同一行。
否则,应该将整个管道操作分割成每行一个管段,管道操作的下一部分应该将管道符放在新行并且缩进2个空格。这适用于使用管道符’|’的合并命令链以及使用’||’和’&&’的逻辑运算链。
# All fits on one line
command1 | command2
# Long commands
command1 \
| command2 \
| command3 \
| command4
1.3.2 重定向
要了解重定向需要先了解标准输入输出的概念
-
标准输入:从设备接收用户输入数据
-
标准输出:通过设备箱用户输出设备
-
标准错误输出:通过该设备报告执行出错的信息
类型 | 设备文件 | 文件描述编号 | 默认设备 |
---|---|---|---|
标准输入 | /dev/stdin | 0 | 键盘 |
标准输出 | /dev/stdout | 1 | 显示器 |
标准错误输出 | /dev/stderr | 2 | 显示器 |
所谓的重定向是指通过重定向符,将对应的输入或输出内容放在一个文件当中。
常用的重定向符号有:
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
2 变量
变量对应的反面是常量,其代表的值会由于各种操作会导致变化,而常亮的值一般是固定的。
运行shell会同时存在三种变量。
- 1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
- 3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
2.1 变量名的定义规则
一般来说一个可以使用的变量名应该符合以下几点要求:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线 _。
- 不能使用标点符号。
- 不能使用bash里的关键字(可用help命令查看保留关键字)。
为了使得shell脚本可读性较高,在定义变量时最好满足下面几点:
- 变量名:使用小写字母,在需要时下划线分隔单词。如:
test_num
- 常量和环境变量名:全部大写,用下划线分隔,声明在文件的顶部。如:
PATH_TO_FILES
2.2 变量的赋值与使用
一般变量的赋值方式为:变量名=变量值
等号两边不能有空格,使用一个变量名在前面加入美元符号$
即可。
[root@localhost data]# vim bianlian.sh
################
#!/bin/bash
your_name=canyun
echo $your_name
################
[root@localhost data]# bash bianlian.sh
canyun
当变量值中有特殊符号的时候可以使用""
界定变量值的范围,但是双引号也会转译有特殊含义的符号。
使用单引号可以确保特殊符号不被转译。
但变量的变量值有特殊符号,或者变量需要与其他字符连接使用,仅通过在变量名前加入$
会发生歧义,这时候则需要在使用变量的时候,通过${变量名}
确保变量引用正确。
除了通过直接的"="赋值意外,可以通过read -p '提示信息' 变量名
的方式,将键盘输入信息赋予变量值。
[root@localhost data]# vim read.sh
########################
#!/bin/bash
read -p '请输入用户名:' user
echo ${user}
:wq
#######################
[root@localhost data]# bash read.sh
请输入用户名:canyun
canyun
/etc/profile /etc/bashrc /root/.bash_profile /root/.bashrc文件区别
系统每次启动都会自动执行 /etc/profile 文件里的命令,这个文件是对全局有效的(所有的shell环境和用户)
不同用户登录系统 会自动执行 自己家目录中的 ~/.bash_profile 文件中的命令,自动执行 ~/.bashrc
~/.bashrc 当前用户每切换一个shell环境都会自动执行,执行 /etc/bashrc
/etc/bashrc 针对所有用户的,用户每切换一个shell环境都会自动执行
如果有需要长久使用的变量,建议将需要使用的变量定义在/etc/profile.d/下,因为以上文件在运行的时候都会执行/etc/profile.d/下的脚本。通过定义/etc/profile.d/下的文件,更加便于管理系统环境。
此外:
通过
变量名=`命令`或$(命令)的方式可以将命令执行的结果作为变量值
2.3 特殊变量
2.3.1 环境变量
环境变量由Linux系统提前创建的一类变量,在设置自定义变量的时候,应当避免使用环境变量名。
查看环境变量名可以通过env
命令查询。
[root@localhost data]# env
XDG_SESSION_ID=157
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.186.2 49717 22
SELINUX_USE_CURRENT_RANGE=
OLDPWD=/
SSH_TTY=/dev/pts/0
USER=root
………………………………省略
2.3.2 位置变量
位置变量又称为位置参数,使用$1,$2,$3......$9表示,如果需要使用$10以上的内容则需要将10使用{}
包含起来,形式如${10}。位置变量的使用则在shell脚本后加入指定参数即可。如:
[root@localhost data]# vim local.sh
####################
#!/bin/bash
echo "用户名为$1"
echo "年龄$2"
####################
[root@localhost data]# bash local.sh canyun 25
用户名为canyun
年龄25
2.3.3 预定义变量
预定义变量是Bash程序定义好的一类特殊变量,用户只能使用预定义变量,不能穿件预定义变量。
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。 |
$? | 上个命令的退出状态,或函数的返回值,返回值(0-255,超过部分 %256 取余) |
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
$*与$@的区别:
$* 不加双引号的话 $和$@都代表脚本后面跟的所有参数,加上双引号 "$" 会把所有参数当做一个整体的参数(此时参数数量为1)去看待
$@ 加上双引号 "$@" 会把脚本后面跟的每一个参数当做一个个体去看待
"one two three four five" $* 参数数量为 1
"one" "two" "three" "four" "five" $@ 参数数量为 5
2.4 变量的运算
SHELL脚本中默认只支持整数运算
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
运算方式有以下几种
- i=$(expr 12 * 5)
i=$((12*5))
i=$[12*5]
let i=12*5
同时也支持自加和自减运算
- let i++ i=$[$i+1]
let i-- i=$[$i-1]
let i+=2 i=$[$i+2]
let i/=2 i=$[$i/2]
a -ge 85 && a -le 100