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 |
|