欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

shell总结

程序员文章站 2022-06-11 19:21:48
...

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)脚本编程

转载于:https://blog.51cto.com/14240011/2372660