shell名词解释
- Kernel:Linux内核,主要是为了和硬件打交道
- shell: 是一个命令行解释器,接收用户命令/应用程序,然后调用操作系统内核。还是一个程序设计语言。
- 查看当前shell解释器和系统支持的shell解释器(我这里用的是centos7的镜像)
- shell的两大主流
- sh:
Bourne shell(sh),Solaris,hpux默认shell
Bourne again shell(bash),linux系统默认shell - bash
C shell(csh)
tc shell(tcsh)
- sh:
在Linux系统中,sh是bash的一个软链接(软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。)
#!声明
告诉系统其后路径所指定的程序是解释此脚本文件的shell程序,也就是指定shell解释器bash,路径是/bin/bash
shell脚本的执行
- 输入脚本的绝对路径或者相对路径
shell脚本文件的后缀是sh,这里使用vim创建并编辑内容后使用绝对路径执行helloword这个脚本没有权限,更改权限后使用绝对路径和相对路径都可以执行
- bash或sh+脚本的绝对路径或相对路径
注意:当脚本没有x(执行)权限时,root和文件所属用户通过这个方式可以正常执行
我这里已经将权限改成了不可执行,但是通过这个方式依然可以执行
- source+脚本的绝对路径或相对路径
查看正在执行的进程
ps -ef
三种执行方式的区别
第一种和第二种在用bash解释器执行脚本时,会先生成一个新的bash,在新的bash中执行
第三种就是在一个bash中执行的,在后面的局部变量中也会体现
shell变量
- 定义变量时,变量名不加$符号
- 命名只能用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,不能使用标点符号
- 不能使用bash里面的关键字(可以用help命令查看)
变量的类型
- 局部变量
局部变量在脚本或命令中定义,仅仅只在当前shell实例中有效,其他shell启动的程序不能访问局部变量 - 环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行
我在shell中定义了一个局部变量name,使用sh调用脚本,在脚本中打印这个局部变量没有显示,但是在脚本中定义的局部变量age却打印出来了,后面我使用export (作用是可以将当前进程的变量传递给子进程去使用)将局部变量name变成了环境变量,这时就可以打印了,造成这种情况的原因是因为前面sh调用脚本时,会先生成一个新的bash,在新的bash里面执行,此时我们在外面用命令定义的局部变量和bash执行的脚本不在同一个bash内,自然是打印不出来的,在当前shell是可以打印的。
[[email protected] scripts]# echo "${name}"
bfy
删除变量
unset
shell的字符串
字符串可以用单引号,也可以用双引号,也可以不用引号
注意:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
- 单引号字符串中不能出现单独一个单引号,可以成对出现,作为字符串的拼接使用
- 双引号里可以有变量
- 双引号里可以出现转义字符
这里的:<<!
!
是多行注释,使用时不局限于感叹号,EOF也可以,甚至是你自定义的字符
在双引号中使用换行符时,需要加上-e
字符串长度
这里的#是取字符串长度,因为定义变量的时候不能取标点符号,所以没有打印
1:4是指从1开始,去四个字符,字符串是从0开始的
shell数组
bash支持一维数组,不支持多维数组,并且没有限定数组的大小
数组的下标从0开始,格式上与Java数组有所不同
shell参数传递
执行shell脚本时,向脚本传递参数,脚本内获得参数的格式为:$n n代表一个数字
这里前9个参数都正常,从第10个开始就发生了变化,原因是$10被默认成了$1拼接上一个0,也就是110。解决办法是给10用大括号括起来。
shell运算符
运算符的分类
算术运算符
expr是一款表达式计算工具,使用它能完成表达式的求值操作
(1)\(((运算式))或\)[运算式]
(2)expr + , - , \*, /, % 加,减,乘,除,取余
注意:expr运算符间要有空格
代码:
关系运算符
= 字符串比较
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
布尔运算符
字符串运算符
(shell的echo指令用于字符串的输出,详情可以看我上一篇博客)
shell流程控制
if判断
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
elif[ 条件判断式 ]
then
程序
fi
注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格
read 读取控制台输入
read(选项)(参数)
选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
参数
变量:指定读取值的变量名
case语句
case $变量名 in
“值1”)
如果变量的值等于值1,则执行程序1
;;
“值2”)
如果变量的值等于值2,则执行程序2
;;
…省略其他分支…
)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
2)双分号“;;”表示命令序列结束,相当于java中的break。
3)最后的“)”表示默认模式,相当于java中的default。
for循环
for (( 初始值;循环控制条件;变量变化 ))
do
代码
done
while循环
while [ 条件判断式 ]
do
程序
done
break命令终止执行后面的所有循环
continue命令不会跳出所有循环,仅仅跳出当前循环
shell函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)