标准和错误的输入输出(重定向)对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 执行
变量名=变量值 
echo $变量名 
变量名(字母,数字,_)
不能有特殊符号,不能以数字开始 ,=两边不能有空格
调用变量 防止歧义{} 
$HOME
$PATH
$USER
$UID
$0  #当前脚本名称
$$  #脚本执行的PID 
$*  #列出所有的参数
$#  #所有的参数个数
$?  #上一条命令是否成功执行 
0代表成功执行  其余均表示未成功执行
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 
语法
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 条件测试  #判断条件是否为真
do 
命令
done
while :  #死循环
do 
命令
done
语法
case 变量 in
值1)
命令;;
值2)
命令;;
*)
命令;;
esac
#当有多个命令时  只有最后一个命令后加;; 双分号
case 只能实现字符串的匹配  不能进行逻辑判断 
case简单 功能少
if功能多 多次判断比较麻烦 
给一段代码取个别名
一个函数可以执行多个命令 
定义函数 
函数名(){
代码 命令
}
调用函数
函数名
echo -e 
-e extend 
3X 字体色
4X 背景色
0X 样式
中断[break,continue,exit]
continue  #结束本次循环 跳到下一循环
break  #结束整个循环
exit  #结束脚本
+ - * / %(求模 除后取余数)
整数运算
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=x2
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
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次
原文:http://blog.51cto.com/2168836/2103357