1.shell脚本的创建和执行
创建一个文件
写一个shell脚本
上面这种方法不常用,常用下面
所有可执行文件是绿色
绝对路径
相对路径
在该文件下运行.sh文件
souce 要在该文件的文件夹下执行
. hello.sh和./hello.sh是完全不同的,点+空格是点命令
2.变量
变量的划分一种可以分为系统变量、用户自定义变量
一种可以分为全局变量(对于当前shell,在里面再启动一个子shell,子shell里可以再嵌套,迭代下去,所有的都是可见的),局部变量(只针对当前shell是可见的)
2.1系统预定义变量
查看当前home,查看当前所有的全局变量
2.2自定义变量
注意:“a=2” 没有空格,shell直接解析成变量赋值表达式
有空格,所以shell找不到
输入bash,会进入到子bash里,这个新的子bash shell会继承父shell的环境变量,但是在子shell做的任何更改(例如更改环境变量)都不会影响到父shell。当在子shell中执行exit命令或者使用Ctrl+D退出时,会返回到父shell
进入子shell里找不到my_var,说明my_var是局部变量,通过这种方法定义的变量是局部
怎么定义全局变量?
先声明一个局部变量,在父dhell申明这个局部变量,就成全局
更改只在子shell有效
在子shell申明的不会影响到父shell
在脚本文件里(.sh)
定义局部变量,写到脚本文件会不会输出?
如果./hello.sh不会输出该局部变量,输出空白(除非变成全局变量,export)
如果. hello.sh会输出,
自定义的变量名最好是小写,因为系统预定义的是大写,默认定义的数值是字符串。
只读变量的定义
撤销一个变量
只读变量不能unset
2.3特殊变量
把hello.sh当命令执行
但不建议这么做
更好的方法:不改变bin目录,而且能把hello.sh当命令执行
$n变量
只获取当前脚本名称,不带路径用basename
$#变量
$*、$@ 变量
$?变量
3.运算符
1)基本语法
“$((运算式))”或“$[运算式]”
转换:
反引号 shift+~
用调用的
4.条件判断
判断a的值是不是hello,是真返回0,假返回1
$a = hello 等号两边一定要用空格隔开
不等号 $a != hello
整数判断
多条件组合判断
&& 表示前一条命令执行成功时,才执行后一条命令;||表示上一条命令执行失败后,才执行下一条命令
[ $ a -lt 20 ]为真,就运行 echo “$a < 20”, [ $ a -lt 20 ]为假,就运行 echo "$a >= 20"
[ ]有内容为真,无内容为假的。
5.流程控制(重点)
5.1if判断
分号;:将两个命令隔开
1)单分支(逻辑为真,执行这段代码,为假,则跳过这段逻辑)
-gt是大于
用shell脚本跑
期待一元表达式的解决方法:
报错是因为a没有被赋值,(ps:断开连接后之前定义的局部变量就没有了?)
想要把条件写在一起, -a逻辑与(and)&&,-o(or)逻辑或||
2)双分支(条件为真是一边,为假是一边)
3)多分支
5.2case语句
5.3for循环
从1加到输入的数
上面那个报错原因,头少写一个斜杠,for里面是分号隔开,我用错成,
为什么这里可以用"<=",这里用了(()),所以可以
{}:表示一个序列
要用引号吧 引起来“$*” “$@”
5.4while循环
# 更人性化写法
6.read读取控制台输入
7.函数
调用系统命令的时候要用$(系统命令) ,达到一种命令替换的状态
7.1系统函数
1)basename
basename只保留最后一个斜杠的内容,本质就是字符串的剪切
用了basename后的parameter
得到的是当前脚本名称,而且不带后缀
2)dirname
7.2自定义函数
有返回值的
报错
正确的
return直接给$s的话,只能返回0~255的值,how to solve?
8.综合应用案例
归档文件
重要数据的归档
9.正则表达式入门
正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在Limnux中,grep,sed,awk等文本处理工具都支持通过正则表达式进行模式匹配。
9.1常规匹配
9.2常用特殊字符
筛选以a开头的所有 ^a
筛选以bash结尾的所有 bash$
只有^$,匹配空行
^atbash$表示以at开头以bash结束的文件,
显示所有空行并显示行号
找到以r隔俩字符以t结尾的r..t
*某一个字符出现任意次
".* "任意字符出现任意次
以a开头,以bash结尾的所有
筛选手机号码
grep不支持和{}一起用,得要用-E
10.文本处理工具
10.1cut(在文件中负责剪切数据)
截取第一列
截取第2,3列
截取1,6,7列
分别为,截取1-4列,截取后四列,截取前四列
截取ip地址
10.2 awk
1)搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第7列。
F1:先grep行的提取,再cut列的提取
2)搜索 passwd 文件以root 关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名 user shell 在最后一行添加"dahaige,/bin/zuishuai"。
注意:BEGIN 在所有数据读取行之前执行;END在所有数据执行之后执行。←
4)将 passwd 文件中的用户id 增加数值1并输出
F2
awk的内置变量
3)切割IP
11.综合案例
发送消息
我们可以利用 Limux 自带的 mesg 和 write 工具,向其它用户发送消息。
需求:实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。
who -T可以查看是否可以接收消息,有+表示可以接受
给david发送消息 write david pts/1 要写清楚给哪个david发
david收
脚本实现