什么是shell 解释器 解释器的总称 bash 解释器 某一种解释器 ]# cat /etc/shells #查看已装的解释器 useradd -s #创建用户并指定解释器 usermod -s #修改用户的解释器

标准和错误的输入输出(重定向)对shell很重要

输出

默认输出 屏幕 1正确输出 #重定向>(覆盖) >>(追加) 2错误输出 #重定向2> 2>>(追加) #正确错误都重定向&> &>>(追加)

输入

默认输入是键盘 可以使用< 例如 发邮件 mail -s test root #交互式 echo test | mail -s 'test' root #非交互 mail -s 'test' root < mail.txt #非交互

管道“|”

将前一个命令的输出结果 传给后一个命令 作为参数 管道 把多个命令组合在一起完成一个大的功能
Linux 的命令 一般都比较 small simple 优点 漏洞少 速度快 缺点 功能少

新建脚本

1 新建文件 (.sh) 2 写代码 #!/bin/bash #解释器 解释器要与下面的代码对应 #注释 [作者 邮箱 功能描述] 代码 3 执行 #给权限x 执行

变量

1 自定义变量

变量名=变量值 echo $变量名 变量名(字母,数字,_) 不能有特殊符号,不能以数字开始 ,=两边不能有空格 调用变量 防止歧义{}

2 系统变量

$HOME $PATH $USER $UID $0 #当前脚本名称 $$ #脚本执行的PID $* #列出所有的参数 $# #所有的参数个数 $? #上一条命令是否成功执行 0代表成功执行 其余均表示未成功执行

3 read变量

read -p '提示' 变量 只定义变量 不赋值 使用者自行赋值

三种引号

单引 #界定一个完整的字符串 并且可以屏蔽特殊符号

echo "a b" = echo 'a b' #a=11 #b=22 #echo "$a $b" 11 22 #echo '$a $b' $a $b

双引 #使用双引号可以界定一个完整的字符串

#touch a b #创建两个文件 a和b #touch "a b" #创建一个文件 "a b" echo a b != echo "a b" echo ab == echo "ab"

反引 命令 $(命令) 反引号引用命令,提取命令的结果

#tar -zcf log-date +%F.tar.gz /var/log #ls log-2017-12-22.tar.gz

  • 局部变量 a=11
  • 全局变量 export a=11
  • 系统变量一般是全局的

for 循环

语法 for 变量名 in 值列表 do 命令序列 done

#echo {1..5} #横排 #seq 10 #1-10 竖排 #seq 5 10 #5-10 for i in {1..5} #只能用常量 for i in seq 10 #可以使用常量和变量

while 循环

语法 while 条件测试 #判断条件是否为真 do 命令 done

while : #死循环 do 命令 done

case 简化的if

语法 case 变量 in 值1) 命令;; 值2) 命令;; *) 命令;; esac #当有多个命令时 只有最后一个命令后加;; 双分号 case 只能实现字符串的匹配 不能进行逻辑判断 case简单 功能少 if功能多 多次判断比较麻烦

函数

给一段代码取个别名 一个函数可以执行多个命令 定义函数 函数名(){ 代码 命令 } 调用函数 函数名

echo -e -e extend 3X 字体色 4X 背景色 0X 样式

中断[break,continue,exit] continue #结束本次循环 跳到下一循环 break #结束整个循环 exit #结束脚本

shell 运算&判断

+ - * / %(求模 除后取余数) 整数运算 expr 数字1 符号 数字2 #数字与符号之间必须空格 * 乘法运算 * *前面加反斜线屏蔽 支持变量

echo #[数字1+数字2] 支持变量 #x=5 #y=7 ]# echo $[x=y]

let #运算不显示结果 x++ x=x+1 x-- x=x-1 x+=2 x=x+2 x+=5 x=x+5 x*=2 x=x*2 x/=2 x=x/2

]# x=1 ]# y=2 ]# let z=x+y ]# echo $z 3

]# x=1 ]# let x++ ]# echo $x 2

小数运算 bc scale=2 #保留小数点后两位 #echo "1+1" | bc #echo "1.1+2.2;2.2+3.3" | bc #使用分号隔开 可以进行多个运算 #echo "scal2=2;3.3/4" | bc #先指定保留小数点的位数 再进行运算 #echo "3>2" | bc #逻辑运算 1为正确 0为错误

