什么是shell
shell 是操作系统的一个软件。它包在linux 内核外面,为用户和内核之间的交互提供了一个接口。系统中的命令用shell解释,shell接收系统回应的输出并显示其到屏幕中。
shell 是一个命令语言解释器,它拥有自己内建的shell命令集。
shell 脚本。
脚本是一种解释型语言。
- 保存执行动作
- 判定命令的执行条件
- 实现动作的批量执行
创建脚本
vim test.sh 用vim编写脚本
#! /bin/bash 脚本使用的解释器,通常用幻数 "#!" 指定
#AUTHOR 脚本作者
#DATE 脚本创作时间
#MAIL 脚本作者联系方式
#VERSION 脚本的版本
脚本编写
vim test.sh
内容:
#! /bin/bash
watch -n 1 date
执行脚本
- sh test.sh
- chmod +x test.sh 加可执行权限 && /mnt/test.sh 绝对路径的方式执行
脚本调试
用绝对路径执行后会显示执行脚本调用的解释器和执行结果
#! /bin/bash -x (注意:-x)
echo hello test
执行:
/mnt/test.sh
输出:
+ echo hello test
hello test
shell 变量
- shell 的变量赋值的时候不用带 , 而 使 用 或 者 输 出 的 时 候 需 要 带 , 而使用或者输出的时候需要带 ,而使用或者输出的时候需要带
- 加减乘除的时候需要两层小括号,括号外面要有一个$, 括号里面的变量可以不用 $
- 变量赋值,变量使用的时候不能有空格,否则会被解析为命令
代码示例:
#!/bin/bash
a=10
b=20
c="this is a test"
d=$((a+b))
e=$((a-b))
f=$((a*b))
g=$((a/b))
h=$((a%b))
i=$((a**3))
echo $c
echo "a = "$a #输出a的值
echo "b = "$b #输出b的值
echo "a+b = "${d} #输出a+b的值
echo "a-b = "${e} #输出a-b的值
echo "a*b = "${f} #输出a*b的值
echo "a/b = "${g} #输出a/b的值
echo "a%b = "${h} #输出a%b的值
echo "a^3 = "${i} #输出a的3次方的值
echo "a+b = "$((a+b)) #输出a+b的值
echo "a-b = "$((a-b)) #输出a-b的值
echo "a*b = "$((a*b)) #输出a*b的值
echo "a/b = "$((a/b)) #输出a/b的值
echo "a%b = "$((a%b)) #输出a%b的值
echo "a^3 = "$((a**3)) #输出a的3次方的值
echo $((a+b*a-b/a+a%b+a**2)) #表达式可以很长
- shell 变量表达式
表达式 | 说明 |
---|---|
${#string} | 计算$string的长度 |
${string:position} | 从pos开始提取字符串 |
${string:position:len} | 从pos开始提取长度为len的字符串 |
${string#substr} | 从开头删除最短匹配子串 |
${string##substr} | 从开头删除最长匹配子串 |
${string%substr} | 从结尾删除最短匹配子串 |
${string%%substr} | 从结尾删除最长匹配子串 |
#!/bin/bash
str="a b c d e f g h i j"
echo "the source string is "${str} #源字符串
echo "the string length is "${#str} #字符串长度
echo "the 6th to last string is "${str:5} #截取从第五个后面开始到最后的字符
echo "the 6th to 8th string is "${str:5:2} #截取从第五个后面开始的2个字符
echo "after delete shortest string of start is "${str#a*f} #从开头删除a到f的字符
echo "after delete widest string of start is "${str##a*} #从开头删除a以后的字符
echo "after delete shortest string of end is "${str%f*j} #从结尾删除f到j的字符
echo "after delete widest string of end is "${str%%*j} #从结尾删除j前面的所有字符包括j
- shell 条件分支结构语句
- 单分支判定语句
#!/bin/bash echo "Please input a filename" read filename if [ -f $filename ];then echo "this file is a ordinary file." fi
- 双分支判定语句
echo "Please input a filename" read filename if [ -f $filename ];then echo "this file is a ordinary file." else echo "this file is not a ordinary file." fi
- 多分支判断语句
#!/bin/bash echo "Please input your math grades" read grades if [ $grades -gt 100 ] || [ $grades -lt 0 ];then echo "Please input the number range in 0 - 100" fi if [ $grades -ge 90 ] && [ $grades -le 100 ];then echo "Your grade is excellent." elif [ $grades -ge 80 ] && [ $grades -le 89 ];then echo "Your grade is good." elif [ $grades -ge 70 ] && [ $grades -le 79 ];then echo "Your grade is middle." elif [ $grades -ge 60 ] && [ $grades -le 69 ];then echo "Your grade is passing." else echo "Your grade is badly." fi
#!/bin/bash echo "Please input a command" read cmd case $cmd in cpu) echo "The cpu information is" cat /proc/cpuinfo;; mem) echo "The mem information is" cat /proc/meminfo;; device) echo "The device information is" cat /proc/scsi/device_info;; CD-ROM) echo "The CD-ROM information is" cat /proc/sys/dev/cdrom/info;; *) echo "Your input command is invalid" esac
- 单分支判定语句
- shell 循环语句
- while
while语句是只要条件为真就执行下面语句。
格式:
while 条件
do
语句
done#!/bin/bash i=$1 while [ $i -gt 0 ] do echo $i ((i--)) done
- until
until语句是只要条件为假就执行下列语句
格式:
until 条件
do
语句
done#!/bin/bash i=$1 until [ $i -le 0 ] do echo $i ((i--)) done
- for
格式:
for 变量 in 列表
do
语句
done#!/bin/bash for i in `seq 2 8` #seq是一个命令,顺序生成一串数字或者字符 do echo $i done
- while
- shell 函数
格式:
[function] funcName()
{
语句
[return 返回值]
}
返回值是可选的,如果没有显示return,则默认返回最后一条语句执行的结果。
shell 函数的返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果return 其他数据,比如一个字符串,会得到错误提示:“numerical argument required”
如果一定要让函数返回字符串,可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
函数参数从 $1 到 $n, $0表示文件名
#!/bin/bash
#打印数字
printNum()
{
echo $1
}
for i in `seq 2 8` #seq是一个命令,顺序生成一串数字或者字符
do
printNum $i
done
返回字符串,报错
#!/bin/bash
#打印字符串
printNum()
{
return "Hello"
}
for i in `seq 2 8` #seq是一个命令,顺序生成一串数字或者字符
do
printNum
done
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNfs0g9Y-1591857331793)(file:///Users/yangmingyue/Documents/Gridea/post-images/1591697007753.jpg)]
脚本命令
- diff
比较两个文件的不同
[num1,num2]a|c|d[num3,num4]
num1,num2表示在第一个文件的行数
a表示添加:add
c表示更改:change
d表示删除:delete
num3,num4 表示在第二个文件中的行数
diff test1 test2
- cut
用于字符串截取
cut -d 指定分隔符
cut -f 1,7|1-7 指定截取的列
cut -c 1,4|1-4 指定截取的字符位置
- sort
用于字符排列
sort -n 纯数字排列
sort -r 倒序
sort -u 去掉重复数字
sort -o 输出到指定文件中
sort -t 指定分隔符
sort -k 指定排序的列
- uniq
对重复字符做相应的处理,配合sort用
注意:只能是相邻行生效,非相邻行无效,所有需要先sort,然后在uniq
uniq 对重复字符做相应的处理
uniq -u 显示唯一的行
uniq -d 显示重复的行
uniq -c 每行显示一次并统计重复次数
- && 和 ||
是与非。
&& 用来执行条件成立后的命令
|| 用来执行条件不成立后的命令
#!/bin/bash
ping -c1 -w1 $1 &>/dev/null && echo $1 is up || echo $1 is down
- test 和 [] 等同
注意:使用[] 的时候必须要每个变量之间要有空格,和左右中括号也要有空格,否则报错。
test "$A"="$B" 等同 ["$A"="$B"]
["$A"="$B"] 表示"$A"="$B"成立
["$A"!="$B"] 表示"$A"="$B"不成立
[ -z "$A"] 表示$A是否为空
[ -n "$A"] 表示$A是否不为空
整形数据比较:
参数:
-eq 等于
-ne 不等于
-le 小于等于
-lt 小于
-ge 大于等于
-gt 大于
[ "$a" = "$b" -o "$a" -lt "50" ] $a是否等于$b,或者$a小于50
[ "$a" = "$b" -a "$a" -lt "50" ] $a是否等于$b,并且$a小于50
-o 表示或者
-a 表示并且
编辑脚本:vim check_num.sh 判定一个数字是否在0-10之间,脚本后面没数字显示please give me a number!,有数字进行判定在1-10输出yes否则输出no。
#!/bin/bash
[ -z "$1" ] && { 判定脚本后第一穿字符是否为空
echo please give me a number !!
exit 1
}
[ "$1" -gt "0" -a "$1" -lt "10" ] && echo yes || echo no
- test命令:判定文件的类型
参数:
[ -e "file" ] 文件是否存在
[ -f "file" ] 文件是否为普通文件
[ -L "file" ] 文件时否为连接(软连接)
[ -S "file" ] 文件是否为套接字
[ -b "file" ] 文件是否为快设备
[ -d "file" ] 文件是否为目录
[ -c "file" ] 文件是否为字符设备
ln -S /mnt/file /mnt/hello 创建链接-s表示软链接,不加-s表示硬链接
判定文件是什么类型的文件
编写脚本:vim file.sh
内容:
#!/bin/bash
[ -z "$1" ] && { 脚本后是否为空
echo please give me a filename !! 为空输出please give me a filename !!
exit 1
}
[ -e $1 ] || { 文件是否存在
echo $1 is not file 文件不存在
}
[ -L $1 ] && { 文件是否为连接
echo $1 is a link file 文件是连接
exit 1
}
[ -f $1 ] && { 文件是否为普通文件
echo $1 is a common file 文件是普通文件
}
[ -S $1 ] && { 文件是否为套接字
echo $1 is a sock file 文件是套接字
}
- tr
字符转换(文本内容)
tr 'a-z' 'A-Z' < /mnt/westos > /mnt/hello
将westox内容转化成大写并重定向到/mnt/hello中
- find 查找
参数:
-type 类型
-size 大小
-perm 权限
-user 拥有着
-group 所有组
-name 名字
-mindepth 最小深度
-maxdepth 最大深度
find /mnt/ -type l 查找/mnt/的连接的文件
find /mnt/ -group student 查找/mnt/的student组的文件
find /mnt/ -user root -a -group student
查找/mnt/的文件是root用户并且是student组的文件
find /mnt/ -user root -o -group student
查找/mnt/的文件是root用户或者是student组的文件
find /etc -maxdepth 深度查找
find /etc -maxdepth 1 -name passwd 查找深度位1的文件
find /etc -mindepth 1 -maxdepth 2 -name passwd
查找最小深度位1最大深度位2的文件