一、简介
1.1、 什么是shell
- Shell是用C语言编写的程序
- Shell是一种应用程序,该应用程序提供一个界面,用户通过界面访问linux
1.2、Shell脚本
Shell 脚本,是Shell编写的脚本程序,后缀名为 .sh
1.3、Shell环境
Shell 常见的编辑器种类如下:
sh
- 即Bourne Shell,sh 是 Unix标准默认的shellbash
- 即Bourne Again Shell。bash是Linux标准默认的shellzsh
- 功能强大的 shell 与脚本语言
shell脚本定脚本解释器
- 指定sh 解释器,unix标准默认#!/bin/sh#!/bin/bash
- 指定bash解释器,linux标准默认
1.4、模式
Shell 有交互和非交互模式
交互模式
代码语言:txt复制shell交互模式为用户在界面执行命令行
例如:
➜ ~ ls -l
非交互模式
代码语言:txt复制shell的非交互模式为执行shell脚本
例如:
➜ bat git:(master) sh andreserver_lanproxy_login.sh
二、基本语法
2.1、解释器
在shell脚本中,#!
描述该shell脚本所使用的解释器,详见1.3 例如:
#!/bin/sh 或 #!/bin/bash
2.2、注释
shell脚本的语法中,注释方式有以下两种
- 单行注释,用
#
开头,例如# 这是一行shell注释
- 多行注释,用
:<<EOF
开头,EOF
结束,例如
代码语言:txt复制:<<EOF
代码语言:txt复制这是多行shell注释
代码语言:txt复制EOF
代码语言:txt复制
2.3、字符串输出
echo用于字符串输出
代码语言:txt复制echo "hello,world"
printf用于格式化输出
代码语言:txt复制printf "$d %s" 1 "hello"
# output: 1 hello
2.4、双引号""、单引号''、反引号
<font color=blue>双引号""、单引号''、反引号 的区别</font>
双引号"": 可识别转义和变量,对变量和转义进行扩展平铺
单引号'': 不识别转义和变量,原样输出
反引号``: 用于执行命令,作用和$(命令)相似
三、变量
3.1、变量命名
- 只能使用英文字母、数字、下划线,首字母不能是数字
- 赋值
=
前后不能有空格 - 不能使用bash的关键字
3.2、声明变量
<font color=red> 访问变量的语法为 ${var} 和 $var,大括号是用来识别变量边界,可加可不加,建议加上</font>
例如:
代码语言:txt复制name="andrekzwu"
echo "${name}"
# output: andrekzwu
3.3、只读变量
设置只读变量语法为: readonly 变量
例如:
代码语言:txt复制name="andrekzwu"
echo ${name}
readonly name
# name="wukezheng" 执行会报错,例如:test.sh: line 6: name: readonly variable
3.4、删除变量
删除变量的语法为:unset 变量
例如:
代码语言:txt复制name="wukezheng"
echo "${name}"
# output: wukezheng
unset name # 删除了变量
3.5、变量类型
- 局部变量,局部变量只在某个脚本内部有效,不能被其他程序和脚本访问
- 环境变量,环境变量是当前shell会话内的所有程序和脚本都可访问的变量,使用
export
关键字可以设置为环境变量
常见环境变量
- $HOME,用户目录
- $PATH,系统路径,用分号分隔的目录列表,shell会从这些目录中找到路径
- $PWD,当前工作目录
- $UID,当前用户ID
四、运算符
<font color=red>执行命令时,命名、变量、符号之间需要空格隔离</font>
例如,执行整数运算:
代码语言:txt复制expr $x $y
例如执行if命令
代码语言:txt复制if [ $x -ne $y ]; then
echo "${x}不等于${y}"
fi
4.1、算术运算符
算术运算符,例如 变量x 为10,变量y为20:
expr 对整数进行运算
运算符 | 说明 | 举例 |
---|---|---|
加法 |
| |
减法 |
| |
乘法 |
| |
/ | 除法 |
|
% | 取余 |
|
= | 赋值 |
|
== | 相等,比较两个数字,相等返回true |
|
!= | 不相等,比较两个数字,不同则返回true |
|
4.2、关系运算符
<font color=blue>关系运算符只支持数字,不支持字符串,除非字符串的值是数字</font>
关系运算符,例如 变量 x为10,变量y为20
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回true |
|
-ne | 检测两个数是否不相等,不相等返回true |
|
-gt | 检测左边的数是否大于右边的数,如果是,返回true |
|
-lt | 检测左边的数是否小于右边的数,如果是,返回true |
|
-ge | 检测左边的数是否大于等于右边的数,如果是,返回true |
|
-le | 检测左边的数是否小于等于右边的数,如果是,返回true |
|
4.3、布尔运算符
布尔运算符,例如 变量 x为10,变量y为20
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为true,则返回false,反之则返回true |
|
-o | 或运算,有一个表达式为true,则返回true |
|
-a | 与运算,两个表达式都为true才返回true |
|
4.4、逻辑运算符
逻辑运算符,例如 变量 x为10,变量y为20
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑与 |
|
|| | 逻辑或 |
|
4.5、字符串运算符
字符串运算符,例如变量 x为"abc",y为"ABC"
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回true |
|
!= | 检测两个字符串是否相等,不相等返回true |
|
-z | 检测字符串长度是否为0 ,为0返回true |
|
-n | 检测字符串长度是否为0,不为0返回true |
|
str | 检测字符串是否为空,不为空则返回true |
|
4.6、文件测试运算符
运算符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,返回true |
|
-d file | 检测文件是否是目录,如果是,返回true |
|
-f file | 检测文件是否是普通文件,如果是,返回true |
|
-r file | 检测文件是否可读,如果是,返回true |
|
-w file | 检测文件是否可写,如果是,返回true |
|
-x file | 检测文件是否可执行,如果是,返回true |
|
-s file | 检测文件是否为空(文件大小是否大于0),不为空,则返回true |
|
-e file | 检测问价(包括目录)是否存在,如果是,则返回true |
|
五、控制语句
5.1、条件语句
格式 :
代码语言:txt复制# if语句
if [ $x -eq $y ]; then
echo "$x 等于 $y"
fi
# if else 语句
if [ $x -eq $y ]; then
echo "$x 等于 $y"
else
echo "$x 不等于 $y"
fi
# if elif 语句
if [ $x -eq $y ]; then
echo "$x 等于 $y"
elif [ $x -ne $y ]; then
echo "$x 不等于 $y"
fi
5.2、循环语句
格式:for 循环
代码语言:txt复制# for 循环1
for arg in elem1 elem2 .....elemN
do
### 语句
done
# 例如遍历文件
for file in $(ls);do
echo $file
done
# for 循环2
for (( i = 0; i < 10; i )); do
echo $i
done
六、函数
函数定义语法:
代码语言:txt复制[ function ] funname [()] {
action;
[return int;]
}
- 函数定义时,
function
关键字可有可无。 - 函数返回值 - return 返回函数返回值,返回值类型只能为整数(0-255)。如果不加 return 语句,shell 默认将以最后一条命令的运行结果,作为函数返回值。
- 函数返回值在调用该函数后通过
$?
来获得。 - 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至 shell 解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
七、参数/流
位置参数变量表:
变量 | 描述 |
---|---|
| 脚本名 |
| 第1个到第9个参数列表 |
| 第10个到第N个参数列表 |
| 不包括$0在内的所有参数 |
| 不包括$0在内的参数个数 |
| 函数名称(仅在函数内部有值) |
函数处理参数:
另外,还有几个特殊字符用来处理参数:
参数处理 | 说明 |
---|---|
| 返回参数个数 |
| 返回所有参数 |
| 脚本运行的当前进程ID |
| 后台运行的最后一个进程的ID |
| 函数返回值 |
输出、输出流:
代码 | 描述符 | 描述 |
---|---|---|
0 | stdin | 标准输入 |
1 | stdout | 标准输出 |
2 | stderr | 标准错误输出 |
重定向:
operator | desc |
---|---|
重定向输出,以覆盖的方式重定向 | |
&> | 重定向输出和错误输出 |
&>> | 以追加的形式重定向输出和错误输出 |
< | 重定向输入,以覆盖的方式重定向 |
/dev/null文件:
/dev/null
- 接受并丢弃所有输入; 不产生输出(总是在读取时返回文件结束指示
$ command > /dev/null
如果希望屏蔽 stdout 和 stderr,可以这样写:
代码语言:txt复制$ command > /dev/null 2>&1
若命令执行错误,标准错误输出也给出打印,若想要将标准错误输出不在屏幕输出,则需要使用重定向技术,将标准错误输出重定向到标准输出2>&1
2>&1
<font color=red>&是用来告诉系统,1这里指的是标准输出,而不是文件。</font>
参考文档:https://juejin.cn/post/6844903784158593038#heading-47
参考文档:https://blog.csdn.net/c_base_jin/article/details/87894722