shell
bash与sh的区别
sh是规范,bash是实现,在linux系统中一般都会将/bin/sh软链到/bin/bash上
sh遵循POSIX规范,当某行代码出错时,不继续往下执行。bash就算出错,也会往下执行。
shell脚本
shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑,脚本不用编译即可运行。它通过解释器解释运行,所以速度相对来说比较慢。
#!/bin/bash
echo hello
" # ”开头的就是注释,单行注释
<<EOF … EOF 或 :<<! … ! :多行注释
#!/bin/bash : 主要用于指定解释器
Linux中提供的shell解释器有:
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
shell执行
1.脚本文件无执行权限
手动在环境中开启指定解释器:sh test.sh
直接在当前环境中运行的shell中运行脚本:. test.sh
直接在当前环境中运行的shell中运行脚本:source test.sh
2.脚本文件有执行权限
绝对路径名运行脚本文件 /zzp/zzp.sh
./相对路径名的格式运行脚本文件
${变量名} 获取变量
$变量名 获取变量 ${变量名}的简写
$() 执行命令并获取结果
·· 执行命令并获取结果
() 开启子shell执行
基本语法
变量
变量类型:
局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要 的时候shell脚本也可以定义环境变量。
shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量, 这些变量保证了shell的正常运行
变量操作:
创建普通变量:name=“test”,组要注意的是等号两边不能有空格。
创建局部变量:local name=“test”,使用local修饰的变量在函数体外无法访问,只能在函数体中使用。
创建只读变量:name=“only_read” -> readonly name,这种变量不可以被修改。
使用变量:echo $name或者echo ${name}
删除变量:unset name,删除之后的变量无法被访问,需要注意无法删除只读变量。
字符串变量:
字符串变量的创建:
使用单引号创建:var='test'。这种方式创建的变量只能原样输出,变量无效
使用双引号创建:var="my name is ${name}",这种方式创建的字符串变量有效,也可以出现转义符。
拼接字符串:
字面量拼接:str01="1""2"或者str01="1"'2',这样就将1和2两个字符拼接在了一起。需要注意的是两个串 之间不可以有空格。
变量拼接:str03=${part01}${part02}或str04=${part01}"end"或str05="${part01}${part02}"这三种方式都可以拼接字符串变量。
命令拼接:str02= date“end”,这里的date是一个shell命令,需要使用引用
获取字符串长度:
wc -L命令:wc -L可以获取到当前行的长度,因此对于单独行的字符串可以用这个简单的方法获取,另外wc -l 则是获取当前字符串内容的行数。
expr length ${str}:可以获取string的长度
awk获取域的个数
数组:
数组名=(元素1 元素2 元素3 ... 元素n)
指定数组对应下标的元素进行赋值:数组名[下标]=值
时指定多个数组元素进行赋值:数组名=([下标1]=值1 [下标2]=值2 ... [下标n]=值n)
引用数组对应下标的元素:${数组名[下标]}
遍历数组元素:
1.for(或while循环)循环遍历数组元素:
a=(1 2 3 4 5 6)
for((i=0; i<10; i++))
do
echo "a[$i]=${a[$i]}"
done
2.${a[*]}
3.${a[@]}
#来获取数组长度 echo "a len: ${#a[*]}"
合并数组:c=(${a[*]} ${b[*]})
删除数组元素:unset a[i]
shell扩展变量
如果parameter变量值为空,返回word字符串,赋值给result变量
result=${parameter:-word}
如果parameter变量值为空,则word替代变量值(parameter),且赋值给result变量
result=${parameter:=word}
如果para变量为空,word当做stderr输出,否者输出变量值
用于设置变量为空导致错误时,返回的错误信息
${para:?word}
如果para变量为空,什么都不做,否则word返回给接受者
${para:+word}
$0 代表执行的文件名
$1 代表传入的第1个参数
$n 代表传入的第n个参数
$# 参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数
$$ 脚本运行的当前进程号
$! 后台运行的最后一个进程的ID
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
--单引号变量不识别特殊变量 双引号变量识别特殊变量
expr 表达式
用空格隔开每个项;
用反斜杠 \ 放在 shell 特定的字符前面;
对包含空格和其他特殊字符的字符串要用引号括起来
ARG1 | ARG2
若 ARG1 的值不为 0 或者不为空,则返回 ARG1,否则返回 ARG2
ARG1 & ARG2
若两边的值都不为 0 或都不为空,则返回 ARG1,否则返回 0
ARG1 < ARG2
ARG1 小于 ARG2 返回 1 否则返回 0
ARG1 <= ARG2
ARG1 小于或等于 ARG2 返回 1 否则返回 0
ARG1 = ARG2
ARG1 等于 ARG2 返回 1 否则返回 0
ARG1 != ARG2
ARG1 不等于 ARG2 返回 1 否则返回 0
ARG1 >= ARG2
ARG1 大于或等于 ARG2 返回 1 否则返回 0
ARG1 > ARG2
ARG1 大于 ARG2 返回 1 否则返回 0
ARG1 + ARG2
计算 ARG1 与 ARG2 相加之和
ARG1 - ARG2
计算 ARG1 与ARG2 相减之差
ARG1 * ARG2
计算 ARG1 与ARG2 相乘之积
ARG1 / ARG2
计算 ARG1 与 ARG2 相除之商,向下转换成整数
ARG1 % ARG2
计算 ARG1 与ARG2 相除取余
STRING : REGEXP
执行模式匹配。两端参数会转换为字符串格式,且第二个参数被视为正则表达式(GNU基本正则),它默认会隐含前缀"^"。随后将第一个参数和正则模式做匹配。如果匹配成功,且 REGEX 使用了 \( 和 \),则返回匹配到的内容,如果未使用 \( 和 \),则返回匹配的字符数。否则返回为 0
match STRING REGEXP
等于 STRING : REGEXP
substr STRING POS LENGTH
返回 STRING 中从 POS(从 1 开始) 开始长度最大为 LENGTH 的子串。如果 POS 或 LENGTH 为负数、0 或非数值,则返回空字符串
index STRING CHARS
CHARS 中任意单个字符在 STRING 中最前面的字符位置。如果在 STRING 中完全不存在 CHARS 中的字符,则返回 0
length STRING
字符串的长度
+ TOKEN
将 TOKEN 解析为普通字符串,即使 TOKEN 是像 match 或操作符 / 一样的关键字
( EXPRESSION )
表达式可以使用一对小括号括起来。注意表达式与括号间需要空格
通配符(管道符) |
是用于两个命令或者多个命令相链接,将前边的命令的执行结果传递到后边的命令
运算
算数运算符:
加法 expr $a + $b
减法 expr $a - $b
乘法 expr $a \* $b
除法 expr $b / $a
取余 expr $b % $a
赋值 a=$b
相等 [ $a == $b ]
不相等 [ $a != $b ]
条件表法式需要放在方括号之间,并且要有空格。
使用expr进行计算时需要使用反引号
(())用于整数运算
let 用于整数运算类似于(())
expr
bc linux的下一个计算器程序,可用于整数和小数计算
$[] 用于整数运算
awk 可用于整数和小数计算
declare 定义变量和属性
关系运算符:
检测两个数是否相等 [ $a -eq $b ] -eq
检测两个数是否不相等 [ $a -ne $b ] -ne
检测左边的数是否大于右边的 [ $a -gt $b ] -gt
检测左边的数是否小于右边的 [ $a -lt $b ] -lt
检测左边的数是否大于等于右边的 [ $a -ge $b ] -ge
检测左边的数是否小于等于右边的 [ $a -le $b ] -le
布尔运算符:
非运算 [ ! false ] !
或运算 [ $a -lt 20 -o $b -gt 100 ] -o
与运算 [ $a -lt 20 -a $b -gt 100 ] -a
逻辑运算符:
逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] &&
逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] ||
布尔运算符和逻辑运算符的区别:
语法上,逻辑运算需要双括弧,布尔运算只需要单大括弧
功能上,逻辑运算具有特殊的短路功能,即是在AND运算中第一个表达式为false时则不执行第二个表达式,在OR运算中第一个表达式为true时不执行第二个表达式。
字符串运算符:
检测两个字符串是否相等 [ $a = $b ] =
检测两个字符串是否不相等 [ $a != $b ] !=
检测字符串长度是否为0 [ -z $a ] -z
检测字符串长度是否不为 0 [ -n “$a” ] -n
检测字符串是否为空 [ $a ] $
文件测试运算符:
检测文件是否是块设备文件 [ -b $file ] -b file
检测文件是否是字符设备文件 [ -c $file ] -c file
检测文件是否是目录 [ -d $file ] -d file
检测文件是否是普通文件(既不是目录,也不是设备文件) [ -f $file ] 返回 true -f file
检测文件是否设置了 SGID 位 [ -g $file ] -g file
检测文件是否设置了粘着位(Sticky Bit) [ -k $file ] -k file
检测文件是否是有名管道 [ -p $file ] -p file
检测文件是否设置了 SUID 位 [ -u $file ] -u file
检测文件是否可读 [ -r $file ] -r file
检测文件是否可写 [ -w $file ] -w file
检测文件是否可执行 [ -x $file ] -x file
检测文件是否为空(文件大小是否大于0) [ -s $file ] -s file
检测文件(包括目录)是否存在 [ -e $file ] -e file
函数:
格式:
函数名(){
函数体
}
执行:
函数名
控制语句
if语句结构:
if condition1
then
command1
elif condition2
then
command2
else
command3
fi
循环结构 for while until循环
for/while/util condition
do
command
done
case-esac多选择语句
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
*)
command1
esac
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null中,/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。语法如下:command > /dev/null
子进程、父进程
父进程指已创建一个或多个bai子进程的进程
子进程指的是由另一进程(对应称之为父进程)所创建的进程
命令外套小括号会开启子进程执行
查看 ps -f --forset
内置、外置命令
内置:系统启动时就加载入内存,常驻内存,执行效率更高,但是占用资源 如 cd/cat
外置:系统需要从硬盘中读取,再加载入内存中,会开启子进程执行 如安装的软件提供的命令,
type 命令 可查看该命令是内置还是外置
compgen -b 查看所有内置命令
shell条件测试
test 测试表达式 评估一个表达式,他的结果是真还是假,真:0
[测试表达式]
[[测试表达式]]
((测试表达式))