shell基础(二)
shell数值运算
Shell 算术运算符
Shell 和其他编程一样,支持包括:算术、关系、布尔、字符串等运算符。
整数运算(expr)
(1)数字运算
expr 3 + 2
expr 3 - 2
expr 3 \* 2 # 注意*出现应该转义,否则认为是通配符
expr 3 / 2 # 没有小数,只有整数
expr 3 % 3
(2)let支持变量运算,只能做整数运算,且运算元素必须是变量,无法直接对整数做运算
let a=2
let a++
let b=a*3
let c=b%2
echo "a=$a b=$b"
(3)$(( ))同时支持数字运算与变量间运算,双小圆括号运算,在shell中(( ))也可以用来做数学运算
echo $(( a=a+1 ))
浮点运算(bc)
浮点运算是采用的命令组合的方式来实现的 echo “scale=N;表达式”|bc
先bc进入计算器然后进行运算即可,默认只有整数
echo "22 * 33"|bc #通用,quit退出
echo "print 22 * 22"| python3 #可以小数运算,vscode和Ubuntu都报错
举例:
echo "scale=2;3/2"|bc
echo "print(3/2)"| python3
# 获取随机整数
echo "import random;print(random.randint(1,100))"| python3
# 获取随机小数
echo "import random;print(random.random())"| python3
或者echo "import random;print(random.uniform(1,100))"| python3
# 获取内存总量与使用量,求内存占用量
total=`free|sed -n "2p"|awk '{print $2}'`
used=`free|sed -n "2p"|awk '{print $3}'`
echo "print(f'{$used/$total*100:.2f}%')"|python3
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法(需要加转义符) | num=3 \* 12 echo $num |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
Shell 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 英文 | 举例 |
---|---|---|---|
-eq | 等于 | equal | [ $a -eq $b ]返回 false |
-ne | 不等于 | not equal | [ $a -ne $b ] 返回 true |
-gt | 大于 | greater than | [ $a -gt $b ]返回 false |
-lt | 小于 | less than | [ $a -lt $b ] 返回 true |
-ge | 大于或等于 | Greater than or equal to | [ $a -ge $b ]返回 false |
-le | 小于或等于 | Less than or equal to | [ $a -le $b ]返回 true |
可以通过test命令比较两个整数的关系,但不会返回结果,需要通过$?才能看到结果:
[root@zuolaoshi ~]# test 100 -gt 300;echo $?
1 #100大于300吗?假的
[root@zuolaoshi ~]# test 100 -le 300;echo $?
0 #100小于或等于300吗?真的
Shell 逻辑运算符
完成一个任务中需要多个条件都满足或者多个条件中只要满足一个即可,那么这就是我们的逻辑运算,以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
! | 非运算 | [ ! false ] 返回 true。 |
Shell 字符串比较运算
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
test文件判断命令
命令功能:检测文件类型和比较运算
命令用法
test [命令选项] 表达式
命令选项
-d 检查文件是否存在且为目录
-e 检查文件是否存在
-f 检查文件是否存在且为文件
-r 检查文件是否存在且可读
-s 检查文件是否存在且不为空
-w 检查文件是否存在且可写
-x 检查文件是否存在且可执行
-O 检查文件是否存在并且被当前用户拥有
-G 检查文件是否存在并且默认组为当前用户组
-nt file1 -nt file2 检查file1是否比file2新
-ot file1 -ot file2 检查file1是否比file2旧
-ef file1 -ef file2 检查file1是否与file2是同一个文件,判定依据的是i节点
以上只列出部分命令选项,详细的可以通过:man test获得。
数组
# 创建数组
arr=(1 2 3 4 5)
# 通过下标修改值
arr[0]="A"
# 显示所有的值
echo ${arr[*]}
# 获取元素的数量
echo "元素的数量:"${#arr[*]}
# 获取数组元素的索引
echo ${!arr[@]}
# 切片:获取部分元素
echo "获取2~4的元素:"${arr[@]:2:3}
# 遍历循环所有的值
for i in ${arr[*]}
do
echo $i
done
# 创建关联数组
declare -A asso_array1
declare -A asso_array2
declare -A asso_array3
# 一次赋一个值
数组名[索引]=变量值
[root@zuolaoshi ~]# asso_array1[linux]=one
[root@zuolaoshi ~]# asso_array1[java]=two
[root@zuolaoshi ~]# asso_array1[php]=three
# 一次赋多个值
[root@zuolaoshi ~]# asso_array2=([name1]=harry [name2]=jack [name3]=amy [name4]="Miss zhang")
# 查看关联数组
[root@zuolaoshi ~]# declare -A
declare -A asso_array1='([php]="three" [java]="two" [linux]="one" )'
declare -A asso_array2='([name3]="amy" [name2]="jack" [name1]="harry" [name4]="Miss zhang" )'
# 管理数组取值
[root@zuolaoshi ~]# echo ${asso_array1[linux]}
one
[root@zuolaoshi ~]# echo ${asso_array1[php]}
three
[root@zuolaoshi ~]# echo ${asso_array1[*]}
three two one
[root@zuolaoshi ~]# echo ${!asso_array1[*]}
php java linux
[root@zuolaoshi ~]# echo ${#asso_array1[*]}
3
[root@zuolaoshi ~]# echo ${#asso_array2[*]}
4
[root@zuolaoshi ~]# echo ${!asso_array2[*]}
name3 name2 name1 name4
常用数据处理命令
数据检索命令
行检索:grep egrep 字符串检索:cut tr
数据处理命令
数据排序:sort 数据去重: uniq
文本数据合并: paste 数据输出: tee 数据处理: xargs
grep:负责从数据源中检索对应的字符串,行过滤
grep -i root passwd 忽略大小写匹配包含root的行
grep -w ftp passwd 精确匹配ftp单词
grep -wo ftp passwd 打印匹配到的关键字ftp
grep -n root passwd 打印匹配到root关键字的行好
grep -ni root passwd 忽略大小写匹配统计包含关键字root的行
grep -nic root passwd 忽略大小写匹配统计包含关键字root的行数
grep -i ^root passwd 忽略大小写匹配以root开头的行
grep bash$ passwd 匹配以bash结尾的行
grep -n ^$ passwd 匹配空行并打印行号
grep ^# /etc/vsftpd/vsftpd.conf 匹配以#号开头的行
grep -v ^# /etc/vsftpd/vsftpd.conf 匹配不以#号开头的行
grep -A 5 mail passwd 匹配包含mail关键字及其后5行
grep -B 5 mail passwd 匹配包含mail关键字及其前5行
grep -C 5 mail passwd 匹配包含mail关键字及其前后5行
cut 切割字符串,按照顺序获取某一段内容;
-d :指定分隔符
-f :显示的列 -f1代表第一列
-c :截取每行的某几个字符 -c1-5代表每行的1-5个字符
tr 字符转换:替换字符、删除字符
语法:commands|tr 'string1' 'string2'
tr 'string1' 'string2' < filename
tr options 'string1' < filename
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
sort 排序显示,默认排序规则是字符编码排序
语法:sort [options] [filename]
-u :去重
-r :降序,默认是升序
-o : 将排序结果输出到文件中 类似 重定向符号 >
-n :按照数字的排序规则排序
-k :指定列来排序
uniq 去除连续的重复行,去重前先使用sort排序
语法:uniq [options] [filename]
-i:忽略大小写
-c: 统计重复行次数
-d:只显示重复行
tee 双向输出,在屏幕输出内容的同时,还可以保存到文件里
-a:双向追加重定向
语法:somecommand |tee filename
paste 将多个文件中的内容按列合并输出到屏幕,不会改变源文件
-d:指定分隔符,默认是
tab
,只接受一个字符,要用单引号引起来-s:行列转换后显示
xargs 将前一个命令的执行结果作为后一个命令的参数
管道(|):上一个命令的输出作为下一个命令的输入,做的是数据源。
命令格式: ''[somecommand]|[filename]'' |xargs -item command
vim download.txt
https://127.0.0.1/1.txt
https://127.0.0.1/2.txt
......
# 通过xargs+wget实现批量下载
cat download.txt |xargs wget
# 等价于wget一个个下载
wget https://127.0.0.1/1.txt
wget https://127.0.0.1/2.txt
......
特殊符号
符号 | 功能 |
---|---|
!! | 自动执行上一次执行的命令 |
$ | 获取变量的值 |
$(命令) | 获取命令的执行结果`` |
&写在命令执行的结尾 | 让前台程序在后台执行 |
&& | 与运算 |
&> | 将标准输出和标准错误输出都重定向到一个文件 |
; | 在命令行中,一行执行多条命令 |
> | 输出重定向,将命令执行结果保存到文件中,不存在时会创建文件,存在时会覆盖原文件内容 |
>> | 追加重定向,将内容添加到文件的最后,不覆盖,只追加 |
< | 输入重定向,读取文件中的内容,交给命令执行 |
<< | 追加输入重定向,将键盘输入的内容交给命令批量执行 |
| | 将前一个命令的执行结果交给后一个命令执行 |
进程管理
jobs 查看进程后台号
bg 编号 放到后台继续运行
fg 编号 将进程放到前台运行