Shell基础学习笔记
Shell是一个命令的解释器,它可以接收应用程序或用户命令,然后调用系统内核。shell也是一个功能强大的脚本语言,易编写,易调试、灵活性强。
Linux提供的Shell解析器如下,写在/etc/shells中
| 1 |  | 
- bash和sh即为一个链接的关系,sh -> bash
- CentOS默认的解析器是bash
基础语法
入门知识
- 脚本以 - #!/bin/bash开头,用以指定解析器
- 脚本的常用执行方式 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- # 方法1
 # 使用bash或者sh的相对路径或者绝对路径,不需要赋予脚本+x的权限
 bash ./helloworld.sh
 # 方法2
 # 直接输入脚本的绝对路径或者相对路径,需要赋予脚本+x的权限
 chmod +x helloworld.sh
 # 如果直接在脚本文件所在目录里调用,则相对路径格式是./
 ./helloworld.sh
 # 方法3
 # 在脚本的路径前加上. 或者 source- 方法1和方法2,是在当前Shell中打开一个子Shell来执行脚本内容,当脚本内容结束,则子Shell关闭,回到父Shell中
- 方法3,可以使得脚本内容在当前Shell里执行,无需打开子Shell
- 是否打开子Shell的区别就在于环境变量的继承关系,例如子Shell中设置的当前变量,父Shell是不可见的
 
变量
变量包括系统预定义变量、自定义变量和特殊变量;根据变量的作用范围,可以分为全局的变量和局部的变量。全局指的是对所有的子Shell有效,局部指的是只对自己的Shell有效,对子Shell无效
系统预定义变量
常用的系统变量有:$HOME $PWD $SHELL $USER,可以使用echo查看对应的系统变量的值。set命令则可以显示当前Shell中的所有变量;env命令则可以显示当前系统的所有全局变量
自定义变量
基本语法如下:
| 1 |  | 
- 变量定义规则基本同其他的编程语言
- 等号两侧不能有空格
- 在bash中,变量的默认类型都是字符串类型,无法直接进行数值运算
- 如果想要进行运算,需要使用到后续的运算符
 
- 变量的值如果有空格,需要使用引号扩起来
- 默认是局部变量,可以使用export 变量名将其提升为全局变量
- 对于全局变量的更改,只在当前的Shell中有效,无法影响到父Shell的变量值
echo中引号的区别:
单引号:直接原封不动地输出引号中的内容,比较傻
双引号:会解析其中的使用了
$解析的变量,比较聪明
特殊变量
主要用于脚本的输入参数的获取,处理等
- $n:表示脚本的第几个参数- 其中n表示数字,如果数字超过9,则需要使用大括号进行包裹,如${10}
- $0,表示该脚本的名称,根据调用方式的不同而不同
 
- 其中n表示数字,如果数字超过9,则需要使用大括号进行包裹,如
- $#:获取所有的输入参数个数,常用于循环中的判断,判断参数的个数是否正确
- $*:表示命令行中所有参数,将所有参数看作一个整体
- $@:表示命令行中的所有参数,但是不是一个整体,可以看作是一个参数集合
- $?:相当于返回值,为最后一次执行命令的返回状态- 如果值为0,证明上一个命令正确执行;非0则表示不正确
 
运算符
前面提到了变量默认都是字符串类型,计算需要使用运算符。
运算符的基本语法为$((运算式))或者$[运算式]
如果需要将一个命令的返回结果当作值进行赋值,则使用反引号或者$()
| 1 |  | 
条件判断
基本语法:
- test 条件表达式
- [ 条件表达式 ],注意这里条件表达式的前后需要有空格
| 1 |  | 
执行完命令之后,不会自动打印结果,需要使用$?来获取判断的返回值,如果返回值是0,则条件表达式的值为true,否则为false。并且注意这里的运算符两边也要有空格。以及条件非空即为true,即[ $B ]为true,[ ]为false
常用判断条件:
- 字符串之间的比较
| 1 |  | 
- 整数之间的比较
| 1 |  | 
- 文件权限判断
| 1 |  | 
- 文件类型判断
| 1 |  | 
多条件判断:与&&和或||
| 1 |  | 
如果在一个中括号中进行多条件判断,可以使用-a或者-o(and
or)
| 1 |  | 
流程控制
if判断
| 1 |  | 
- 分号;表示一行中可以输入多个命令,使用分号隔开
- if后面要有空格
- 条件表达式和中括号之间需要有空格
case语句
| 1 |  | 
- case行尾必须为单词in,每个模式匹配必须以)结束
- 双分号;;表示命令序列结束,相当于java中的break
- 最后的*)表示默认模式,相当于java中的default
for循环
| 1 |  | 
| 1 |  | 
- 前面说到的$*和$@,如果使用双引号包含的时候,会进行不同的变化,前者作为一个整体,后者展开成为一个序列
- 如果没有双引号包裹的话,则没有区别
| 1 |  | 
while循环
| 1 |  | 
read读取控制台输入
基本语法:read [选项] [参数]
- 选项:
- -p:指定读取值时的提示符
- -t:指定读取值时等待的时间(单位为秒),如果不加-t则一直等待
 
- 参数:
- 变量:指定存放值的变量名
 
| 1 |  | 
函数
函数又可以分成系统函数和自定义函数。
这里举几个系统函数的例子
| 1 |  | 
- basename命令会删掉所有的前缀,包括最后一个/字符,然后将字符串显示出来
- 可以理解为取出路径中的文件名称
- suffix为后缀,如果被指定了,会将其中的suffix删除
| 1 |  | 
- 从给定给定包含绝对路径的文件名中去除文件名,返回目录的部分
我们也可以自定义函数实现,基本语法如下
| 1 |  | 
- 上面的方括号表示可以省略
- 函数的形参不需要定义,可以使用$n获取,与脚本类似;也可以有函数返回值,使用$?获取
- 因为shell脚本是逐行运行的,所以在调用函数之前需要声明
- 如果不写return,会返回最后一条命令的运行结果。并且return后跟数值n,范围为0-255
- 一种方法可以绕过返回值的限制,在函数中进行echo,然后用命令替换$()进行捕获
| 1 |  | 
应用举例
helloworld.sh
| 1 |  | 
acc.sh
| 1 |  | 
printHa.sh
| 1 |  |