shell脚本基础

shell脚本
shell:人机交互的接口
GUI:Gnome ,KDE xfce 图形化
CLI:sh ,csh, zsh,ksh,bash,xsh .... 字符界面;command line
进程:是一段代码执行后的状态,是在内存中的;是动态
程序:能够实现某些功能的代码,是静态;存在磁盘

编程:本质向内存生成数据
面向过程:指令+数据 以指令为核心 指令:由程序文件提供(暂时理解为命令)
数据:IO设备、文件、管道、变量
面向对象:算法+数据结构 以数据为核心

脚本:命令堆砌,数据,控制

脚本编程:
shell脚本的好处
减少重复性工作,提升效率

脚本格式
#!/bin/bash 调用的解释器
#多行注释:脚本功能、版本、作者、联系方式、官网...
引用哪些外部文件:提供变量
单独定义变量
定义函数 (函数的作用: 代码复用)
程序主体:使用指令+变量+函数

所讲bash:功能
1).支持命令历史
2).支持管道、重定向
3).支持命令别名
4).支持命令行编辑
5).支持命令行展开
6).支持文件名通配
7).支持使用变量
8).支持编程

declare 声明:c语言中定义变量

基础-----------------------------------------------------------------------------------

查看当前系统中支持哪些shell?
# cat /etc/shells

查看当前shell
# echo $SHELL

切换shell

1)临时切换(调用其它shell编写的程序时)
# ksh //切换的ksh
2)永久切换
chsh --- change shell
#chsh -s /bin/ksh
#chsh -s /bin/csh/ root

与用户登录相关的文件决定了用户的环境。

1)/etc/profile 通常是设定系统变量的;设定环境变量;运行命令或脚本
2)/etc/bashrc 通常是设定别名;设定本地变量
3)/.bashrc
4)/.bash_profile


模式匹配、特殊字符---------------------------------------------------------------------

1.特殊字符

表示强制转义:会将后面的符号,转义成符号本身的意义
& 后台运行
; 多命令执行 ,并且前后两个命令执行过程式不受影响的
&& 与运算 连接两条命令,前面的命令执行成功,才执行后面的命令
|| 或运算 连接两条命令,前面的命令执行失败,才会执行后面的命令
echo $? $?:代表上一条执行结果的状态返回值

2·模式匹配

$ 提取变量值
$(): 命令替换;引用命令执行的结果
${}:引用变量
$[]:数学运算
文件名通配:
*: 匹配任意长度的任意字符
?: 匹配任意的单个字符
.在有的位置也表示单个字符(任意单个字符)
[]:匹配指定范围内的任意单个字符 [abc]
[^]:匹配指定范围之外的任意字符 [^abc]
3·引号用法:*****
“”:弱引用,可以实现变量替换
``: 命令替换,等同于$()
'':强引用,不完成变量替换

变量------------------------------------------------------------------------------------
为何引用变量: 值的重复引用,---> 灵活性 个性化

变量:内存中一段连续的地址空间 两部分:变量名、变量值(变量赋值、变量重新赋值)

变量名:不能以关键词和命令
变量赋值:name=value ----- 字母、数字、下划线,不能以数字开头
取消变量的值**** # unset name

shell中变量的类型
1、本地变量(局部变量)
2、环境变量(全局变量)
3、位置变量:$0 $1 $2 $3 $4 ...
4、特殊变量: $* $@ $#
如果想让环境变量永久生效:
#vim /etc/profile
export age=88
就是将变量age导出为全局变量,而且永久生效
1、本地变量
也叫自定义变量,用户根据自己的需求自己定义的变量
作用域(作用范围)在整个shell脚本中生效;如果是在命令行定义的变量,作用范围就是当前shell。
定义变量: 变量名=变量值 定义本地变量
2、环境变量
作用范围:当前shell及其子shell
定义环境变量:写/etc/profile中,下次登录就可以使用
3、位置变量: $0 $1 $2 $3 ...
位置变量使用:例如$1就是执行脚本时,脚本后边跟的第一个参数
($0 —— 表示当前运行的脚本或者命令本身)
4、特殊变量
$$ 查看当前shell的pid
!$和$_ 上一条命令的最后一个参数
$? 上一条命令的执行状态的返回值
$# 表示参数的个数 : $#=13
$@ 表示参数的列表 $@: ‘3’ ‘a’
$* 表示参数的列表 $*: '3 a'

