shell总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell总结相关的知识,希望对你有一定的参考价值。
env 查看环境变量set 显示环境变量(包括局部变量)
设置环境变量:export 变量名=value
变量名=value,export 变量名
取消变量 unset 变量名
环境变量的初始化过程:
先加载/etc/profile 全局变量文件
在执行/etc/profile.d的目录下的脚本文件
运行$HOME/.bash_profile用户环境变量文件---在执行$HOME/.bashrc
单引号:里面是什么就输出什么,六亲不认
双引号:会解析变量的
需要将命令的结果作为变量内容:
用单引号~~ cmd=ls
或者() CMD=$(ls)
在使用awk的时候,我们习惯先用echo 加符号输出变量在通过管道给awk,进而控制变量输出结果
echo $quan |awk ‘{print $0}‘
QQQQ
echo "$quan" |awk ‘{print $0}‘
QQQQ
echo ‘$quan‘ |awk ‘{print $0}‘
$quan
定义变量的技巧:
变量名只能为字母、数字或下划线,只能字母或下划线开头
驼峰写法
shell中的特殊变量:
特殊的位置参数: $0 $1 $2 ....${10} ${11}
$0当前执行shell脚本的文件名
$# 获取当前执行shell脚本的总参数个数
$ 所有参数 加双引号"$" 所有参数视为一个字符串
[email protected] 不带双引号的时候都是一样,带了双引号后,还是分别为字符串
set 可以设置位置变量参数:set -- “I am” handsome boy
$1 $2 $3
shift 可以使变量位置向左移一位
shell进程中的特殊变量:
$? 上一条命令执行成功或失败,0为成功,非0为失败
多用于判断是否源码安装一步一步成功
$$ 获取当前进程shell脚本的进程号
$?应用:当对服务器进行备份的时候,我们会执行完关键命令后,
通过返回值确认是否数据完整
判断脚本或函数等程序是否成功
若在函数里面调用执行“exit 数字” 则会返回这个数字给“$?”变量
如果是函数里,则通过“return 数字 ” 把这个数字以函数返回值的形式给“$?”
/etc/init.d/rpcbind
bash shell内置变量的命令:echo eval exec export read shift
echo 输出信息
-n 不换行输出内容
-e 解析转义字符
转义字符:\n 换行
(加引号) \r 回车
\t tab
\b 退格
\v 纵向制表符
[root加quan油 ~]$echo quan ;echo -n zhi
quan
zhi[root加quan油 ~]$echo -n quan ;echo zhi
quanzhi
echo -e "quan\nzhi"
quan
zhi
eval args 当shell程序执行到eval语句时,shell读入参数args,并组合成新的命令再执行
exec 命令参数 在不创建子进程的前提下,执行指定的命令,执行完之后,该进程自动终止
read 从标准输入读取字符串等信息
shift:移位
运算命令:
(()) 用于整数运算的常用运算符
((i+1)) 用echo $((i=i+1))输出其值
i=$((i+1)) 将表达式运算后的值付给i
((8>7&&5==5)) 进行比较操作,用于条件判断
echo $((2+1)) 直接输出计算结果
[root加quan油 SH]$a=9
[root加quan油 SH]$echo $((a++))
9
[root加quan油 SH]$echo $a
10
[root加quan油 SH]$echo $((++a))
11
[root加quan油 SH]$echo $a
11
注意:echo $((a++)) echo $((a--)) 显示运算前的值,即a的值
echo $((--a)) echo $((++a)) 显示的是运算后的值
在(())使用变量时可以忽略变量前的$ echo $((my+1))
expr用法:expr(evaluate(求值) expression(表达式))
既可以运算整数,也可以用于字符串长度,匹配等处理
注意: 计算时,运算符和数字之间都需要空格
乘号要反斜线转义
eg:expr 9 + 1
i=`expr 9 + 1`
i=`expr $i + 1`变量需要用反引号括起
判断一个变量值或字符串是否为整数
原理:利用expr计算时变量或字符串必须为整数的规则,把变量和一个整数(非零)
相加,判断命令返回是否为0,0——成功为整数
#!/bin/bash
expr $1 + 1 &> /dev/null
if [ $? -ne 0 ];then
echo "char"
else
echo "int"
fi
判断扩展名是否符合要求 注意运算的时候都要加空格
#!/bin/bash
if expr "$1" : ".*\.sh" &>/dev/null
then
echo "thie name is right"
else
echo "you must rename to $1.sh"
fi
通过expr计算字符串的长度
#!/bin/bash
for N in quan zhi qiang
do
if [ `expr length $N ` -le 4 ]
then
echo $N
fi
done
bc 交互式计算,命令行计算
echo 9+9|bc
echo `seq -s "+" 10`=`seq -s "+" 10|bc`(其中seq为生成数字序列 -s 分隔符)
1+2+3+4+5+6+7+8+9+10=55
awk 计算小数很准确
echo "9.9 9.8"|awk ‘{print (($1-3)*$2)}‘
67.62
基于shell变量输入read命令
shell变量可以直接赋值或脚本传参外,还可以使用read命令标准输入
read 参数 变量名
参数:-p messege 设置提示信息
-t time 设置等待输入时间,单位默认为s
Shell脚本的条件测试:
最常用的为:[ 测试表达式 ] 两边必须有空格 且里面如果要使用&& || < > 这些只用在[[ ]]
需用-a -o -gt -lt 代替
[[ 测试表达式 ]]
test 测试表达式
((测试表达式))
test -f file && echo 1 ||echo false,使用&& || 带空格美观一点
[ -f /data/sh ] && echo 1 || echo false 可以使用man test 来进行表达式的书写
文件测试描述符
-d 文件 directory 文件 存在且为目录为真
-f 文件 file 文件存在且为普通文件为真
-e 文件 exist 文件存在为真
-r 文件 read 文件存在且为可读为真
-s 文件 size 文件存在且文件大小不为0为真
-w 文件 write 文件存在且可写为真
-x 文件 executable 文件存在且可执行为真
-L 文件 link 文件存在且为连接文件为真
f1 -nt f2 newer than 文件1比文件2 新。以文件修改时间为准
f1 -ot f2 older than 文件1比文件2 旧 。修改时间为准
注意:测试变量的时候最好加上双引号
[ -d "$QUAN" ] && echo "yes" || echo "no"
也可以用测试描述符代替if
[ 条件1 ] && {
命令1
命令2
命令3
}
if [ 条件1 ]
then
命令1
命令2
命令3
fi
字符串测试操作符
-n "str" 字符串长度不为0为真 no zero
-z “str” 字符串长度为0 则为真
“str1” = “str2” 两个字符串相等为真 ==代替=
“str1” != “str2” 两个字符串不等为真
注意:字符串一定要用“”括起来
= != 两边要有空格
[ -n "" ] && echo "sb" || echo "bs"
bs
整数二元比较操作符
[] 和test中 (()) 和[[]]中
-eq ==或= 相等,equal
-ne != 不相等,no equal
-gt > 大于,greater than
-ge >= 大于等于 greater equal
-lt < 小于 less than
-le <= 小于等于 less equal
注意:两端还是要空格
[ $A -eq $B ] && echo "A=B" || echo "A!=B"
逻辑操作符:
[] 和 test中 [[]] 和 (())
-a &&(可用在表达式外部)
-o ||(可用在表达式外部)
-! !
企业案例:
如果传入数字等于1,就打印one 如果等于2,就打印two,其他提示输入不对并退出
#!/bin/bash
read -p "please input a number: " innum
[ "$innum" = "1" ] && { #普通字符比较多的使用字符串的语法,使用整数比较容易出错,除非确定是整数
echo "one"
exit 1
}
[ "$innum" = "2" ] && {
echo "two"
exit 2
}
[ "$innum" = "1" -a $innum = "2" ] && {
echo "input error"
exit 3
}
[[ "$A" =~ [1-3] ]] && echo 8 判断A是否为1或2或3,用到通配符,使用[[]]
8
if条件语句
单分支格式:if 条件测试表达式
then
指令
if
或者
if 条件测试表达式 ;then
指令
fi
多分支格式:if 条件测试表达式
then
指令集1
else
指令集2
fi
if 条件测试表达式
then
指令集1
elif 条件测试表达式
theb
指令集2
else
指令集3
fi
多分支elif的写法,每个elif后面都要then,最后一个else没有then
Shell函数
格式:function 函数名() {
指令
return n
}
函数的执行:执行不带参函数:直接输入函数名即可——不要带小括号
注意:执行时 ,函数名前的function和函数后的小括号都不带
定义在前,执行在后
return是退出函数,可以设置退出的值,给当前的程序使用
如果函数发在文件当中,可以使用source或 . 来加载使用
函数内会使用local定义局部变量,离开函数后消息
执行带参函数: 函数名 参数1 参数2
注意:shell的位置参数也可以当成函数的参数
此时父脚本的参数临时被函数参数掩盖或隐藏
$0依旧是父脚本的名称
函数的参数变量是在函数体里面定义个的
注意:实现函数和执行脚本文件分离
可以通过source或者.加载脚本functions中的命令或者参数
里面有一个函数叫action 用法如下:
action “字符串” /bin/true或者/bin/false
显示如下:字符串 [ OK ]
case条件语句:
case "变量" in
值1)
指令1
;;
值2)
指令2
;;
..
..
..
)
指令3
esac
注意:每个值之后的指令结尾要加 ;;最后一个可以不加
字符串加颜色:echo -e 可以识别转义字符,特殊字符
\e 开始颜色
[1;31m 其中1代表加粗显示(不同的数字,代表不同意思) 详细可以man console_codes
31m--37m代表设置前景色,即字符串颜色
\e[0m 关闭所用属性
\e[1m 设置高亮度
\e[4m 下划线
\e[5m 闪烁
\e[7m 反显
\e[8m 消隐
\e[30m -- \e[37m 前景色
\e[40m -- \e[47m 背景色
echo -e "\e[1;31m\e[4m "quanzhiqinag" \e[0m"
quanzhiqinag (带下划线)
注意:main $ 执行main函数,利用$*接受到的命令行的所有参数,并传入到main函数当中
while循环
格式 while 条件测试语句
do
指令
done
条件测试语句成立的时候,执行语句
until循环
until 条件测试语句
do
指令
done
测试语句不成立时进入循环语句
shell中的休息命令:sleep 1 休息一秒
usleep 1000000 休息一秒
注意: 在进行死循环的时候最好要加上sleep命令进行控制循环的频率,否者会消耗大量
系统资源
shell脚本后台运行知识
使用&后台运行脚本 sh 111.sh &
crl+c 停止执行当前脚本或任务
ctl+z 暂停执行当前的脚本或任务
防止执行脚本中断的方法:
sh 111.sh &
nohup 111.sh &
screen保持回话,在执行脚本 ,一般要先安装在使用这个命令
screen -x 加入已存在的screen回话
-ls 显示所有的screen作业
-S 指定screen作业名称创建
定义菜单类型的范范:
cat <<END
===================
===================
END
while按行读取文件的方法:
exec读取文件
eg:exec <file
sum=0
while read line
do
cmd
done
cat读取文件:
cat file |while read line
do
cmd
done
while结尾done处通过输入重定向读取文件
while read line
do
cmd
done<file
总结:while主要是执行守护进程,适用于频率小于1分钟循环处理,加sleep 和usleep控制频率
case语句,主要用于系统启动脚本时传入少量固定规则字符串的情况下
打印菜单,多适用于cat here 文档替换
for循环——主要用于执行有限次的循环
for 变量名 in 变量取值列表(可以空格隔开)
do
指令
done
打印乘法口诀的结果
#!/bin/bash
for n1 in seq 1 +1 9
do
for n2 in seq 1 +1 9
do
if [ $n1 -ge $n2 ]
then
echo -n "$((n1*n2)) "
fi
done
echo ""
done
注意 echo -n " "
生成随机数的犯法;
1)使用系统变量$RANDOM 0-32767 加密性不好,利用md5sum并截取需要的位数
echo "$RANDOM" |md5sum|cut -c 1-8
2)通过openssl产生随机数
openssl rand -base64 8
3)通过时间date 获得随机数
date +%s%N %s从linux系统开始到现在的秒数,%N纳秒
4)通过UUID生成随机数
UUID全称为通用唯一识别码(Universally Unique Identifier,UUID)
是一个软件建构的标准,亦为自由软件基金会Open Software Foundation OSF
的组织在分布式计算环境Distributed Computin Environment DCE领域的一部分
cat /proc/sys/kernel/random/uuid
5)expect附带的mkpasswd生成
mkpasswd命令依赖于expect 必须安装
mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
-l 指定密码长度 默认为9 length
-d 指定密码中的数字数量 默认为2 digits
-c 指定密码中小写字母的数量 默认为2 lowercase chars
-C 指定密码中大写字母的数量 默认为2 upper chars
-s 指定密码中的特殊字符数量 默认为1 special chars
以上都必须有
Select 循环介绍
主要用于显示菜单
select 变量名 in 变量取值列表(可以空格隔开)
do
cmd
done
eg:select name in a b c d
do
echo $name
done
显示为:1) a 自动加标号
2) b
3) c
4) d
#? 这个是默认提示符
其中:PS3 就是控制select循环的提示符的变量
REPLY 就是菜单项对应的数字 即用户输入的数字变量
PS3="echo "please input the num you want:"
"
select CH in "install lamp" "install lnmp" "quit"
do
case $CH in
"install lamp")
Install lamp
;;
"install lnmp")
Install lnmp
;;
"quit")
echo "see you"
return 3
;;
*)
echo "input Error"
esac
done
Shell脚本后台运行
sh fiel.sh & 后台运行
ctl +c 停止
shell 数组
定义: 1) array=(quan zhi qiang) 每个变量值之间要用空格进行分隔
2) 动态定义数组:array=($(命令))
或者 array=(命令
)
打印数组元素:echo ${array[i]} i是从零开始的
echo ${array[*]} 整个数组的内容
echo ${#array[*]} 数组元素的个数
数组的删除:unset 数组[下标]
不加下标,默认是清除整个数组所有的数据
数组的截取和替换:
截取:echo ${array[*]:1:3} 从下标为1的元素开始截取,共截取3个数组元素
数组的替换:
echo ${arary[*]/1/b} 将数组中的1 替换成为b
${数组名[*或@]/查找字符/替换字符}
注意:该操作不会改变原先数组的内容,于sed修改
脚本开发的规范:、
1) 第一行为 使用的脚本解释器
2)最好加上版本版权等信息
3)尽量不使用中文注释,如果非要加中文 export LANG="zh_CN.UTF-8"
4) 脚本的扩展名应给为.sh
模块的启动和停止脚本命名:start_模块名.sh stop_模块名.sh
监控脚本通常以 _mon.sh 为后缀
控制脚本一般以 _ctl.sh 为后缀
5) 脚本应该放在固定的路劲下
6) 成对的括号一次性打出来
7) 流程控制语句一次性格式写完,再写内容
8) 字符串赋值时,等号左右不能有空格
9) 设当的缩进使代码美观可读
10)全局变量应该全部大写 SHELL 局部变量最好使用驼峰法Shellquan 即单词首字母大写
11)变量前后有字符使用{} 来引用变量 变量为字符串时 加双引号"${QUAN}"
变量为整数时,最好直接使用 $QUAN
12) 函数命名 单词首字母大写 TestUtl 最好都加上return
13)尽量把功能进行子函数的封装
14)缩进的规范:一般使用四个空格缩进
脚本调试的方法:
使用dos2unix 命令来格式化windows下开发的脚本 dos2unix file.sh
1)使用echo命令调试:一般在可能出错的地方,特别是变量附近
加入echo 输出 变量 并退出exit 不在执行以下的命令
2)使用bash命令参数调试
sh [-nvx] file.sh
-n 不会执行该脚本,仅查询脚本语法是否有问题,并给出错误
-v 先将脚本输出,在执行脚本,有错误则暑促错误
-x 将执行脚本内容及即时输出显示到屏幕上,最有用的参数
注意:程序段会前面会显示+ 表示为程序代码 由PS4决定
PS4=‘+${LINENo}‘ 显示行号
3)用set 命令调试部分脚本
set -n
set -v
set -x 开启调试功能
set +x 关闭调试功能
直接将set -x set +x 加入脚本中需要调试的位置,运行脚本就无需 sh -x 了
shell脚本开发环境的配置和优化实践
vim 编写sh脚本自动添加注释:
autocmd BufNewFile .py,.cc,*.sh, exec ":call SetTitle()"
func SetTitle()
if expand("%:e") == ‘sh‘
call setline(1, "#!/bin/bash")
call setline(2, "####################################################")
call setline(3, "#DATE: ".strftime("%F-%T"))
call setline(4, "#NAME: ".expand("%"))
call setline(5, "#AUTHOR: QuanZhiQiang")
call setline(6, "#E-MAIL: [email protected]")
call setline(7, "#TEL: 13145710069")
call setline(8, "####################################################")
endif
endfunc
linux中的信号以及trap命令
信号是由一个整数构成的异步消息,由某个进程发给其他进程,也可以是用户特定键发生的异常事件
由系统发给某个进程
信号列表:kill -l 或者 trap -l 命令 可列出各种信号
HUP 1 挂起,通常因终端掉线或用户退出引发
INT 2 中断,通常因按下Ctrl+c 组合键引发
QUIT 3 退出,通常因按下Ctrl+\ 组合键引发
ABRT 6 中止,通常因某些严重的执行错误引发
ALRM 14 报警,通常用来处理超时
TERM 15 终止,通常在系统关机时发送
TSTP 20 停止进程的运行,但该信号可以被处理和忽略,通常因按下Ctrl+z组合键引起
通常需要忽略的信号包括:
HUP INT QUIT TSTP TERM ,脚本中可以使用数字也可以使用信号名字
trap命令用于指定,接受到信号后将要采取的行动
常见用途是在脚本程序被中断时完成的清理工作,或者屏蔽用户非法使用某些信号,
注意:在使用信号名时,需要省略SIG前缀
trap cmd signal
cmd:是接受到信号应该采取的行动,命令可以用;隔开 signal 接收到到的信号
eg:trap ’echo quan ‘ 2 注意:一定是单引号
用stty -a 可以列出中断信号与键盘对应的信息
trap ‘’ 2 屏蔽信号 单引号里面不用填东西
trap ‘:’ 2 恢复信号,单引号里面加冒号
EXPECT 自动化交互式程序
是一个自动交互式软件,基于TCL(Tool Command Language)脚本编程
以上是关于shell总结的主要内容,如果未能解决你的问题,请参考以下文章