一、什么是shell?
Shell 是一个用户与操作系统内核之间的接口,提供了一个命令解释和程序执行的环境。用户通过 Shell 可以直接与操作系统进行交互,运行命令、脚本和程序。在 Unix 和 Unix-like 系统中,Shell 是一个重要的组件。
Shell 的作用:
- 命令解释器: Shell 解释和执行用户输入的命令。
- 程序运行环境: Shell 可以用来运行脚本和程序。
- 环境配置: 用户可以通过 Shell 配置环境变量、别名等。
文件操作: 用户可以通过 Shell 进行文件和目录的操作。
- 作业控制: 在后台运行程序、中断正在运行的程序等。
常见的 Shell:
- Bourne Shell (sh): 原始的 Unix Shell,简单而高效。
- Bash (Bourne Again SHell): Bourne Shell 的扩展,广泛用于 Linux 系统。
- C Shell (csh): 具有 C 语言风格语法的 Shell。
- Korn Shell (ksh): 合并了 Bourne Shell 和 C Shell 的特性。
- Zsh: 高度可定制的 Shell,具有丰富的特性。
- Fish (Friendly Interactive SHell): 面向用户友好,提供直观的自动补全和语法高亮。
对于bashshell脚本而言,shell分为默认的交互shell和默认的系统shell,在Linux中,shell脚本都是vim编辑,由Linux命令、bash shell指令、逻辑控制语句和注释信息组成。
Shebang:在计算机程序中,shengbang指的是出现在文本文件的第一行前两个字符#!
在Unix系统中,程序会分析shebang后的内容,作为解释的指令,例如
- 以#!/bin/sh开头的文件,程序在执行的时候会调用/bin/sh,也就是bash解释器
- 以#!/usr/bin/python开头的文件,代表指定python解释器去执行
- 以#!/usr/bin/env解释器名称,是一种在不同平台上都能正确找到解释器的办法
如果文件没有指明shebang,则会以当前默认的shell去执行,即$SHELL,如果shebang指定了可执行的解释器,则脚本在执行的时候,文件名会作为参数传递给解释器。
脚本注释:在shell脚本中常用#作为注释命令,注释可以单独写一行也可以将注释写在命令的后面
二、shell的父子关系
在Shell中,进程之间存在父子关系。当一个Shell脚本或命令启动时,它会创建一个新的进程,该进程称为子进程。
父进程
当你在终端中运行一个Shell脚本或命令时,这个终端就成为父进程。
父进程通常等待子进程完成执行,并且可以获取子进程的退出状态。
子进程:
当你在终端中运行一个Shell脚本或命令时,这个脚本或命令就会启动一个新的进程,即子进程。
子进程的代码是由父进程复制过来的,但有独立的执行空间。
获取子进程的退出状态:
父进程可以通过特殊变量 $? 来获取子进程的退出状态。
退出状态为0表示子进程成功执行,非0表示发生错误或异常。
后台作业和前台作业:
当在Shell中运行一个命令时,该命令可以在前台或后台运行。
在前台运行的命令会将终端锁定,直到命令执行完毕。
在后台运行的命令可以让你继续在终端中输入其他命令。
& 符号:
在Shell命令末尾加上 & 符号,可以将该命令放到后台执行。
例如:command &,这将使command在后台执行。
shell的多种执行方式
bash file 、sh file、. file、source file
前两种是在子shell中运行,后两种是在本shell中运行
bash允许多条命令一起执行,多条命令中间用分号隔开。
shell解释器在哪
cat /etc/shells | chsh -l
三、shell变量
$$变量:
在Shell中,$$ 变量表示当前进程的进程ID(PID)。
例如,echo $$ 将输出当前Shell进程的PID。
在shell中变量的定义时,变量与赋值之间不能有空格,bash默认把所有变量都认为是字符串类型。
变量名的规则:名称定义要做到见名知意,不能够引用保留关键字,变量名只能够包含数字、字母、下划线,且不能够以数字开头,不能够使用标点符号,变量名严格区分大小写。
变量的作用域:本地变量,只针对当前的shell进程。切换shell变量会丢失。
环境变量(全局变量):针对当前shell以及其任意子进程,环境变量也分为自定义和内置两种环境变量。
每个用户都有自己的环境变量配置文件,~/.bash_profile ~/.bashrc,并且以个人的配置文件优先加载变量读取,以个人的优先生效。当需要给所有用户都设置环境变量时,则可以将变量写入全局配置文件/etc/profile中即可。
检查系统环境变量的命令
set:输出当前的shell环境中的所有的变量,包括全局变量、局部变量
env:只显示全局变量
declare:输出所有变量,如同set
export:显示和设置环境变量值
如果需要撤销环境变量,unset变量名,删除变量和函数。
设置只读变量:readonly,只有shell结束了,只读变量才会失效
位置参数变量:用于shell脚本中传递参数
特殊变量:shell内置的特殊功效变量 $? 0:成功 1-255:错误码
特殊变量用在如脚本,函数传递参数使用,
- $0:获取shell脚本文件名,以及脚本路径
-
$n:获取shell脚本的第n个参数,n在1~9之间,大于9则需要写成如${ 10 }的形式,参数空格隔开
- $#:获取执行的shell脚本后面的参数总个数。
- $*:获取shell脚本所有参数,不加引号等于$@的作用,加上双引号作用是接受所有参数作为单个字符串
- $@:接受所有参数为独立字符串,会将所有的参数从整体上看成一份数据,而不是把每个参数都看成一分数据。
- 注意:如果使用echo直接输出$*和$@做对比,是看不出来区别的;但是如果使用for循环来逐个输出数据,立刻就能够看出区别。
- 特殊 状态变量
- $? :上次命令执行状态返回值,0正确,非0则失败
- $$:当前shell脚本的进程号
- $!:上一次后台进程的PID
- $_:获取上条命令的最后一个参数
-
变量的作用域(盒子的嵌套)
本地变量是指的当前shell中的变量,单引号变量,不识别特殊语法,双引号变量,能够识别特殊符号。
每当调用bash或者sh解释器执行脚本时,都会开启一个子shell,因此不保留当前shell变量,通过pstree命令可以查询进程树。
调用source或者点符号执行脚本时,在当前shell环境加载脚本,因此会保留变量。
环境变量的设置
环境变量一般是由export内置命令导出的变量,用于定义shell运行环境,保证shell命令的正确执行,shell通过环境变量确定登陆的用户名、PATH路径、文件系统等各种应用。
环境变量可以在命令行中临时创建,但是当退出shell终端时,变量丢失,如果要永久生效,需要修改环境变量的配置文件。
bash内置命令:
echo: -n 不换行输出、-e 解释字符串中的特殊符号、 \n 换行、 \r 回车、 \t 制表符、 \b 退格
eval: 执行多个命令
exec: 不创建子进程,执行后续名令,且在执行完成功后,自动的exit
shell子串的花式用法
${变量}:返回变量值
${#变量}:返回变量长度,字符长度
${变量:start} :返回start数值之后的字符
${变量:start:length} 提取start之后的length限制的字符
${变量#word}:从变量开头删除最短匹配的word子串
${变量##word}:从变量开头,删除最长匹配的word。
${变量%word}:从变量结尾删除最短的word
${变量%%word}:从变量结尾开始删除最长匹配的word
${变量/pattern/string}:用string代替第一个匹配的pattern
${变量//pattern/string}:用string代替所有的pattern
特殊shell扩展变量
变量的处理
以下四个扩展变量都是对变量的值进行判断、处理
如果parameter变量值为空时,返回word字符串,赋值给result变量
result=${parameter:-word}
如果para变量为空时,则word替代变量值,且返回其值
result=${para:=word}
如果para变量为空时,word当作stderr输出,否则输出变量值,用于设置变量为空时导致错误时,返回的错误信息
${para:?word}
如果para变量为空,什么都不做,否则word返回
${para:+word}
检测是否在子shell环境中
Linux默认的有关shell变量
BASH_SUBSHELL:该变量的特点,如果是0,就是在当前shell环境中运行的,否则就是开辟子shell去运行的
子shell的嵌套运行
利用括号,开启子shell运行命令,可以多个括号嵌套开启多个子shell环境,开启子shell的理念,以及检查,在shell脚本开发中,经常会用子shell进行多线程处理,提高程序并发执行效率。
(pwd;(pwd;($BASH_SUBSHELL)))
内置命令和外置命令
内置命令:在系统启动时就加载入内存,常驻内存,执行效率更高,但是占用资源
外置命令(自己单独下载的文件系统命令):系统需要从硬盘中读取程序文件,再读入内存加载。例如ps
外置命令的特点:一定会开启子进程执行
内置命令的特点:内置命令不会产生子进程去执行,内置命令和shell是为一体的,时shell的一部分,不需要单独去读取某个文件,系统启动后,就执行在内存中了。
type命令验证即可 || compgen -b 查看Linux系统中的内置命令。
shell中的数学运算 - 一、整数运算
- 方法一:expr
- 方法二:$(())
- 方法三:$[]
- 方法四:let
- 二、小数运算
- 通过安装计算器程序bc来进行计算
- shell中常见的运算符