Shell
基础知识
什么是 shell ?
在计算机科学中,shell 就是一个命令解释器
功能定位
shell 担任了操作系统和应用程序之间的中间人,它负责将应用程序的输入命令信息解释给操作系统,操作系统将指令集结果反馈给应用程序。
Category
linux: sh/csh/ksh/bash/…
Basic Operation
- 查看当前系统的 shell
1 | echo $SHELL |
- 查看当前系统环境支持的 shell
1 | cat /etc/shells |
- 更改默认的 shell
1 | chsh 用户名 -s newshell |
执行操作
shell脚本的执行通常可以采用以下几种方式:
1 | bash /path/to/script-name 或 /bin/bash /path/to/script-name (强烈推荐使用) |
Shell 变量
Category
变量 | 说明 |
---|---|
本地变量 | 变量仅仅在当前Shell终端有效 |
环境变量 | 也叫全局变量,变量在当前Shell终端其派生出来的任意子进程Shell终端中有效 |
内置变量 | Shell解析器内部的一些功能参数变量 |
本地变量
def: 变量仅仅在当前 Shell 终端有效
表现样式:
① 普通变量的定义方式有如下三种:
类型 | 样式 | 特点 | 备注 |
---|---|---|---|
无引号 | 变量名=变量值 | 变量值必须是一个整体,中间没有特殊字符 | “=” 前后不能有空格 |
单引号 | 变量名=’变量值’ | 原字符输出 | |
双引号 | 变量名=”变量值” | 变量值先解析,后整合 | 无 |
② 命令变量的定义方式有如下两种:
类型 | 样式 | 特点 | 备注 |
---|---|---|---|
反引号 | 变量名=‘ 命令’ | 反引号 | 不要用中文 |
小括号 | 变量名=$(命令) | $() | 无 |
环境变量
def:也叫全局变量,变量在当前Shell终端其派生出来的任意子进程Shell终端中有效
表现形式:
1 | export 变量=值 |
变量操作
查看:$变量名、“$变量名”、${变量名}、”${变量名}”
取消:unset 变量名
内置变量
属性含义:
符号 | 意义 |
---|---|
$0 | 获取当前脚本文件名 |
$n | 获取脚本的第n个参数值,样式:$1,${1} |
$# | 获取脚本参数的总个数 |
$? | 获取上一个指令的状态返回值(0为成功,非0为失败) |
条件表达式
语法格式
① 方式A:test 条件表达式
1 | # 注意:=号两边必须有空格 |
② 方式B:[ 条件表达式 ]
1 | # 注:=号两边必须有空格,并且方括号[、]与条件表达式之间也要至少有一个空格 |
条件成立,状态返回值是0;条件不成立,状态返回值是1。
表达样式
① 重点表达式:
逻辑 | 样式 | 特点 |
---|---|---|
&& | 命令1 && 命令2 | 只有1成功,2才执行 |
|| | 命令1 || 命令2 | 1和2只能执行一个 |
文件 | 样式 | 特点 |
---|---|---|
-f|d|s | -f file_name | 判断文件格式 |
-r|w|x | -x file_name | 判断文件权限 |
② 一般表达式:
数字 | 样式 | 特点 |
---|---|---|
eq | 数字1 eq 数字2 | 相等eq,不等ne |
gt | 数字1 gt 数字2 | gt大于,小于lt |
字符串 | 样式 | 特点 |
---|---|---|
== | != | str1 == str2 | 字符串内容是否一致 |
-z|n | -z str1 | z空,n不空 |
③ 计算表达式:
样式一:$[计算表达式]、a=$[变量名a+1]
样式二:$((计算表达式)) 或 a=$((变量名a+1))
样式三:let 变量名a=变量名a+1
注意:样式三的表达式必须是一个整体,中间不能出现空格等特殊字符
常见符号
① 信息传递
重定向符号 | 特点 |
---|---|
>|< | 表示将符号左侧|右侧的内容,以覆盖的方式输入到右侧|左侧文件 |
>>|<< | 表示将符号左侧|右侧的内容,以追加的方式输入到右侧|左侧文件的末尾行中 |
② 其他符号
后台展示符号 | 特点 |
---|---|
& | 就是将一个命令从前台转到后台执行 |
信息获取符号 | 特点 |
---|---|
1 | 表示正确输出的信息 |
2 | 表示错误输出的信息 |
2>&1 | 代表所有输出的信息,也可以简写为 “&>” |
常见命令
grep
global search regular expression and print out the line
文本搜索命令
命令格式
1 | grep [参数] [关键字] <文件名> |
参数详解:
参数 | 说明 |
---|---|
-c | 只输出匹配行的计数 |
-n | 显示匹配行及行号 |
-v | 显示不包含匹配文本的所有行 |
-E | 使用扩展正则匹配 |
sed
行文件编辑工具
命令格式:
1 | sed [参数] '<匹配条件> [动作]' [文件名] |
参数详解:
参数 | 说明 |
---|---|
参数为空 | 表示sed的操作效果,实际上不对文件进行编辑 |
-n | 默认只输出修改的内容,一般在动作中结合”p”使用 |
-i | 表示对文件进行编辑 |
注:mac版本的bash中使用 -i参数,必须在后面单独加个东西: -i ‘’
① 替换操作
命令格式:
1 | sed -i '行号s#原内容#替换后内容#列号' [文件名] |
注意:行号不写表示所有行,列号不写表示第1列,列号写成g,表示当前所有匹配的内容
awk
awk是一个功能非常强大的文档编辑工具,它不仅能以行为单位还能以列为单位处理文件。
命令格式:
1 | awk [参数] 'BEGIN{...}{动作}END{...}' [文件名] |
常见参数 | 说明 |
---|---|
-F | 指定列的分隔符 |
常见动作 | 说明 |
显示内容 | |
$0 | 显示当前行所有内容 |
$n | 显示当前行的第n列内容,如果存在多个$n,它们之间使用逗号(,)隔开 |
常见内置变量 | 说明 |
FILENAME | 当前输入文件的文件名,该变量是只读的 |
NF | 输出最后一列的内容 |
OFS | 输出格式的列分隔符,缺省是空格 |
FS | 输入文件的列分融符,缺省是连续的空格和Tab |
流程
if 语句
① 单分支if
特点:单条件,单结果
1 | if [ 条件 ] |
示例:
1 |
|
② 双分支if
特点:单条件,两结果
1 | if [ 条件 ] |
示例:
1 |
|
③ 多分支if
特点:n条件,n+1结果
1 | if [ 条件1 ] |
示例:
1 |
|
1.2 脚本案例
① 需求说明
要求脚本执行需要有参数,通过传入参数来实现不同的功能。
参数和功能详情如下:
参数 | 执行效果 |
---|---|
start | 服务启动中… |
stop | 服务关闭中… |
restart | 服务重启中… |
* | 脚本x.sh使用方式为: x.sh [ start|stop|restart ] |
② 脚本内容
1 |
|
2. case语句
我们发现多if语句使用的时候,代码量很多,而且整体看起来确实有那么一丁点乱,有没有办法更好的实现这种效 果呢?就是case语句。
2.1 语法格式
1 | case 变量名 in |
注:
① 首行关键字是case,末行关键字esac
② 选择项后面都有 )
③ 每个选择的执行语句结尾都有两个分号
2.2 语法示例
场景:在多if语句的基础上对脚本进行升级
需求:要求脚本执行需要有参数,通过传入参数来实现不同的功能
参数和功能详情如下:
参数 | 执行效果 |
---|---|
start | 服务启动中… |
stop | 服务关闭中… |
restart | 服务重启中… |
* | 脚本x.sh使用方式为: x.sh [ start|stop|restart ] |
脚本内容:
1 | # vi case.sh |
3. 循环语句
3.1 语法格式
for循环语句:
1 | for 条件 |
注:for语句,循环的数量有列表中元素个数来决定
简单实践:
1 |
|
while条件:
1 | while 条件 |
注:while语句,只要条件满足,就一直循环下去
简单实践:
1 |
|
util条件:
1 | until 条件 |
注:until语句,只要条件不满足,就一直循环下去
简单实践:
1 |
|
shell 函数
1. 函数定义
定义:函数就是将某些命令组合起来实现某一特殊功能的方式,是脚本编写中非常重要的一部分。
1.1 基本语法
简单函数格式:
1 | function 函数名(){ |
调用函数:函数名
传参函数格式:
1 | function 函数名(){ |
调用函数:函数名 参数
注:function 关键字可以省略
1.2 简单实践
简单函数定义和调用示例:
1 |
|
函数传参和函数体内调用参数示例:
1 |
|
2. 函数进阶
2.1 进阶样式
脚本传参和函数调用:
1 | # 脚本传参数 |
函数定义和调用:
1 | 函数名(){ |
函数定义和调用(生成用):
1 | 本地变量名="$1" |
2.2 进阶实践
脚本传参+函数调用:
1 |
|
脚本传参+函数调用(生产用):
1 | ! /bin/bash |