shell基础认识
目录
shell的初识
shell是命令,又是一门程序设计语言,有变量、函数、逻辑控制语句
echo $SHELL 输出当前系统环境使用的shell解析器
linux系统默认shell解析器为 /bin/bash
shell脚本是一个文本文件,里面可以编写shell命令或编程,形成一个可重复执行的脚本文件
提高Linux系统的管理效率(批操作)
shell脚本文件的编写规范:
文件后缀名常用 .sh
文件首行需要设置该文件的shell解析器类型
#! shell解析器类型(/bin/bash)
单行注释:#注释内容
多行注释::<<! 注释内容 !
shell文件的三种执行方式
1、sh解析器执行
sh 脚本文件路径
2、bash解析器执行
bash 脚本文件路径
3、文件自己执行(需要文件有执行权限,而sh和bash解析器不需要)
脚本文件路径(当前目录下的文件仍需为 ./文件名)
shell变量:
变量用于存储管理临时的数据,都存在运行内存中
环境变量:
1、系统环境变量:shell环境加载全局配置文件中的变量共享给所有shell程序使用
env指令:查看当前shell环境的系统环境变量
set指令:查看当前shell环境的系统环境变量+自定义变量+函数
常用系统环境变量:
PATH:命令的搜索路径
HISTFILE:用户历史操作指令列表所在路径
LANG:系统语言环境
2、个人环境变量:shell环境加载个人配置文件中的变量给当前用户的shell程序使用
自定义变量:
自定义局部变量:只能在一个脚本内部使用的变量
定义语法:变量名=变量值
规则:1、名称可有字母、数字、下划线,但不能以数字开头
2、= 号左右俩边不能有空格
3、在bash解析器中,默认为字符串类型,不能进行数值运算
4、变量值存在空格,需用 “ ”括起来
5、不能用shell的关键字做变量名
输出:echo $变量名,可用 { }进行字符拼接
删除:unset 变量名
自定义常量:只可以读的变量,不可修改
定义语法:readonly 变量名
自定义全局变量:
父子shell环境:A.sh中调用了B.sh,则A.sh为B.sh的父shell环境,父shell环境中定义的全局变量,可在子shell环境中使用
定义语法:export 变量名=变量值
修改:变量名=新的值
查找:${变量名}
删除:unset 变量名
特殊符号变量:
$n:用于接收脚本文件执行时传入的参数
$0:当前脚本文件的名称
$1-$9:表示第一个到第九个传入的参数
第十个参数以上需加 { },${数字}
脚本文件传入参数的方法:sh 脚本文件 传入参数1 传入参数2 ...
$#:获取脚本文件传入参数个数
$*和$@:获取所有传入参数
1、不加 " ",俩者无区别,都是将所有参数拼成一个字符串
2、加 " ","$@":表示一组传入参数列表对象,每个参数都是单独的字符串
$?:获取上一个shell命令的退出状态码,或函数的返回值
一般来说,返回0表示成功,非0失败
$$:获取当前shell环境的进程ID号
shell环境变量深入:
系统环境变量全局配置文件 /etc/profile
可在配置文件中增删系统环境全局变量(export)
需source(重载)后才会生效
unset删除(直接删除文件内的声明语句无法直接生效,需要再次关开机后重新加载shell环境)
shell工作环境分类:
交互式和非交互式
交互式:用户实时输入命令操作,shell立即反馈
非交互式:shell直接进行一系列操作,不需要用户参与,最后反馈结果
登录和非登录式:
登录:需要用户名和密码进行登录操作的shell环境
非登录式:不需要用户名和密码进行登录操作的shell环境 或 执行脚本文件
不同的登录模式加载环境变量的流程不同:
简单来说:非登录的shell工作环境,不会加载 /etc/profile文件
可使用 echo $0 来识别当前shell的登录环境
输出 -bash(-su):当前为登录式shell环境
输出 bash:表示当前为非登录式shell环境
工作环境之间的切换:
su 用户名 -l (--login): 加载shell登录环境
su 用户名 : 加载shell非登录环境
bash:切换到非登录环境
bash -l(--login)脚本文件 :先加载shell登录环境,在执行脚本文件
sh -l(--login)脚本文件:先加载shell登录环境,在执行脚本文件
shell字符串变量:
使用格式:
单引号:无法解析变量,直接原样输出
双引号:可以解析变量,且可以包含空格、子双引号(需转义)
echo "双引号 \" 子双引号 \" "
无引号:可以解析变量,但有变量要解析时,则整个字符串不能有空格
获取长度:
${#字符串变量名}
拼接方式:
无符号拼接: 拼接字符串中间不能存在空格
新字符串=字符串1字符串2
有符号拼接:允许存在空格和其它字符
新字符串=" 字符串1 字符串2"
混合拼接:不使用 " "也能进行空格拼接,但需要借助echo
截取:
${变量名:start:lenth}:从左侧start位置(0开始数)开始,向右截取lenth长度字符
${变量名:start}:从左侧start位置(0开始数)开始,向右截取剩余全部字符
${变量名:0-start:lenth}:从右侧strat位置(1开始数)开始,向左截取lenth长度字符
${变量名:0-start}:从右侧start位置(1开始数)开始,向左截取剩余全部字符
${变量名#*字符C}:截取从左侧开始第一次出现字符C位置的右侧剩余字符
${变量名##*字符C}:截取从左侧开始最后一次出现字符C位置的右侧剩余字符
${变量名%字符C*}:截取从右侧开始第一次出现字符C位置的左侧剩余字符
${变量名%%字符C*}:截取从右侧开始最后一次出现字符C位置的左侧剩余字符
索引数组:
定义:()表示数字,数组元素用空格隔开
数组名称=(元素1 元素2 ...)
数组名称=([索引下标]=元素1 [索引下标]=元素2 ...)
=左右俩侧不能存在空格
PS:不能通过此方法创建关联数组(key-value)
获取:
${数组名[索引]}:该索引对应的数组元素
${数组名[*]} 或 ${数组名[@]}:获取数组全部元素
${#数组名[*]} 或 ${#数组名[@]}:获取数组的长度或元素个数
${#数组名[索引]}:该索引对应的数组元素的长度
拼接:同定义创建
新数组名称=(数组1 数组2):
删除:unset
unset 数组名[索引]:删除指定元素
unset 数组名:删除整个数组
shell内置命令:
由shell自身提供,不是系统文件中的可执行脚本文件
查看命令的类型:type 命令
内置:相当于函数调用,效率高
脚本文件:启动新进程,磁盘I/O操作,进程上下文切换,效率低
alias:设置别名
alias指令:查看当前环境下的别名列表
alias 别名="命令":给命令设置别名
unalias:别名 :删除指定别名
unalias -a:删除所有别名
PS:仅临时生效,想永久生效需修改配置文件
echo:输出字符串,默认换行
echo 字符串:默认换行输出
echo -n 字符串:不换行输出
echo -e 字符串:解析转义字符
echo -e 字符串\c:解析\c,清楚结尾的换行符,使不换行输出
read:读取数据
read:不提供变量名,则最后一个输入数据存储在环境变量 $REPLY中
read 变量名:读取数据存入指定变量中
操作选项:
-n 数字X:限制读取X个字符
-p "提示信息":关于输入的提示信息
-s:静默输入,不将输入内容显示出来(eg:密码输入)
-t 限制输入时间T(单位秒):设置输入时间,超过时间T会输入失败
exit:退出,并返回状态码
exit:默认正确退出,状态码为0
exit: 非零数字X :错误退出,返回状态码X
可通过状态码,判断操作执行失败的原因
declare:声明变量、设置变量类型
declare 操作选项 变量名=变量值
操作选项:
-:指定变量类型
+:取消变量类型
a:普通的索引数组
索引数组名=([索引下标]=值1 [索引下标]=值2 ...) 索引下标不能为字符串
A:关联数组
关联数组名=([字符串key1]=值1 [字符串key2]=值2 ...
r:自读变量 (readonly)
x:全局变量 (export)
i:整形变量 (int)
f:函数变量
shell运算符:
算数运算符:
expr命令: 求值表达式
加减乘除:(只能整形运算)
语法:expr 运算符表达式 (表达式各元素需要用空格隔开)
将计算结果赋值给新变量:新变量名=expr `运算符表达式` (此处` `为反引号)
+:加 expr 1 + 1
-:减 expr 3 - 1
*:乘 expr 2 \* 3 (乘需进行转义)
/:除 expr 4 / 2
%:取余 expr 4%2
=:赋值 expr $a=$b
若运用了()也需要转义 \( \)
比较运算符:
整数比较运算符:只可以比较整数
语法:[ 数值1 操作选项 数组2 ](注意空格)
操作选项:
-eq:比较俩个数是否相等,等返回0,不等返回1
-ne:比较俩个数是否不相等,不等返回0,等返回1
-gt:比较数值1是否大于数值2,大返回0,不大返回1
-lt:比较数值1是否小于数值2,小返回0,不小返回1
-ge:比较数值1是否大于等于数值2,是返回0,否返回1
-le:比较数值1是否小于等于数值2,是返回0,否返回1
语法:((数值1操作选项数值2))(不要空格隔开)
另一种语法格式,效果一致
操作选项:
<、<=、>、>=、==、!=
字符串比较运算符:可以比较数字字符与字符串
使用 [ 字符串1 操作选项 字符串2 ] 或 [[ $字符串1 操作选项 $字符串2 ]]
==或=:判断是否相等,相等返回0,不等返回1
!=:判断是否不等,不等返回0,等返回1
<:比较左侧字符串或数字是否小于右侧,小则返回0,不小于则返回1
>:比较左侧字符串或数字是否大于右侧,大于返回0,不大于返回1
PS:字符串比较符不存在>= 或 <=,需组合使用
< 和 > ,在使用 [ ] 时,需转义,[ \< ] [ \> ],而 [[ ]]不用
只能使用 [ ]:
-Z:判断字符串长度是否为0,是返回0,不是返回1 [ -Z $字符串 ]
-n:判断字符串长度是否不为0,是返回0,不是返回1 [ -n $字符串 ]
$:判断字符串是否为空,是返回0,不是返回1 [ $字符串 ]
[[ ]]和 [ ]的区别:
1、字符分隔(word spliting):
[ ]会将有空格分隔的字符串分割成多个字符
2、部分操作选项需要转义 \
布尔运算符:只能使用 [ ]
只能使用 [ ] 或搭配 test指令使用
!:取反 [ ! 表达式]
-o:或 [ 表达式1 -o 表达式2 ]
-a:与 [ 表达式1 -a 表达式2 ]
逻辑运算符:
&&:逻辑与 [[ 表达式1 && 表达式2 ]]
||:逻辑或 [[ 表达式1 || 表达式2 ]]
!:逻辑非 [[ ! 表达式 ]]
PS:&&和 || 可以使用 [[ ]] 和 (( ))
而 !可以使用 [[ ]] 和 [ ],不能使用 (( ))
文件测试运算符:检查文件
文件类型:
-:普通文件
d:文件夹(目录文件)
l:链接文件(eg:快捷键)
b:块设备文件
c:字符设备文件
p:管道文件
文件属性检测:[ 操作选项 $记录文件路径的变量] 或 [ 操作选项 文件路径 ]
-f:是否是普通文件,是返回0,不是返回1
-d:是否是文件夹(目录文件),是返回0,不是返回1
-r:是否有读权限,是返回0,不是返回1
-w:是否有写权限,是返回0,不是返回1
-x:是否有执行权限,是返回0,不是返回1
-s:是否为空,是返回0,不是返回1
-e:是否存在,是返回0,不是返回1
-nt:文件1是否比文件2新,是返回0,不是返回1 [ 文件1路径 -nt 文件2路径]
-ot:文件1是否比文件2老,是返回0,不是返回1 [ 文件1路径 -ot 文件2路径 ]
按照文件最近修改时间判断