Shell简介
Shell是一个解释器,介于应用程序(用户)和操作系统之间的一个桥梁,负责命令的解释。
Shell语言是一种解释型语言,是程序在运行时由解释器翻译成机器语言,每一次执行都要翻译一次,效率相较于便于性语言要低,但可移植型要更好。
Shell的应用场景
Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核,如下图所示
- shell可以写一些脚本实现一个工程中自动更新;
- 自动打包、编译、发布等功能;
- 清理磁盘中空文件;
总之,一切有规律的或脚本都可以尝试使用。
Shell解析器
Linux提供的解析器 | 介绍 |
---|---|
/bin/sh | 是bash的一个快捷键方式 |
/bin/bash | bash是多数Linux默认的shell,包含的功能几乎可以涵盖shell所有的功能 |
/sbin/nologin | 表示非交互,不能登录操作系统 |
/bin/dash | 小巧,高效,功能相对比较少一些 |
/bin/tcsh | 具有C语言风格的一种shell,具有许多特性,但是也有一些缺陷 |
/bin/csh | 是csh的增强版本,完全兼容csh |
Shell中的变量
1. 常用系统变量:$HOME、$PWD、$SHELL、$USER
2. 自定义变量
基本语法:
操作名 | 操作用法 |
---|---|
定义变量 | 变量名=变量值 |
撤销变量 | unset 变量名 |
声明静态变量 | readonly 变量(静态变量不能被撤销) |
变量定义规则:
规则编号 | 规则内容 |
---|---|
(1) | 变量名称可以由字母、数字和下划线组成,但不能以数字开头,环境变量名建议大写 |
(2) | 等号两侧不能有空格 |
(3) | 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算 |
(4) | 变量的值如果有空格,需要使用双引号或单引号括起来 |
3. 特殊变量
变量名 | 功能描述 |
---|---|
$n | n为数字,$0代表该脚本名称,$1-9代表第一个到第九个参数,十个以上的参数需要用大括号括起来,如${10} |
$# | 获取所有输入参数的个数,常用于循环 |
$* | 代表命令行中所有的参数,且把所有的参数看成一个整体 |
$@ | 也代表命令行中的所有参数,但不加引号时将所有参数看成一个整体,加引号时将每个参数区分对待 |
$? | 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。 |
Shell中的运算符
运算符号 | 基本语法 | 例句 | |
---|---|---|---|
方式一 | +(加),-(减),*(乘),/(除),%(余) | $((运算式))或$[运算式] | S=$[(2+3)*4] |
方式二 | +(加),-(减),*(乘),/(除),%(余) | expr 运算式 | expr `expr 2 + 3` * 4 |
支持小数运算:例如:echo $(echo “scale=1; $a+$b” | bc)
条件判断
基本语法: [ condition ]
- condition前后要有空格
- 条件非空即为true,如[ abc ],为空则返回false,[]返回false
常用判断条件
1. 两个整数之间的比较
符号 | 作用 |
---|---|
-lt | 小于(less than) |
-le | 小于等于(less equal) |
-eq | 等于(equal) |
-gt | 大于(greater than) |
-ge | 大于等于(greater than) |
-ne | 不等于(not equal) |
2. 按照文件权限判断
符号 | 作用 |
---|---|
-r | 有读的权限 (read) |
-w | 有写得权限 (write) |
-x | 有执行的权限(execute) |
3. 按照文件类型进行判断
符号 | 作用 |
---|---|
-f | 文件存在并且是一个常规文件 (file) |
-e | 文件存在 (existence) |
-d | 文件存在并且是一个目录(directory) |
流程控制
1. if 判断
基本语法一般有两种用法:
(1)
if [ 条件判断式 ];then
程序段
fi
(2)
if [ 条件判断式 ]
then
程序
elif
then
程序
else
程序
fi
注意事项:
(1) 中括号和条件判断式之间必须要有空格
(2) if后边要有空格
2. case语句
基本语法:
case $变量名 in
"值1")
程序1 (如果变量值等于值1,则执行程序1)
;;
"值2")
程序2 (如果变量值等于值2,则执行程序2)
;;
...
*)
程序0 (如果变量值都不是以上的值,则执行程序0)
esac
注意事项:
(1) case行尾必须为单词 “in” ,每一个模式匹配必须以右括号 “)” 结束;
(2) 双分号 “;;” 表示命令序列的结束,相当于java中的break;
(3) 最后的 “*)” 表示默认模式,相当于java中的default;
3. for 循环
基本语法(1)
for((初始值;循环控制条件;变量变化))
do
程序
done
注:for括号内的写法同C、JAVA一致;
基本语法(2)
for 变量 in val1 val2 val3
do
程序
done
注:in后边的多个变量值可以是 $*、$@、"$*"、"$@"
4. while 循环
基本语法:
while [ 条件判断式 ]
do
程序
done
注: while 后必须要空格;
Shell文本处理工具
1. cut: 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
基本用法: cut [选项参数] filename
选项说明:
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符分隔列 |
-c | 指定具体的字符 |
2. sed: 是一种流编辑器,一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把换乘区的内容送往屏幕,接着处理下一行,这样不断重复,直到文件末尾。文件内容不发生改变,除非使用重定向存储输出。
基本用法: sed [选项参数] 命令参数 filename
选项参数说明
选项参数 | 功能 |
---|---|
-e | 直接在指令列模式上进行sed的动作编辑(一次执行多个操作) |
-i | 直接编辑文件 |
命令参数说明
命令 | 功能 |
---|---|
-a | 新增,a的后面可以接字符串,在下一行出现 |
-d | 删除 |
-s | 查找并替换 |
3. awk: 把文件逐行读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。
基本用法: awk [选项参数] ‘pattem1 {action1} pattem2 {action2} …’ filename
选项参数说明:
选项参数 | 功能 |
---|---|
-F | 指定输入文件拆分分隔符 |
-v | 赋值一个用户定义变量 |
awk的内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读取的记录数 |
NF | 浏览记录的域的个数(切割后,列的个数) |
4. sort: 将文件进行排序,并将排序结果标准输出。
基本语法: sort (选项) (参数) 文件名
选项 | 说明 |
---|---|
-n | 依照数值的大小排序 |
-r | 以相反的顺序排序 |
-t | 设置排序时所用的分隔符 |
-k | 指定需要排序的列 |
一些Shell编程题
1、写一个脚本,给脚本传递3个参数 两个数字(不区分运算符的位置),一个运算符,根据运算符计算出结果,例如 2 3 - 2-3=1
j=1
s=0
for i in "$@"
do
if [ "$i" = "*" ]
then
s="$i"
else
s=$(echo "$i" | grep [^0-9] || echo "")
fi
if [ "$s" ]
then
arr[0]="$i"
else
arr[$j]=$i
j=$[$j+1]
fi
done
echo "${arr[*]}"
2、写出一个脚本程序,给定一个文件,比如:/root/class21/inittab.txt
a、判断这个文件中是否有空白行? b、如果有,则显示其空白行的总行数,否则显示没有空白行
awk -v i=0 '/^$/{i=i+1}END{if(i>0){print "空白行总数为:" i}else{print "没有空白行!"}}' /root/class22/inittab.txt
3、判断/root/class22/inittab.txt文件是否大于100行,如果大于,则显示”inittab is a big file.”否者显示”inittab is a small file.”
awk 'END{if(NR>100){print "inittab is a big file."}if(NR<=100){print "inittab is a small file."}}' /root/class22/inittab.txt
4、写一个脚本输入任意数组或则数字例如 2 4 3 5 9 7 8 6,按照从小到大排序后输出
i=0
for j in "$@"
do
arr[$i]=$j
i=$[$i+1]
done
a=0
b=0
for((k=0;k<$[$#-1];k++))
do
for((h=0;h<$[$#-$k-1];h++))
do
b=$[$h+1]
if [ ${arr[$h]} -gt ${arr[$b]} ]
then
a=${arr[$h]}
arr[$h]=${arr[$b]}
arr[$b]=$a
fi
done
done
echo "从小到大排序为:${arr[*]}"