shell脚本基础
终端:附着在终端的接口程序
GUI:KDE,GNome,Xfce
CLI: /etc/shells
bash zsh fish
bash的特性:
命令行展开
命令别名:alias,unalias
文件名通配:glob
快捷键:Ctrl+a, e,k,l,u
命令补全:$PATH 根据路径下的命令查找
路径补全:根据开头,在指定路径下查找
bash特性之:命令hash —>缓存之前执行过的命令结果(缓存):key-value
如果有唯一一个与用户输入的打头字母匹配的,自己匹配
如果有多个匹配的,按俩下tab,显示所有
hash是一个内部命令,内部命令没有hash结果
-r :清空hash表
-d :删除
bash特性之:变量
程序:指令+数据
数据:IO设备,文件,管道,变量:(变量名—>内存中空间)
程序:算法+数据结构
变量赋值:name=value
变量类型:存储格式,表示数据范围,参与的运算
bash :弱类型的语言 ——> bash把所有变量通通视为字符型
num1=123 , cstr1=34 :能自动的转换成相同的类型
bash不支持浮点数据,除非借助外在工具
bash中的变量无需事先声明
变量替换: 把变量名出现的位置,替换为其在内存空间中的数据
$(var_name),括号多数情况下可以省略: $var_name
bash 变量类型:
本地变量 :作用域范围为当前shell的变量
环境变量 : 作用域为当前shell进程及子进程
局部变量 : 当前shell进程中的某代码片段(函数上下文)
位置参数变量 :向执行脚本的shell进程传递的参数
特殊变量 :shell内置的有特殊功用的变量 $? (保存上一个命令的执行状态结果)
本地变量:
变量赋值:name=value
变量引用: ( n a m e ) , (name), (name),name
“” :变量名会替换为其值
‘’ :不会替换
查看变量:set
撤销变量:unset 变量名
环境变量:
变量赋值:(1)export name=value
(2)name=value
export name
(3)declare -x name=value
变量引用: ( n a m e ) , (name), (name),name
注意:bash 内嵌了许多环境变量(全大写),用于定义了bash的工作环境
PATH,HISTSIZE,HISTFILE ,UID,SHELL,HOME,PWD
查看环境变量有哪些:declare , printenv,env
只读变量:不支持重新赋值,不支持撤销,随shell进程的终止而终止
declare -r name
readonly name
bash特性之多命令执行:
~]# command1;command2;command3;…
逻辑运算:
运算数:真(true,yes,no,1,0)
与:&& :左边文件执行失败,右边就不会执行(短路法则)
或:|| :id user1 || useradd user1 左边的成功,右边的不执行
非: !
shell脚本编程
编程语言:根据运行方式:
编译运行:源代码->编译器–>程序文件
解释运行:源代码->运行时启动解释器,右解释器边解释边执行
根据编程过程中功能的实现是调用库还是调用外部的程序文件:
shell脚本编程 :
利用系统上的命令及编程组件进行编程
完整编程:
自己能通过库和编程组件进行编程
编程模型:过程式编程语言,面向对象编程语言
程序=指令+数据
过程式:以指令为中心来组织代码,数据是服务于指令的
顺序执行:
选择执行
循环执行
代表:c,bash
对象式:以数据为中心来组织代码,指令是服务于数据的
类:实例化对象,和静态方法组成
代表:java,c++,Python
如何编写Shell:
脚本文件第一行:顶格:给出shebang:解释器路径,用于解释执行当前脚本的解释器程序文件
常见的解释器:
#!/bin/bash
#!/usr/bin/python
#/usr/bin/perl
文本编辑器:nano
行编辑器:sed
全屏幕编辑器:namo,vi,vim
运行脚本会出现的问题:
如果脚本中出现一个错误,就会推出整个脚本。
所以脚本中需要不断对脚本执行的判断。
shell脚本是什么:
命令的堆积:
但是很多命令不具有幂等性,需要用程序逻辑进行判断运行条件是否满足,以避免其运行中发生错误
运行逻辑:选择执行,循环执行
运行脚本:
(1):赋予权限,并直接执行此程序文件
(2):直接运行解释器,将脚本以命令行参数传递给解释器程序
bash的配置文件:
俩类:profile类,bashrc类
profile类:为交互式登录的shell提供配置
bashrc类:为非交互式登录的shell进程提供配置
交互式登录:直接通过某终端登录(通过账号和密码)。使用su命令:su - USERNAME su -l USERNAME 执行的登录切换是交互式登录。
非交互式登录切换:su USERNAME , 在图形界面下打开的终端是非交互式登录,运行脚本的时候
profile类文件:
全局配置:对所有用户都生效
/etc/profile
/etc/profile.d/*.sh
用户个人:对用户个人生效
~/.bash_profile
功用:1.用来定义环境变量 2.用来运行初始化命令和脚本
bashrc类文件:
全局:/etc/bashrc
用户个人:~/.bashrc
功用:1.用来定义本地变量 2.用来定义命令别名
只有管理员才能定义全局配置文件。
配置文件读取次序:
交互式登录shell进程:1.先读/etc/prfile-> /etc/profile.d/* -> .bash_profile->.bashrc->/etc/bashrc 。
非交互式shell进程:1. ~.bashrc->/etc/bashrc->/etc/profile.d/*
命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期
配置文件定义的特性,只对随后新启动的shell进程有效
让通过配置文件定义的特性立即生效:
(1)通过命令行重复定义一次
(2)让shell进程重新读配置文件: source /PATH/FROM/CONF_FILE
文本处理工具:
Linux上文本处理三剑客:grep sed awk
grep:文本过滤工具(模式:pattern)工具
sed :(stream editor) ,流编辑器:文本编辑工具
awk :Linux上的实现为gawk,文本报告生成器(格式化文本);
正则表达式(regual Expression) REGXP:这三个工具都会用到
由一类特殊字符及文本字符所编写的模式,期中有些字符不表示其字面意义,而是表示控制或通配的功能。
分俩类:(元字符不同:
\(hello[[:space:]]\+\)\+
1.基本正则表达式:BRE
2.扩展的正则表达式:ERE
grep :Global search REgular expression and Print out the line :基于文本过滤式
作用:文本搜索工具,根据用户指定的模式(过滤条件),对目标文本逐行进行匹配检查。打印匹配到的行。
模式:由正则表达式的元字符及文本字符编写出的过滤条件
正则表达式引擎(正则表达式处理器):perl语言的正则表达式引擎工具特别强
grep命令的用法:
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
OPTIONS :
--color=auto:颜色,默认选项
-i :忽略字符的大小写
-o :仅显示匹配到的字符串本身,而不是整行
-v :反向显示(显示不能被模式匹配到的行
-E :支持扩展的正则表达式元字符
-q : 不输出任何信息; --quiet, --silent :静默模式,会用到 $?
-A # :显示该行的后几行
-B #:显示该行的前几行
-C #: 显示前后各#行
基本正则表达式或元字符:
字符匹配:
. : 匹配任意单个字符
[] :匹配指定范围内的任意单个字符
[^] :匹配指定范围外的任意单个字符
[[:digit:]] [[:lower:]] [[:upper:]] [[:alpha:]] [:alnum:] [:punct:] [:space:]
匹配次数:用在要指定其出现的次数的子符的后面,用于限制其签名字符出现的次数。默认工作于贪婪模式。
* :匹配器前面的字符任意次:0,1,多次
.* :匹配任意长度的字符 :
? :匹配其前面的字符0次或一次:即其前面的字符是可有可无的
\+ :匹配其前面的字符1次或多次
\{m\}匹配其前面的字符m次
\{m,n\} :匹配其前面的字符至少m,至多n次
\{0,n\} :至多n次
位置锚定 :
^ :行首锚定:用于模式的最左侧
$ :行位锚定 :用于模式的最右侧
^pattern$ :用pattern匹配整行
^$ :空白行;
1*$ :空行,或包含空白字符的行
单词:非特殊字符组成的连续字符(字符串),包括单词:
\< 或 \b :锚定词首,用于单词的左侧
\> 或\b :锚定词尾,用于模式的右侧
\< pattern \> :用于锚定完整单词
练习:1.显示/etc/passwd 中不以/bin/bash 结尾的行
2.找出/etc/passwd中俩位数或三位数
3./etc/rc.d/rc.sylint至少一个空白字符开头,其后面存在非空白字符的行
4.找出“netstat -tan"命令的结果总以”LISTEN后缀0,1或多个空白字符结尾的行。
1.grep -v "bin/bash" /etc/passwd
2.grep "\<[0-9]\{2,3\}\>" /etc/passwd
3.grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
4. netstat -tan | grep "LISTEN[[:space:]]*$"
分组及引用:
xy*ab :y出现0次到多次
如果向让xy一起出现0次到多次
\(xy\)*ab :转意字符 \(\):转义括号,将一个或多个字符捆绑在一起,当做一个整体进行处理。
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量为:
\1 :模式从左侧起,第一个左括号与之匹配的右括号自己的模式所匹配到的字符
\2 :模式从左侧起,第二个左括号与之匹配的右括号自己的模式所匹配到的字符
...
He loves his lover.
He likes his lover.
She likes her liker.
She loves her liker.
~]# grep "^\(root\).*\1" /etc/passwd :后项引用 :引用前面的分组括号中模式所匹配到的字符。
egrep 命令:默认支持扩展表达式,-g :支持基本表达式, == grep -E
fgrep 命令:不支持正则表达式 ==grep -f
egrep :支持扩展的正则表达式
扩展的正则表达式:
字符匹配:
. :
[] :
[^] :
次数匹配:
* :任意次
? :0次或一次
+ : 其前面字符至少一次
{m} :其前字符m次
{m,n}:至少m,至多n
位置锚定
一样
分组及引用:
():分组
后向引用: \1 \2 …
或: a|b :a或者b
文本查看及处理工具: wc,cut ,sort,uniq,diff ,patch
wc : word count 行数 ,单词数,字节数
-l :行数
-w :单词数
-c :字节数
cut : cut - remove sections from each line of files :文本截取工具
用法:cut OPTION… [FILE]…
-d :设置以什么分隔符
-f :挑选出的字段
#:单个
#-#:连续多个
#,#:间隔多个
sort : /etc/passwd
-t CHAR :指定分隔符
-k # :用于排序比较的字段
-n :基于数值大小排序
-r :逆序排序
-f :忽略字符大小写
-u :重复的内容只保留一次 (unique)
uniq : 报告或移除重复的行
-c :显示每行的重复次数
-u :仅显示未曾出现过的行
-d :显示重复过的行
diff : 显示文件的不同之处
patch :向文件打补丁
练习:取出ifconfig 中 eth0的ip地址
[:space] ↩︎