1. 输出命令
echo [选项] [输出内容]
选项:
• -e:支持反斜线控制的字符转换(具体参见表 1)
• -n:取消输出后行末的换行符号(内容输出后不换行)
2.shell脚本的结构(一般为三部分)
(1)声明脚本中的语言:
#!/bin/bash
(2)声明脚本的功能
以#开头的语句都是注释
(3)脚本的主体
3. 运行方式(运行前需注意该对该文件是否有执行的权限)
(1)使用路径直接运行
(2)通过bash调用脚本
bash 文件路径
4. 给命令设置别名
(1)显示系统中的命令别名
alias
(2)设置别名
alias 别名='原命令'
注意:设置别名后,原命令失效。且设置的别名在系统中必须是不存在的。
使用命令设置的别名且在系统未注销、重启前有效,需要持久生效,需要修改配置文件
(3)删除别名
unalias 原命令
5. 提取命令grep
在文件中提取和匹配符合条件的所有字符串行
grep [选项] "搜索内容" 文件名
选项:
• -A 数字:列出符合条件的行,并列出后续的 n 行;
• -B 数字:列出符合条件的行,并列出前面的 n 行;
• -c:统计找到的符合条件的字符串的次数;
• -i:忽略大小写;
• -n:输出行号;
• -v:反向査找;
• --color=auto:搜索出的关键字用颜色显示;
6. 管道符
用来连接多条命令,但下一条命令的执行依赖于上一条命令的正确输出
“命令1 | 命令2” 命令2只能处理命令1的正确输出结果
ls -a /etc/ | more
7. bash 通配符
通配符 作 用
- ? 匹配一个任意字符
- * 匹配 0 个或任意多个任意字符,也就是可以匹配任何内容
- [ ] 匹配中括号中任意一个字符。例如,[abc] 代表一定匹配一个字符,或者是 a,或者是 b,或者是 c
- [-] 匹配中括号中任意一个字符,- 代表一个范围。例如,[a-z] 代表匹配一个小写字母
- [^] 逻辑非,表示匹配不是中括号内的一个字符。例如,[^0-9] 代表匹配一个不是数字的字符
8. 单引号和双引号、反引号
单引号内的内容会当成字符串原样输出
双引号内的内容会考虑特殊含义,比如"$"、"\"
如果需要调用命令的输出或者将命令的输出赋值给变量,则需要反引号,反引号等价于$(命令),但为了避免反引号与单引号的混淆,常用的是 $(命令)代替反引号的使用
9. 圆括号与花括号
圆括号和花括号主要区别在于:
• () 执行一串命令时,需要重新开启一个子 Shell 来执行。
• {} 执行一串命令时,在当前 Shell 中执行。
• () 和 {} 都是把一串命令放田括号里面,并且命令之间用";"隔开。
• () 最后一条命令可以不用分号。
• {} 最后一条命令要用分号。
• {} 的第一条命令和左括号之间必须有一个空格。
• () 里的各命令不必和括号有空格。
• () 和 {} 中括号里面的某条命令的重定向只影响该命令,但括号外的重定向则会影响到括号里的所有命令。
其实在执行一串命令时,如果使用的是小括号,则这串命令所做的修改只在子 Shell 中生效,一旦命令执行结束,回到父 Shell 中,这个修改就会丟失;而如果使用的是大括号,则此串命令直接在父 Shell 中执行,命令执行结束后,修改依然会生效。
父shell和子shell互不干扰
10. 变量
(1)变量由字母、数字和下划线组成,不可以以数字开头
(2)在Bash中,变量的默认类型是字符串类型,如需进行数值运算,必须进行另外指定:
如:a=1+2
echo $a
1+2
(3)变量两边用“=”连接,等号两边不能有空格
(4)变量叠加:
两种格式:"$变量名"或${变量名}
(5)将命令的结果作为变量的值赋值给变量,需要使用$()(不推荐使用反引号)
(6)环境变量建议使用大写区分
11. 用户自定义变量
(1)查询已经设定的变量
set [选项]
选项:
• -u:如果设定此选项,则在调用未声明的变量时会报错(默认无任何提示);
• -x:如果设定此选项,则在命令执行之前会先把命令输出一次;
(2)变量删除
Unset 变量名
12. 环境变量和自定义变量
环境变量是全局变量,而自定义变量是局部变量。如果将环境变量写入配置文件,则环境变量可以永久存在,否则一旦shell终止,则环境变量也失效了
(1)环境变量的设置
Export age="18"
(2)环境变量的查询
Set 查询所有变量
Env 仅查询环境变量
(3)删除
Unset 变量名
13. bash位置参数变量用法
ls a.conf b.conf c.conf
// 则 $0 的值就是 ls 命令本身,$1,$2,$3 的值分别是 a.conf b.conf c.conf
位置参数变量 作 用
- $n
n 为数字,$0 代表命令本身,$1〜$9 代表第 1〜9 个参数,10 以上的参数需要用大括号包含, 如${10} - $*
这个变量代表命令行中所有的参数,把所有的参数看成一个整体 - $@
这个变量也代表命令行中所有的参数,不过 $@ 把每个参数区别对待 - $#
这个变量代表命令行中所有参数的个数
14. 预定义变量(已定义、不能更改的全局变量)
预定义变量 作 用
- $?
最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这 个变量的值为非 0 (具体是哪个数由命令自己来决定),则证明上一条命令执行错误 $$ 当前进程的进程号(PID)
- $!
后台运行的最后一个进程的进程号(PID)
15. 接收标准输入
Read 【选项】 【变量名】
选项:
• -p "提示信息":在等待read输入时,输出提示信息;
• -t 秒数:read命令会一直等待用户输入,使用此选项可以指定等待时间;
• -n 字符数:read命令只接收指定的字符数就会执行;
• -s: 隐藏输入的数据,适用于机密信息的输入;
read -n 1 -t 30 -p "Please select your gender[M/F]:" gender
提示"请选择性别"并等待30秒,把用户的输入保存到变量gender中
使用"-n 1"选项只接收一个输入字符就会执行(无须按回车键)
16. 数值运算
(1)使用declare声明变量类型
declare [+/-] [选项] 变量名
选项:
• -:给变量设定类型属性;
• +:取消变量的类型属性;
• -a:将变量声明为数组型;
• -i:将变量声明为整数型(integer);
• -r:将变量声明为只读变量。注意,一旦设置为只读变量,既不能修改变量的值,也不能删除变量,甚至不能通过 +r 取消只读属性;
• -x:将变量声明为环境变量;
• -p:显示指定变量的被声明的类型;
Name[0]="zhang san"
Name[1]="li ming"
Name[2]="xiao ming"
echo ${name}
// zhang san
echo ${name[*]}
// zhang san li ming xiao ming
(2)使用expr或let数值运算工具
Dd = $(expr $aa + $bb)
注意+号两边必须有空格,否则运算不执行
let ee = $aa+$bb (推荐的运算方法)
(3)$((运算式))或者$[运算式]
Gg=$[$aa+$bb]
17.常用运算符
优先级 运算符 说 明
-,+ 单目负、单目正
!,~ 逻辑非、按位取反或补码
*, /, % 乘、除、取模
+, - 加、减
<<, >> 按位左移、按位右移
<=, >=, <, > 小于或等于、大于或等于、小于、大于
== ,!= 等于、不等于
& 按位与
^ 按位异或
| 按位或
&& 逻辑与
II 逻辑或
=,+=,•=,*=,/=,%=,&=, |=, <<=, >>= 赋值、运算且赋值
18.错误处理
# 1. 开启变量不存在报错提示,默认变量不存在会忽略
set -u
# 2. 出现错误立刻退出
set -e
# 3. 如果是管道操作中出错,后面还会继续执行,所以 set -e 需要其他命令配合
set -eo pipefail
# 4. 查看每条命令执行结果,用于调试
set -x
# 5. 总结之前
建议在每个脚本开头都加上命令:set -euo pipefail
# 6. exit 钩子
function finish {
err=$?
if [[ $err == 1 ]]; then
echo '1'
fi
}
trap finish EXIT
这里的 trap 是一个内置命令,用来捕捉发送给程序的信号。它接受两个参数,第一个是处理信号的方式,第二个则是信号名。
# 7. 代码调试
如果只想调试代码而不执行,可以通过 sh -n *.sh
此外,我们还可以增强 set -x 指令的效果,上文说过被执行的指令前面会有 + 的前缀,它其实是是通过一个叫做 PS4 的环境变量来控制的。我们可以修改这个变量:
export PS4='+{$LINENO:${FUNCNAME[0]}} '
这里会显示代码所在行数(LINENO)和当前函数名(FUNCNAME[0])