@扩展------------------------------------------------------------------------------

echo:打印变量值、打印字符串等
-e:让echo支持以下符号:
:tab
:换行

输出内容颜色设定
shell脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数-e
格式如下:

echo -e "33[字背景颜色;文字颜色;其它属性m 字符串 33[0m"
例如:
echo -e "33[41;36m welcome laozhang 33[0m"
其中41的位置代表底色(40-47), 31的位置是代表字的颜色(30-37)

最后面控制选项说明

  33[0m 关闭所有属性
  33[1m 设置高亮度
  33[4m 下划线
  33[5m 闪烁
  33[7m 反显
  33[8m 消隐
  33[30m — 33[37m 设置前景色
  33[40m — 33[47m 设置背景色
  33[nA 光标上移n行
  33[nB 光标下移n行
  33[nC 光标右移n行
  33[nD 光标左移n行
  33[y;xH设置光标位置
  33[2J 清屏
  33[K 清除从光标到行尾的内容
  33[s 保存光标位置
  33[u 恢复光标位置
  33[?25l 隐藏光标
  33[?25h 显示光标

--开启一个缓冲区 #cat << EOF > /a.txt
>laozhang
>laoli
>EOF
#cat /a.txt
laozhang
laoli
--seq 数值生成器
seq 5
seq 2 5
seq 1 2 5
seq 5 -1 1

算术运算---------------------------------------------------------------------------
+ - * / ** (次方)% (取模)

1、$[] 和 $(())

2、let 常用于while循环变量更新
+= -= *= /= %=
let 变量=值
let可以帮助实现算术运算
# let sum=1+2
# let sum=$sum+1 等同于:sum+=1
# let i++ //在循环中更新变量值常用的,每次i的值加1
i++ 先引用变量值,再增长
++i 先增长,再引用

3.使用expr
#echo $(expr arg1 + arg2)
运算符号和前后两个数值之间必须要有空格;注意: 在使用*时,要将其引号括起来

4、Linux计算器(bc)
scale=3 //指定精度,精度就是小数点后保留几位小数
实现小数的计算:
#echo "scale=3;3/4" | bc

比较运算------------------------------------------------------------------------------------
单目比较(一个数据) 双目比较(两个数据)

1、比较使用方式:

#test 运算符 对象

#[ 运算符 对象]
选项可以#man bash--------/CONDITIONAL EXPRESSION
例: 文件类:
单目测试:-f file --普通文件为真
双目测试:file1 -nt file2--测试文件1是否比文件2新,如果新为真
字符串类:
单目测试:-z string ---字符串为空时,为真
双目测试:string1 == string2 两个字符串是否相同,相同为真
数值类:
双目测试:arg1 运算符 arg2
运算符可以是:-eq, -ne, -lt, -le, -gt, -ge(等于、不等于、小于,小于或等于、大于、大于或等于)

2、位运算符:

<< 左移位运算 >>右移位运算 &与运算 |或运算 ~ 非运算

逻辑运算----------------------------------------------------------------------------------
&& 与运算
[command1] && [command2]
注:1.当第一个命令执行成功,第二命令才能被执行
2.左右有一个为假,则整个运算都为假
|| 或运算
注:1.只有第一个命令假时,才会执行第二个命令
2.左右有一个为真,这结果为真
! 非运算
取运行结果的反值

脚本编程----------------------------------------------------------------------------

1、shell脚本的调试

对脚本整体进行调试
sh -x 脚本的名字 //-x:会将脚本执行过程中每一行都打印到标准输出
对脚本的局部调试
set -x //开启调试功能
set +x //关闭调试功能
2、读取变量

read:能够从标准输入读取用户输入的值,然后传递给脚本中的变量

read 自身显示提示信息 -p 打印提示的 —— prompt:提示

read 不回显用户输入的信息 -s 注意:-s 的选项要放在-p的前面

read 限制读取时间 -t

流程控制语句-----------------------------------------------------------------------------

条件判断语句:(前提条件)

if语句:
使用格式:

单分支:
方式一:if 条件运算表达式或命令;then
动作(命令)
fi

方式二:if 条件运算表达式或命令
then
动作
fi
(注释:在条件运算表达式结果为真,或命令执行状态为真,则运行动作)

双分支:
if 条件运算表达式或命令 ; then
动作1
else
动作2
fi

(注释:当满足条件,或命令执行成功,则运行动作1;否则运行动作2)

多分支:
if 条件1;then
动作1
elif 条件2;then
动作2
elif 条件3;then
动作3
...
else
动作n
fi

嵌套: 流程控制语句可以彼此嵌套

例:if 条件1;then
if 条件2;then
动作2
else
动作3
fi
else
动作1
fi

多重条件判断
条件表达式1 选项 条件表达式2
选项:
-a:并且 &&
-o:或者 ||
!条件表达式 :取反,非
if [ $score -gt 100 -o $score -lt 0 ]
if [ $score -gt 100 ] -o [ $score -lt 0 ]
if [ $score -gt 100 ] || [ $score -lt 0 ]
if [[ $score -gt 100 || $score -lt 0 ]]

case 多分支判断
语法结构:

单变量:
case 变量 in
值1)
命令1
;;
值2)
命令2
;;
... ...
... ...
值n)
命令n
;;
*)
命令
;;
esac

如果变量的值满足的是 值1,执行命令1;如果不满足,继续向下匹配值2,执行命令2,... ...
* 表示的通配,除了上面所有的值以外的值
注意:分号和esac

双变量:

用任意符号分隔两个变量
case $username,$password in
root,redhat)

循环判断语句

for语法--------------------------------------------

for 变量 in 变量列表;do
循环体 //可以重复执行n次的
done

说明:
变量列表中的值的数量,决定了循环的次数

例子:嵌套循环
打印99乘法口诀表
[root@shell script]# vim 99.sh
#!/bin/bash
for i in `seq 9`
do
for j in `seq $i`
do
echo -n "$i*$j=$[$i*$j] "
done
echo
done

while语法----------------------------------------

while 条件表达式或者命令(read)
do
循环体
变量的更新 //一定要有变量的更新,否则死循环
done

说明:while循环,当判断条件为真时,执行循环体中的操作;当判断条件为假时退出循环。

1·while与输入重定向结合使用

#!/bin/bash
#判断用的Uid是否大于500,打印普通用户还是系统用户
while read use ;do
name1=`echo $use | cut -d ":" -f 1`
uid1=`echo $use | cut -d ":" -f 3`
if [ $uid1 -lt 500 ];then
echo "$name1 系统用户"
else
echo "$name1 普通用户"
fi
done < /etc/passwd

注意:将/etc/passwd逐行赋给$use

函数--------------------------------------------------------

格式:
函数名(){
函数体
}
例: #!/bin/bash
#
diskusage=`df -Th`
memusage=`free -m | grep -i "mem"`
swapusage=`free -m | grep -i "swap"`

infos () {
case $abc in
d)
echo "$diskusage";;
m)
echo "$memusage";;
s)
echo "$swapusage";;
q)
echo "already exit!"
exit ;;
*)
echo -e "33[31;42;5m please input a effective!33[0m"
exit;;
esac
}

while read -p "please input options [d/m/s/q]: " abc;do
infos
done


变量默认值

当前脚本变量1 --- 引用外部文件变量2 --- 若变量2未赋值 --- 则引用变量1的默认变量
(防止程序运行因变量值导致运行失败)

例:
# vim /laozhang/a.sh
#!/bin/bash

virtual2="2"

# vim /laozhang/b.sh
#!/bin/bash

./laozhang/a.sh

virtual1=${virtual2-"1"}
echo "num值为 $virtual1"

until语句:-----------------------------------------------

until 条件判断语句或命令;do
循环体
[变量的更新]
done

注意: 条件为假、或者命令执行失败,则运行循环体

循环控制:
continue : 跳过本次循环

break : 跳出当前整个循环

exit : 退出整个脚本
例:
#!/bin/bash

num=1

until [ $num -gt 5 ];do
echo "hello $num"
let num++
done

原文地址:https://www.cnblogs.com/zhangshan-log/p/13745287.html