判断 字符串判断 数字 文件或者目录 判断的语法 [ 判断的表达式 ] #注意:空格 test 判断的内容 1 字符串 格式 [ "abc" == "abc" ] #脚本中至少有一个是变量 [ "abc" == "abc" ] 相等 [ "abc" != "abc" ] 不等 [ -z $test ] 是否为空 ]# [ -z $test ] #问 test这个变量是空的吗 ]# echo $? 0 #空的

在一行里打多个命令 ; && || A && B #执行A 仅当A成功 才执行B A || B #执行A 仅当A失败 才执行B A ; B #执行A 执行B

]# [ root == root ] && echo Y || echo N Y ]# [ root == tom ] && echo Y || echo N N ]# [ root == $USER ] && echo Y || echo N Y ]# [ root == $PATH ] && echo Y || echo N N

2 数字判断 -eq #等于 equal -ne #不等于 not equal -gt #大于 greater than -ge #大于等于 greater or than -lt #小于 less than -le #小于等于 less or equal

3 文件或者目录判断 -e #是否存在(exist) -f #是否存在 且为文件(file) -d #是否存在 且为目录(directory) -r #是否可读 -w #是否可写 -x #是否可执行 #不论权限如何 root对任何文件均可读写 但是如果没有执行权限时 则无法执行

]# [ ! -d /abc ] &&mkdir /abc ]# [ -d /aaa ] || mkdir /aaa

if 语法

1 单分支 #只能判断对 if [ 判断 ] ; then 命令 fi

if [ 判断 ] then 命令 fi #命令放到一个文件中 [ 脚本 ]

2 双分支 #能判断对错 if [ 判断 ] ; then 命令 else 命令 fi

3 多分支 #多次判断 if [ 判断1 ] ; then 命令 elif [ 判断2 ] ; then 命令 elif [ 判断3 ] ; then 命令 else 命令 fi

字符串的截取以及切割

${var:起始位置:长度} ${X:0:4} ${X:3:6} ${x::6} #如果起始位置是0 可以省略

expr substr $变量 开始 长度

echo $变量 | cut -b 开始位置-结束位置 echo $x | cut -b 2-5 echo $x | cut -b 3,8,11

变量中字符串替换 ${X/3/} #只替换第一个 ${X//3/} #将所有的3替换成星 #替换不影响原变量的值

字串中的删除 掐头 去尾 ${变量#} #掐头 ${变量%} #去尾 echo ${X#:} #找最近的冒号 echo ${X##:} #找最远的冒号 echo ${X%:} #找最近的冒号 echo ${X%%:} #找最远的冒号

${变量:起始位置:长度} #截取 ${变量/old/new} #替换 ${变量#} #掐头 ${变量%} #去尾 ${变量:-} #初始值

变量赋初始值

看变量有没有值 如果有 就直接用 如果没有 就给初始值 echo {变量:-值} #注意值前面要加一个减号 #X=123 #echo {X:-test}

数组

#一个变量存多个值 定义 x=(11 22 33 aa bb cc) 调用 echo ${x[0]} echo ${x[1]} echo ${x[2]} echo ${x[*]} #查看数组所有的值 echo ${x[@]} #查看数组所有的值

x[0]=11 x[1]=22 x[2]=33

非交互式发邮件 vim test.sh #不需要邮件文件 内容简单 mail -s error root < mail.txt #需要一个邮件文件 mail -s error root << EOF
内容 EOF

End of File 习惯的开头和结束 也可以为其他 但首尾须一致 邮件位置 /var/spool/mail/用户名

expect 期待 预设脚本中的交互 ]# yum -y install expect

正则表达式

#使用特殊符号去表达的一种方式 基本正则 ^ #开始 $ #结尾 [ ] #集合 取之一 [abcdef56789] == [a-f5-9] == [5-9a-f] [^] #对集合取反 . #任意单个字符 * #匹配前一个字符出现了任意次 .* #任意所有 不限定长度 \{n,m\} #匹配前一个字符出现了n到m次 \{n,\} #匹配前一个字符出现了n以上次数 \{n\} #匹配前一个字符出现了n次 \(\) #保留(复制)

扩展正则 #简化基本 扩展新的 使用 grep -E /egrep \{2,5\} {2,5} \(\) () #保留 (复制) \1 #把第一个内容粘贴 *任意次 ? 前面的字符出现了0或1次 + 前面的字符出现了至少一次 ()整体 (abc)+ #前面的abc 出现了至少一次 | 或者 (test|taste) \b 单词边界 扩展正则:简单 兼容性差 不一定每个软件都支持扩展正则 基本正则:麻烦 兼容性强 能支持正则的软件基本都支持