何为shell?
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
shell脚本通俗的来讲:
命令解释器 :“翻译官” 介于系统内核与用户之间,负责解释命令行要执行的命令按顺序保存到一个文本文件 给该文件可执行权限 ,可结合各种shell控制语句以完成更复杂的操作
应用场景: 重复性操作, 交互性任务, 批量事务处理, 服务运行状态监控, 定时任务执行。
作用: 自动化运维, 批量化重复操作可以编写脚本结合计划任务自动周期运行, 减轻管理员工作量, 提供处理文本文件的速度, 避免配置出错 。
linux 中常见的shell
-
bash:基于GUN的框架下发展的shell
-
csh:类似C语言的shell
-
tcsh:整合了csh 提供了更多功能
-
sh:已经被bash替换
-
nologin:使用户无法登陆
-
bash(/bin/bash)是目前大多数 Linux 版本采用的默认 shell。
bash特性:
- 支持快捷键:比如 ctrl+c 强制终止进程 、 ctrl+l 清屏 、Tab补齐 等等。
- 支持查看历史命令(history)
- 支持别名(alias)
- 标准输入和标准输出的重定向
- 管道符
- 文件名通配机制
- 支持命令hash
- 支持变量
shell脚本的基本结构规范
脚本名称规范:文件都以.sh结尾
第一行:脚本申明,调用使用的语言,默认以/bin/bash执行
第二行:注释信息: 以#开头的语句表示注释信息,被注释的语句在运行脚本中不会被执行
第三行:可执行代码内容
范例:
#!/bin/bash
# Filename: hello.sh
echo "hello world"
脚本的执行方式
使用绝对路径或相对路径,一定要给文件加上执行权限
绝对路径:
chmod +x hello.sh
/roo/hello.sh
相对路径:
chmod +x hello.sh
./hello.sh
指定shell解释器去执行,可以不加执行权限
source 脚本名 或 . 脚本名 //不会启动子shell环境,在当前环境执行
bash hello.sh
source hello.sh
. hello.sh
注意:
- 执行脚本时的shell环境:
- source和 . 执行脚本时,会在当前shell环境中执行脚本。
- bash、绝对路径、相对路径 执行脚本时,会创建一个子shell环境,并在这个子shell环境中执行脚本。
-
不建议使用source来执行脚本,可能会影响一些资源配置。
-
脚本中的空白行会被解释器忽略。
-
脚本中,除了shebang,余下所有以#开头的行,都回被视作注释行而被忽略。此即为注释行。
重定向与管道符
由于Shell脚本“批量处理”的特殊性,其大部分操作过程位于后台,不需要用户进行干预,因此要学会提取、过滤执行信息变得十分重要,所以我们需要重定向和管道。
| 标准输入 | /dev/stdin | 0 | 从键盘获得输入 | /proc/self/fd/0 |
|---|---|---|---|---|
| 标准输出 | /dev/stdout | 1 | 输出到屏幕(即控制台) | /proc/self/fd/1 |
| 错误输出 | /dev/stderr | 2 | 输出到屏幕(即控制台) | /proc/self/fd/2 |
重定向:不输出到屏幕,输出到指定位置
| 命令 < 文件 | 从指定的文件读取文件,而不是从键盘输入 |
|---|
| 符号 | 作用 |
|---|---|
| 命令 > 文件 | 将标准输出结果保存到指定的文件中(覆盖原有内容) |
| 命令 >> 文件 | 将标准输出结果追加到指定的文件尾部 |
| 命令 2> 文件 | 将错误输出信息保存到指定文件中(覆盖原有内容) |
| 命令 2>> 文件 | 将错误输出信息追加到指定文件尾部 |
| 命令 > 文件 2>&1 | 混合输出,将标准输出与错误输出保存到文同一个文件中 |
| 命令 &> 文件 | 同上 |
| 命令 >& 文件 | 同上 |
- &表示混合,&> 和 >& 都表示将标准输出和错误输出重定向到同一个文件。
举例: 给用户修改密码(记得关闭防火墙)
useradd zjl
echo "123" > 1.txt
passwd --stdin zjl < 1.txt
将123重定向追加输出到bbb当中
echo "123" > bbb.txt
管道符
管道符的作用是连接两个命令,将第一个命令的标准输出作为第二个命令的标准输入。 同一行命令中可以使用多个管道符xx| 管道符右边的命令如果需要执行对象,则需要在命令前添加xargs。
ps aux | wc -l | xargs cp 1.txt
变量:-
- 变量必要性:linux具有多人多任务的环境特点,每个人登录系统都能取得一个bash shell
- 变量定义:以一组文字或符号来替换一些设置或一串保留的数据
- 变量分类:环境变量(需要读入到系统中,也称为全局变量,所以名称均以大写字符来表示,如PATH、HOME)、自定义变量(也称为局部变量)
- linux 一切皆文件,命令也是文件,环境变量也是文件,通过修改文件实现对环境的配置
变量的作用:
用来存放系统和用户需要使用的特定参数(值)。
- 变量名:使用固定的名称,由系统预设或用户定义。
- 变量值:能够根据用户设置、系统环境的变化而变化。
定义变量: 变量名=变量值
我们也可以使用 read 变量名
引用变量: ¥变量名或 ${变量名}
查看变量:
- echo $变量名:查看单个变量
- set:查看所有变量,包括局部变量和环境变量
取消变量: unset 变量名
变量类型
环境变量:全局生效,在任何bash环境中都可以识别。
局部变量:生效范围为当前shell进程。对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。
只读变量:read only, 只可以读取不可以更改 。
位置变量:通过命令行给脚本传递参数 。
预定义变量:用来保持脚本程序的执行信息。
环境变量与局部变量
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。
自定义的环境变量只是临时生效,退出系统后就会失效。需要将自定义的环境变量放入配置文件中,才会永久生效。配置文件可以用来长期变更或设置环境变量。
可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。
export 变量=变量值
我们也可以进入/etc/profile,修改此文件会作用于所有用户
只读变量
我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。
只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。
位置变量
使用$n表示,n为数字序列号,且必须为整数。
如:$1、$2、…、$9 、${10}、${11}。
两位数需要加花括号{},不然$10会被识别为:$1和0 。
预定义变量
预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。
| 可以直接使用这些变量,不能直接为这些变量赋值。变量 | 作用 |
|---|---|
| $? | 表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。 |
| $* | 表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词) |
| $@ | 表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体) |
| $# | 表示命令行中位置参数的总个数。 |
| $0 | 表示当前脚本名称(如果是软链接,显示当前软链接文件名)。 |
| $_ | 表示在此之前执行的命令或脚本的最后一个参数。 |
| $$ | 获取当前进程的PID。 |
$* 和 $@的区别:
- 不加双引号的话,
$*和$@都代表脚本后面跟的所有参数。 - 加上双引号的话,"
$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待。