Shell 入门与实践
什么是 Shell
Shell 首先是 UNIX/Linux 下的脚本编程语言,它是解释执行的,无需提前编译。Shell 的语法细节和你熟悉的大部分编程语言都不太一样,需要重点学习。
Shell 同时也是一个程序,它的一端连接着 UNIX/Linux 内核,另一端连接着用户和其它应用程序;换句话说,Shell 是用户和应用程序与内核沟通的桥梁。
Shell 脚本功能非常强大,完全能够胜任 Linux 的日常管理工作,如文本或字符串检索、文件的查找或创建、大规模软件的自动部署、更改系统设置、监控服务器性能、发送报警邮件、抓取网页内容、压缩文件等。
Shell 虽然没有 C/C++、Python、Java、C# 等编程语言强大,但也支持了基本的编程元素,例如:变量、数组、字符串、注释、加减乘除等概念。if...else 选择结构,for、while、until 循环等流程控制语句。为了方便模块化开发,Shell 也支持自定义函数。
Shell 是一种脚本语言,那么,就必须有解释器来执行这些脚本,常见的脚本解释器有:bash(Linux 标准默认的 shell,由 Brian Fox 和 Chet Ramey 共同完成,是BourneAgain Shell 的缩写,内部命令一共有 40 个),sh(Unix 标准默认的 shell,由 Steve Bourne 开发,是 Bourne Shell 的缩写)。另外还有 ash、 bsh、tcsh、csh、 ksh 等。
Shell 有两大基本类:GUI Shel(图形界面 Shell)、CLI Shell(命令行界面 Shell)。
Shell 是运维人员必须掌握的技能。
Shell 基本语法
任何编程语言的学习始于 hello world
#!/bin/bash
echo “hello world!”;
第一行指定解释器,第二行打印 hello world!
执行 shell 脚本三种方式:
1) 直接用 bash 解释器执行。
bash test.sh
2) 添加可执行权限。
chmod +x test.sh
./test.sh
这种方式默认根据第一行指定的解释器处理,如果没写以当前默认 Shell 解释器执行。
3) source 命令执行,以当前默认 Shell 解释器执行。
# source test.sh
Hello world!
系统变量
在命令行提示符直接执行 env, set 查看系统或环境变量。env 显示用户环境变量,set 显示 Shell 预先定义好的变量以及用户变量。可以通过 export 导出成用户变量。如下是 Shell 脚本常用的系统变量:
普通变量和临时环境变量
普通变量定义: VAR = value
临时环境变量定义:export VAR = value
变量引用:$VAR
Shell 进程的环境变量作用域是Shell进程,当 export 导入到系统变量时,则作用域是 Shell 进程及其子进程。
位置变量
位置变量:函数或脚本后跟的第 n 个参数 $1~$n(第十个参数开始要用花括号调用)
eg:
#vi test2.sh
#!/bin/bash
echo “1: $1, 2: $2, 3: $3”
#bash test2.sh a b c
特殊变量
变量引用
自定义变量引用
Shell 中所有变量引用使用 $ 符号,后跟变量名。以下这些情况会影响正常引用,需要使用 ${VAR}:
1:个别特殊字符,2:跟其他字符串紧挨着
例如:
# var = 123
# var += 456
# echo $var
123456
# 无法正常打印 var
# echo $var_
# 正确写法
# echo ${var}_
# echo $var456 打印空白,正确写法:echo ${var}456
双引号和单引号
在变量赋值时,如果值有空格,Shell 会把空格后面的字符串解释为命令:
# var = 123
会报 command not found
单引号是告诉 Shell 忽略特殊字符,二双引号则解释特殊符号原有的意义,比如 $,!。
Shell 注释很简单,只要在每行前面加上 # 号即可。
Shell 变量作用域
Shell 变量的作用域可以分为三种:
有的变量可以在当前 Shell 会话中使用,这叫做全局变量(global variable)
全局变量的作用范围是当前的 Shell 会话而不是当前的 Shell 脚本文件,它们是不同的概念。打开一个 Shell 窗口就创建了一个 Shell 会话,打开多个 Shell 窗口就创建了多个 Shell 会话,每个 Shell 会话都是独立的进程,拥有不同的进程 ID。在一个 Shell 会话中,可以执行多个 Shell 脚本文件,此时全局变量在这些脚本文件中都有效。
有的变量只能在函数内部使用,这叫做局部变量(local variable)
变量的作用域仅限于函数内部,需要在定义时加上local命令,此时该变量就成了局部变量。
而有的变量还可以在其它 Shell 中使用,这叫做环境变量(environment variable)
全局变量只在当前 Shell 会话中有效,如果使用 export 命令将它导出,那么它就在所有的子 Shell 中也有效了,这称为“环境变量”。
字符串处理
获取字符串长度:${#var}
字符串切片:${parameter:offset:length},${parameter:offset}
替换字符串:${parameter/pattern/string}
字符串截取:${parameter#word},${parameter##word},${parameter%word},${parameter%%word}
变量状态赋值:${var:-string},${var:+string},${var:=string},${var:?string}
字符串颜色设置:\033[1;31;40m #1 是显示方式,可选。31是字体颜色。40m是字体背景颜色。 \033[0m # 取消颜色设置。
Shell 表达式与运算符
Shell 括号用途总结
Shell 流程控制
常用的流程控制语句主要有以下几种:
if 语句
for 语句
while 语句
break 和 continue 语句
case 语句
select 语句
if 语句
格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi
1.单分支
if 条件表达式; then
命令
fi
2.双分支
if 条件表达式; then
命令
else
命令
fi
3.多分支
if 条件表达式; then
命令
elif 条件表达式; then
命令
else
命令
fi
for 语句
格式: for name [ [ in [ word ... ] ]; ] do list; done
for 变量名 in 取值列表; do
命令
done
还有一种 C 语言风格的语法,常用于计数、打印数字序列:
for (( expr1; expr2; expr3 )); do list; done
while 语句
格式:while list; do list; done
while 条件表达式; do
命令
done
break 和 continue 语句
break 是终止循环。
continue 是跳出当前循环。
continue 与 break 语句只能在循环语句中使用。
case 语句
case 语句一般用于选择性来执行对应部分块命令。
格式: case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac
case 模式名 in
格式1)
命令
;;
格式2)
命令
;;
*)
不符合以上模式执行的命令
esac
每个模式必须以右括号结束,命令结尾以双分号结束。
另外,模式也支持正则,匹配哪个破会就执行哪个模式。
模式支持的正则有:*, ?, [], [.-.], |
select 语句
select 是一个类似于 for 循环的语句。
格式:select name [ in word ]; do list; done
select 变量 in 选项 1 选项 2; do
break
done
Shell 函数与数组
函数
func() {
command
}
function 关键字可写,也可不写。
注意:Shell 函数很简单,函数名后跟双括号,再跟双大括号。直接通过函数名调用,不需要加小括号。
数组
数组是相同类型的元素按一定顺序排列的集合。
格式:array = (元素 1 元素 2 元素 3 ...)
用小括号初始化数组,元素之间用空格分隔。
定义方法 1:初始化数组
array = (a b c)
定义方法 2:新建数组并添加元素
array[下标]=元素
定义方法 3:将命令输出作为数组元素
array = ($(command))
数组操作:
正则表达式
正则表达式在每种语言中都会有,功能就是匹配符合你预期要求的字符串。
Shell 正则表达式分为两种:
基础正则表达式:BRE
扩展正则表达式:ERE,扩展的表达式有+、?、|和()
下面是一些常用的正则表达式符号,我们先拿 grep 工具举例说明。
在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具:
Shell 文本处理三剑客
grep
过滤来自一个文件或标准输入匹配模式内容。除了 grep 外,还有 egrep、fgrep。egrep 是 grep 的扩展,相当于 grep -E。fgrep 相当于 grep -f,用的少。
Usage: grep [OPTION]... PATTERN [FILE]...
sed
流编辑器,过滤和替换文本。
工作原理:sed 命令将当前处理的行读入模式空间进行处理,处理完吧结果输出,并清空模式空间。然后再将下一行读入模式空间进行处理输出,以此类推,直到最后一行。还有一个空间叫保持空间,又称暂存空间,可以暂时存放一些处理的数据,但不能直接输出,只能放到模式空间输出。这两个空间其实就是在内存中初始化的一个内存区域,存放正在处理的数据和临时存放的数据。
Usage:
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
sed [选项] '地址 命令' file
awk
awk 是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等。在 linux 系统下默认 awk 是 gawk,它是 awk 的 GNU 版本。
基本命令语法:awk option 'pattern {action}' file
总结
Shell 的优势
简单的输入输出模式、管道、通用性强、程序重用。
Shell 的用途
启停程序(调度)、查看系统状态、日志分析、数据处理、上传下载、监控及调度、调试测试。
Shell 不适合干什么
计算密集型任务、高性能服务场景、复杂数据结构。
入门练习脚本:
https://github.com/shixiwanzi/shell-learning
End
致力于为更多的程序员提供更好的技术