shell编程企业级实战

时间:2024-01-10 20:49:33

如何才能学好Shell编程

  1. 为什么要学习shell编程
    1. Shell是Linux底层核心
    2. Linux运维工作常用工具
    3. 自动化运维必备基础课程
  2. 学好shell编程所需Linux基础
    1. 熟练使用vim编辑器
    2. 熟练使用Linux的常用命令
    3. 熟练使用三剑客和正则表达式
  3. 如何才能学好shell编程
    1. 掌握shell脚本的常见语法
    2. 从简单判断、循环做起
    3. 多模仿、多练习、多思考
    4. 锻炼编程思维:先将需求理解,然后将大需求分解,逐步分成小的程序或者模块,然后再开发,或者先分析最终需求的基础实现,最后逐步扩展批量实现
    5. 不要拿来主义:从简单做起
    6. 多解决企业实际问题
    7. 找一本合适的教科书
    8. 反复实现本课程,反复练习
  4. 学完课程后的可达到的shell编程高度

Shell脚本初步入门

什么是是shell?

shell原意,是贝壳,

它在Linux内核和应用程序之间。就像一个翻译官,中间人,让程序员员写的应用程序能和系统之间相互交流

什么是shell脚本?

简单点说,就是许多shell命令,写在一个文件中,实现一个需求

先看一个清除日志的脚本

# clean logs ,v0.
cd /var/log
cat /dev/null>message
echo "Logs clean up"

这个脚本的问题在于,三条命令之间没有表现明确的关系

我们不知道脚本执行后,会是什么样的结果!

下面看一个完善的版本

#! /bin/bash
LOG_DIR=/var/log
ROOT_UID= # 第一关,必须是root用户才能执行脚本,否则提示,并终止
if ['$UID' -ne '$ROOT_UID']
then
echo 'Must be root to run this script!'
exit
fi
# 第二关,成功切换到目录,否则提示,并终止
cd $LOG_DIR || {
echo 'Can not change to necessary directory!'
exit
}
# 第三关,清理日志,如果清理成功,给出正确的提示
cat /dev/null>message && {
echo 'Logs cleaned up!'
exit
} # 第四关,通关失败,给出提示
echo 'cleaned logs fail!'
exit

shell脚本在Linux中的地位

Shell脚本语言很擅长处理纯文本类型的数据,而Linux系统中几乎所有的配置文件、日志文件(如NFS、 Rsync、 Httpd、 Nginx、 LVS、 MySQL等),以及绝大多数的启动文件都是纯文本类型的文件。

自然学好Shell脚本语言,就可以利用它在Linux系统中发挥巨大的作用。

形象的将shell和各种运维工具比喻为一串项链以及三种SHELL语言分类

shell编程企业级实战

shell编程企业级实战

Shell脚本的建立

1、脚本的第一行

一个规范的Shell脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash编程中一般为:
#!/bin/bash或#!/bin/sh #<==255个字符以内

2、bash和sh的区别

早期的bash与sh稍有不同,它还包含了csh和ksh的特色,但大多数脚本都可以不加修改地在sh上运行。

3、需要注意的地方

CentOS和Red Hat Linux下默认的Shell均为bash。因此,在写Shell脚本的时候,脚本的开头即使不加#!/bin/bash,它也会交给bash解释。

如果写脚本不希望使用系统默认的Shell解释,那么就必须要指定解释器了。否则脚本文件执行的结果可能就不是你想要的。

建议读者养成好的编程习惯,不管什么脚本最好都加上相应的开头解释器语言标识,养成Shell编程规范。

Shell脚本的执行

1. bash script-name或sh script-name

这是当脚本文件本身没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法,这也是老男孩老师推荐的使用方法

2. path/script-name或./script-name

指在当前路径下执行脚本(脚本要有执行权限),需要先将脚本文件的权限改为可执行(即文件权限属性加x位),

具体方法为chmod +x script-name。然后通过脚本绝对路径或相对路径就可以直接执行脚本了。

3. source script-name或. script-name

关于点和souece的妙用,就是父子shell之间可以相互调用变量

[root@dao scripts]# sh sh_user.sh   # 文件中是user=‘whoami’ 相当于定义了局部变量
[root@dao scripts]# echo $user [root@dao scripts]# . ./sh_user.sh # 使用点,调用了子变量(局部变量)
[root@dao scripts]# echo $user
whoami

4. sh<script-name或cat scripts-name|sh

[root@dao scripts]# chkconfig --list |grep :on |awk '{print "chkconfig",$1,"off"}'|bash

shell脚本执行一个重要的例子

shell编程企业级实战

当我们登陆命令行,就相当于开启一个shell,也就是局部变量和全局变量的意思,只能在创建他们的shell函数或者shell脚本中使用。

https://www.cnblogs.com/yxiaodao/p/10401327.html#_label2

取消定义变量unset user

shell中批量注释

1、vim批量操作

2、:EOF

EOF (这个EOF前面不能有空格)原理就是,EOF把中间的内容交给冒号,但是冒号表示什么都不做,所以,也就是注释了

3、cat > /dev/null <<EOF

EOF

shell脚本的执行过程

shell编程企业级实战

shell脚本的编程规范和习惯

.开头加脚本解释器
.附带作者及版权信息
.脚本扩展名为*.sh
.脚本存放在固定的目录下
.脚本中不用中文
.成对的符号一次书写完成
.循环格式一次性输入完成

Shell变量核心基础知识与实践

什么是变量?

x=1,x就是变量名,=号表示赋值。用一个字符或者字符串表示一堆内容。这个字符或者字符串叫做变量

变量的特性?

在bash shell中不会区分变量的类型

变量的分类?

两类,环境变量(全局变量)和普通变量(局部变量)。https://www.cnblogs.com/yxiaodao/p/10401327.html#_label2

Shell环境变量

环境变量(全局变量),系统中默认就存在的,作用就是解决系统的一些问题。

显示环境变量的方法:

1、echo $变量名

2、env

3、set     set -o 查看bash编程的配置

定义环境变量:

PS1、PATH、HOME、UID 系统固有的,默认就表示一定意义。

3种定义环境变量的方法(环境变量尽量大写)

1、直接export

export  PIZZA=1

2、先赋值,在export

PIZZA=2

export  PIZZA

3、declare

-x  A=1

-i  表示定义整型

环境变量永久生效的配置/etc/profile

环境变量取消 unset  PIZZA

环境变量的文件执行顺序

全局文件

/etc/profile

/etc/bashrc/

用户环境变量文件

~/.bashrc

~/.bash_profile

shell编程企业级实战

上图是文件加载的顺序

注意:新添加的环境变量要加在文件的前面,不要加在最后面,其中的代码会影响执行顺序。

注意:在ssh 远程登录或者其他特殊情况下,也许不会加载/etc/profile和~/.bash_profile

所以在添加变量的时候,添加在/etc/bashrc下

Shell普通变量

局部变量

当前用户或者脚本中生效

a.变量名:
规则:字母、数字、下划线,3者组合,以字母开头。
要求:见名知意
)OldboyAge=
)oldboy_age=
) oldboyAge= ###驼峰语法 b.变量内容
字符串:
变量名=value #<==不加引号。 ##解析变量或者命令,然后输出,纯数字选择不加引号。
变量名=’value’ #<==加单引号。 ###所见即所得
变量名=”value” #<==加双引号。 ##解析变量或者命令,然后输出,字符串默认选择双引号,可以把要定义的内容作为一个整体。 命令变量,把一个命令的结果赋值给变量
变量名=`ls`
变量名=$(ls) 小结:
针对变量名:
  1、变量名一定要有一定的命令规范,并且要见名知意,推荐使用驼峰法
  2、变量名仅能使用字母、数字、下划线的任意多个字符,并且要字母开头
针对变量内容:
  3、在脚本中定义普通字符变量,尽量使用双引号括起来。
  4、单纯数字的变量内容可以不加引号
  5、希望变量的内容鸳鸯输出需加单引号
  6、希望变量值引用命令并获取命令的结果就用反引号或者$()
针对赋值符号:
  7、变量定义使用赋值等号(=),赋值符号两端不要有空格
针对变量输出:
  8、使用或者输出变量的内容,可用 $ 变量名,$PS1
  9、若变量名(db)后面有其他字符链接的时候,就必需给变量名加上大括号

Shell特殊位置参数变量

在Shell中存在一些特殊且重要的变量,例如: $0、 $1、 $#,我们称之为特殊位置参数变量,

要从命令行、函数、或脚本执行等处传递参数时,就需要在Shell脚本中使用位置参数变量。

shell编程企业级实战

特殊位置变量:
$ 获取脚本的名字,如果脚本前面跟着路径的话,那就获取路径加上脚本名字。
[root@web01 scripts]# cat test.sh
#!/bin/bash
echo $
[root@web01 scripts]# bash test.sh
test.sh
[root@web01 scripts]# bash /server/scripts/test.sh
/server/scripts/test.sh
企业应用;
一般在启动脚本的结尾会使用$0获取脚本的路径和名字给用户提示用。
/etc/init.d/crond $,$----$n
$1表示脚本后的第一个参数
$2表示脚本后的第二个参数
....
超过$,${} 要加{}大括号
企业应用:
case "$1" in
start)
rh_status_q && exit
$
;;
stop) $# 脚本后面所有参数的个数
企业应用:
[root@web01 scripts]# cat test.sh
#!/bin/bash
if [ $# -ne ]
then
echo "Usage:$0 arg1 arg2"
exit
fi
echo ok $* 获取脚本的所有参数,“$ $ $”
$@ 获取脚本的所有参数,"$1" "$2" "$3" 当需要接收脚本后面所有参数时,但是又不知道参数个数就用这两个变量。 区别:
[root@web01 scripts]# cat test.sh
#!/bin/bash
for arg in "$*"
do
echo $arg
done echo -------------------------- for arg1 in "$@"
do
echo $arg1
done
[root@web01 scripts]# bash test.sh "I am" oldboy teacher.
I am oldboy teacher.
--------------------------
I am
oldboy
teacher. make
echo $?

Shell进程特殊状态变量

shell编程企业级实战

$? 获取上一个命令的返回值,如果返回值为0就证明上一个命令执行正确,
非0,就证明上一个命令执行失败的。
***** $$ 获取当前执行脚本的进程号 $! 获取上一个后台工作进程的进程号 $_ 获取上一个执行脚本的最后一个参数

Shell变量子串

shell编程企业级实战

Shell变量子串(变量内容相关知识)

[root@web01 scripts]# oldboy="I am oldboy"
[root@web01 scripts]# echo ${oldboy}
I am oldboy
[root@web01 scripts]# echo ${#oldboy} [root@web01 scripts]# echo $oldboy|wc -L [root@web01 scripts]# expr length "$oldboy" [root@web01 scripts]# echo $oldboy|awk '{print length}' [root@web01 scripts]# echo $oldboy|awk '{print length ($1)}' [root@web01 scripts]# echo $oldboy|awk '{print length ($0)}' 练习题:
I am oldboy I teach linux
打印这些字符串中字符数小于3的单词。
涉及知识点:取字符串长度,for,if。 [root@web01 scripts]# echo ${oldboy:}
am oldboy
[root@web01 scripts]# echo ${oldboy::}
am
[root@web01 scripts]# echo ${oldboy::}
am o
OLDBOY=abcABC123ABCabc [root@web01 scripts]# echo ${OLDBOY}
abcABC123ABCabc
[root@web01 scripts]# echo ${OLDBOY%a*C}
abcABC123ABCabc
[root@web01 scripts]# echo ${OLDBOY%a*c}
abcABC123ABC
[root@web01 scripts]# echo ${OLDBOY%%a*c} [root@web01 scripts]#

Shell特殊变量扩展知识

只挑了4个,最重要的是第1个

shell编程企业级实战

[root@web- ~]#
[root@web- ~]# result=${test:-UNSET}
[root@web- ~]# echo $test [root@web- ~]# echo $result
UNSET
[root@web- ~]# echo $test [root@web- ~]# #当变量test为空的时候,就把UNSET内容赋值给result result 媳妇
test 销售 空
UNSET 备胎 赋值给result 企业用途
find $path -name "*.name" -mtime +7|xrangs rm -f
当 $path 为空的时候,命令会从根目录开始删,所以我们准备一个备胎
find  ${path:-/tmp}  -name  "*.name"  -mtime +7|xrangs  rm  -f

系统中的应用---httpd的启动脚本中

- = ? +

Shell变量的数值计算

算数运算符

如果要执行算术运算,就离不开各种运算符号,和其他编程语言类似, Shell也有很多算术运算符,下面就给大家介绍下常见的Shell算术运算符

shell编程企业级实战

Bash编程常见运算命令汇总

shell编程企业级实战

只适合整数运算
、(()) 推荐
、let 次推荐
、expr
、$[]
既适合整数,又适合小数运算。
、bc
、awk 推荐 (())
[root@web-01 ~]# a=1
[root@web-01 ~]# b=2
[root@web-01 ~]# echo $a+1   不加
1+1
[root@web-01 ~]# $(a+1) 更不加了
-bash: a+1: command not found
[root@web-01 ~]# echo $(a+1)
-bash: a+1: command not found [root@web-01 ~]# echo $((a+1)) 双括号才加
2
[root@web01 scripts]# echo $((2**3))
8
[root@web01 scripts]# echo $((1+2**3-5/3))
8
[root@web01 scripts]# echo $((1+2**3-5%3))
7
问? ++a 和 a++有什么区别 let
[root@web-01 ~]# a=1
[root@web-01 ~]# b=2
[root@web-01 ~]# i=$a+$b
[root@web-01 ~]# echo $i
1+2
[root@web-01 ~]# let i=$a+$b
[root@web-01 ~]# echo $i
3 expr用于运算,必须要有空格
[root@web-01 ~]# expr 1 + 1
2
[root@web-01 ~]# expr 1+1
1+1 $[]
[root@web-01 ~]# echo $[2+2]
4
[root@web-01 ~]# echo $[2 + 2]
4 ===========
bc 就像启动计算器,高端点用法自己在了解一下
[root@web-01 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+1
2
3+4
7
1
1
1*1.2
1.2 [root@web-01 /server/scripts]# echo "scale=2;355/113"|bc
3.14 使用scale来保留2位小数
[root@web-01 /server/scripts]# echo "scale=3;355/113"|bc
3.141 awk的运算效果很好!运算精确,好用
[root@web-01 ~]# echo 1.1 0.5 |awk '{print $1-$2}'
0.6

expr命令的多种企业应用实践

1、判断变量的类型是否为整数

在shell编程里,由于函数库很少,因此在判断字符串是否为整数时,就不是很容易的事情

可以利用expr做计算时必须是整数的规则,把一个变量或者字符串和一个一直西横竖(非0)相加,

看命了返回值是否为0。就认为做加法的变量为整数,否则就不是整数。

[root@web- ~]# i=pizza         将字符串赋值给i
[root@web- ~]# expr $i + &>/dev/null 把i和6相加,&>/dev/null表示不保留任何输出
[root@web- ~]# echo $? 输出返回值
2 非0 就证明输出了错误,证明1不是整数
[root@web- ~]# i=
[root@web- ~]# expr $i + &>/dev/null
[root@web- ~]# echo $?
0 返回为0,则证明i的值是整数

编写一个脚本来判断变量是不是整数

[root@web- /server/scripts]# vim judge1.sh
#!/bin/bash echo + $ &>/dev/null
if [ $? -eq ]
then
echo "$1 是整数"
else
echo "$1 不是整数"
fi "judge1.sh" [New] 9L, 112C written
[root@web- /server/scripts]# bash judge1.sh
是整数
[root@web- /server/scripts]# bash judge1.sh ll
ll 是整数

2、判断文件扩展名是否符合要求

[root@web- /server/scripts]# vim judge2.sh
#!/bin/bash
# :冒号两边要有空格
expr "$1" : ".*\.txt" &>/dev/null
if [ $? -eq ] then
echo "$1 是文本"
else
echo "$1 不是文本"
fi
~
~
~
"judge2.sh" 10L, 152C written
[root@web- /server/scripts]# bash judge2.sh old
old 不是文本
[root@web- /server/scripts]# bash judge2.sh old.txt
old.txt 是文本

expr 好有很多功能,请自行了解(man expr)

bash内置核心命令

  Shell变量除了可以 直接赋值 或者 脚本传参 外!还可以使用read命令从标准输入中获得,

  read为bash内置命令,可以通过help read查看帮助。

  语法格式:read [参数] [参数]

  常用参数如下。

    -p prompt:设置提示信息

    -t  timeout:设置输入等待时间,单位默认为秒。

[root@web- /server/scripts]# read -p "请输入一个数字:" a
请输入一个数字:
[root@web- /server/scripts]# echo $a

read一般的作用就是和用户交互

[root@web- /server/scripts]# read -p "请输入两个数字:" a b
请输入两个数字: [root@web- /server/scripts]# echo $((a+b))

bash内置核心命令read的企业级应用实践

打印一个菜单,让用户选择要做的事情

#!/bin/bash
cat <<EOF
、install lamp
、install lnmp
、exit
EOF
read -p "请选择一个序号(必须是一个数字):" num
# 先判断一下是不是数字
expr + $num &>/dev/null
if [ $? -ne ]
then
echo "usage:$0 {1|2|3}"
exit
fi if [ $num -eq ]
then
echo "install lamp..."
elif [ $num -eq ]
then
echo "install lamp..."
elif [ $num -eq ]
then
echo "bye"
else
echo "usage:$0 {1|2|3}"
exit
fi
数值运算命令:
只适合整数运算
、(()) 推荐
、let 次推荐
、expr
、$[]
既适合整数,又适合小数运算。
、bc
、awk 推荐 、(()) 推荐
[root@web01 scripts]# i=$((a+))
[root@web01 scripts]# echo $i [root@web01 scripts]#
[root@web01 scripts]# echo $((a+)) [root@web01 scripts]# echo $((+)) [root@web01 scripts]# echo $((**)) [root@web01 scripts]# echo $((+**-/)) [root@web01 scripts]# echo $((+**-%)) 、let 次推荐
[root@web01 scripts]# let i=$a+
[root@web01 scripts]# echo $i 、expr用于运算 、$[] =============
bc
awk
[root@web01 scripts]# echo +|bc [root@web01 scripts]#
[root@web01 scripts]# echo 1.1+|bc
3.1
[root@web01 scripts]# echo 1.1+2.3|bc
3.4
[root@web01 scripts]# echo 2.1 1.4|awk '{print $1-$2}'
0.7
[root@web01 scripts]# echo 2.1 1.4|awk '{print $1*$2}'
2.94 [root@web01 scripts]# expr + [root@web01 scripts]# expr + a
expr: non-numeric argument
[root@web01 scripts]# echo $? [root@web01 scripts]#
[root@web01 scripts]#
[root@web01 scripts]#
[root@web01 scripts]# a=
[root@web01 scripts]# expr + $a &>/dev/null
[root@web01 scripts]# echo $? [root@web01 scripts]# a=oldboy
[root@web01 scripts]# expr + $a &>/dev/null
[root@web01 scripts]# echo $? [root@web01 scripts]# cat judge1.sh
#!/bin/bash
expr + $ &>/dev/null
if [ $? -eq ]
then
echo "$1 is 整数"
else
echo "$1 不是整数"
fi
[root@web01 scripts]# bash judge1.sh
is 整数
[root@web01 scripts]# bash judge1.sh oldboy
oldboy 不是整数 root@web01 scripts]# cat judge_kuozhan.sh
#!/bin/bash
expr "$1" : ".*\.txt" &>/dev/null
if [ $? -eq ]
then
echo "$1 是文本"
else
echo "$1 不是文本"
fi
[root@web01 scripts]# sh judge_kuozhan.sh oldboy.txt
oldboy.txt 是文本
[root@web01 scripts]# sh judge_kuozhan.sh alex.log
alex.log 不是文本
[root@web01 scripts]# sh judge_kuozhan.sh peiqi.log
peiqi.log 不是文本
[root@web01 scripts]# sh judge_kuozhan.sh 老男孩老师.txt
老男孩老师.txt 是文本 [root@oldboy scripts]# cat test.sh
#!/bin/bash
a=
b=
echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))" 变量的赋值:
、定义法
a= 、传参法
[root@web01 scripts]# cat test7.sh
#!/bin/bash
a=$
b=$
echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))" 、read读入,读取用户输入。
-p 提示
-t 等待用户输入的时间 read -t -p "请输入一个数字:"
[root@web01 scripts]# read -t -p "请输入一个数字:" a
请输入一个数字:
[root@web01 scripts]# echo $a [root@web01 scripts]# a=
[root@web01 scripts]# echo $a read读入有什么作用
和用户交互。 [root@web01 scripts]# cat test6.sh
#!/bin/bash
read -p "请输入两个数字:" a b
echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))" read企业应用
[root@web01 scripts]# cat select1.sh
#!/bin/bash
cat <<EOF
.install lamp
.install lnmp
.exit
EOF
read -p "请选择一个序号(必须是数字):" num
#.判断是否为整数
expr + $num &>/dev/null
if [ $? -ne ]
then
echo "Usage:$0 {1|2|3}"
exit
fi #.判断执行处理
if [ $num -eq ]
then
echo "install lamp..."
elif [ $num -eq ]
then
echo "install lnmp..."
elif [ $num -eq ]
then
echo "bye."
exit
else
echo "Usage:$0 {1|2|3}"
exit
fi

Shell的常见条件表达式语法介绍和实践

通常,在bash的各种条件结构和流程控制结构中都要进行各种测试,然后根据测试结果执行不同的操作,有时也会与if等条件语句相结合,来完成测试判断,减少程序运行的错误。执行测试条件表达式后通常会返回“真”或“假”,就像执行命令后的返回值为0表示真,非0表示假一样。

条件表达式常见语法

shell编程企业级实战

条件表达式的编程语法

[ 测试表达式 ]  && 命令1 | |  命令2

如果前面的表达式成功,name就执行命令1,否则执行命令2

========相当于========

if  [ 测试表达式 ]

then

  命令1

else

  命令2

fi

当命令很多的时候

[ 测试表达式 ]  && {

  命令1

  命令2

}| |{

  命令3

  命令4

}

如果前面的表达式成功,那么久执行后面命令

[ 测试表达式 ]  && 命令1

如果前面表达式失败,那么就执行后面的命令

[ 测试表达式 ]  | | 命令2

条件表达式
[root@web- /server/scripts]# [ -e /etc/hosts ] && echo || echo [root@web- /server/scripts]# [ -e /etc/host ] && echo || echo 命令表达式
[root@web- /server/scripts]# (expr + &>/dev/null) && echo || echo [root@web- /server/scripts]# (expr + a &>/dev/null) && echo || echo

文件测试表达式的常见功能

在man test 中可以找到这些内容

shell编程企业级实战

字符串测试表达式常见功能说明

shell编程企业级实战

注意:

1、字符串就用双引号

2、等号可以用一个或者两个

3、等号两端必须要有空格

整数测试表达式

shell编程企业级实战

记住在单括号和双括号的写法的区别,测试一下

逻辑测试表达式

shell编程企业级实战

不同符号测试表达式 [ ]  [[ ]] (( ))  test 的区别

shell编程企业级实战

条件表达式6种写法:if,while
语法1: test <测试表达式>
语法2: [ <测试表达式> ] #两端有空格
语法3:[[ <测试表达式> ]] #两端有空格
语法4:((<测试表达式>)) #不需要空格 语法5:(命令表达式)
语法6:`命令表达式` 编程语法:
[ <测试表达式> ] && 命令1
如果前面表达式成功,那么就执行后面命令。 [ <测试表达式> ] || 命令1
如果前面表达式失败,那么就执行后面命令。 [ <测试表达式> ] && {
命令1
命令2
命令3
}
如果前面表达式成功,那么就执行后面命令。 [ <测试表达式> ] && 命令1 || 命令2
如果前面表达式成功,那么就执行命令1,否则执行命令2。 [ <测试表达式> ] && {
命令1
命令2
}||{
命令3
命令4
}
如果前面表达式成功,那么就执行命令1,,否则执行命令3,。 <测试表达式>有哪些: 文件测试表达式:
为什么需要文件测试表达式?
操作一个对象,就要看对象条件是否满足,否则不要操作。
、常见功能
、实践
、企业应用:启动脚本中的应用。 字符串测试表达式
[ -n "字符串" ] 字符串长度[不]为0,表达式为真。 not zero。
[ -z "字符串" ] 字符串长度为0,表达式为真。 zero。
[ "字符串1" == "字符串2" ] 两个字符串相同则为真。
[ "字符串1" !== "字符串2" ] 两个字符串不相同则为真。 注意:
字符串就用双引号
等号可以用一个或者两个
=号两端必须要有空格
实践:
[root@web01 ~]# [ -n "oldboy" ] && echo || echo [root@web01 ~]# [ -z "oldboy" ] && echo || echo [root@web01 ~]# char="oldboy"
[root@web01 ~]# [ -z "$char" ] && echo || echo [root@web01 ~]# unset char
[root@web01 ~]# [ -z "$char" ] && echo || echo [root@web01 ~]# [ "dd" == "dd" ] && echo || echo [root@web01 ~]# [ "dd" == "ff" ] && echo || echo [root@web01 ~]# [ "dd" = "ff" ] && echo || echo [root@web01 ~]# [ "dd" != "ff" ] && echo || echo [root@web01 ~]# [ "dd" != "dd" ] && echo || echo 改造上面的四则运算的脚本
企业应用:
[root@db03 scripts]# cat yunsuan1.sh
#!/bin/bash
##############################################################
# File Name: yunsuan.sh
# Version: V1.
# Author: oldboy
# Organization: www.oldboyedu.com
# Created Time : -- ::
# Description:
##############################################################
#!/bin/bash
read -p "pls input two num:" a b

# b没有值,肯定是没有输入或者没有输入2个
if [ -z "$b" ]
then
echo "请输入两个数"
exit
fi
# 判断是不是数字
expr $a + $b + &>/dev/null
if [ $? -ne ]
then
echo "Usage:$0 num1 num2"
exit
fi echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))" 整数测试表达式: 小题:使用read的交互方式,来比较两个整数的大小。 分析:
、要求整数
、2个数
、比较大小
大于
等于
小于 [root@web01 scripts]# cat com1.sh
#!/bin/bash
read -p "请输入两个整数:" a b #.判断是不是输入两个数
[ -z "$b" ] &&{
echo "请输入两个整数"
exit
} #.判断整数
expr $a + $b + &>/dev/null
[ $? -ne ] &&{
echo "请输入两个整数"
exit
} #.判断是否大于
[ $a -gt $b ] &&{
echo "$a>$b"
exit
} #.判断是否等于
[ $a -eq $b ] &&{
echo "$a=$b"
exit
}
#.判断是否小于
echo "$a<$b" [root@db03 scripts]# cat comp.sh
#!/bin/bash
##############################################################
# File Name: comp.sh
# Version: V1.
# Author: oldboy
# Organization: www.oldboyedu.com
# Created Time : -- ::
# Description:
##############################################################
read -p "Pls input two num:" a b
#.第一关判断传入的内容都是整数
expr $a + $b + &>/dev/null
[ $? -ne ] &&{
echo "Usage:$0 num1 num2"
exit
} #.第二关输入两个数
[ -z "$b" ] &&{
echo "Usage:$0 num1 num2"
exit
} #.比较大小
[ $a -gt $b ] && {
echo "$a>$b"
exit
} [ $a -eq $b ] && {
echo "$a=$b"
exit
}
echo "$a<$b"
exit ==============升级使用if
[root@db03 scripts]# cat comp.sh
#!/bin/bash
##############################################################
# File Name: comp.sh
# Version: V1.
# Author: oldboy
# Organization: www.oldboyedu.com
# Created Time : -- ::
# Description:
##############################################################
read -p "Pls input two num:" a b
#.第一关判断传入的内容都是整数
expr $a + $b + &>/dev/null
[ $? -ne ] &&{
echo "Usage:$0 num1 num2"
exit
} #.第二关输入两个数
[ -z "$b" ] &&{
echo "Usage:$0 num1 num2"
exit
} #.比较大小
if [ $a -gt $b ]
then
echo "$a>$b"
elif [ $a -eq $b ]
then
echo "$a=$b"
else
echo "$a<$b"
fi 逻辑测试表达式
! 非
&& -a 并且
|| -o 或者 []中 使用 -a -o
[[]]或(())里面 使用&& ||
[] [[]] (()) 这些符号之间连接 使用&& || make && make install ====================
[root@db03 scripts]# [ -eq -a -f /etc/hosts ] && echo || echo [root@db03 scripts]# [ -eq -a -f /etc/hosts ] && echo || echo [root@db03 scripts]# [ -eq && -f /etc/hosts ] && echo || echo
-bash: [: missing `]' [root@db03 scripts]# [[ -eq && -f /etc/hosts ]] && echo || echo [root@db03 scripts]# [ -eq ] && [ -f /etc/hosts ] && echo || echo [root@db03 scripts]# [ -f /etc/hosts ] && echo || echo [root@db03 scripts]# [ ! -f /etc/hosts ] && echo || echo 小题:如果/tmp/oldboy.sh是普通文件,并且可执行,就执行改脚本。
file="/tmp/oldboy.sh"
if [ -f $file ] && [ -x $file ]
then
bash $file
fi . 单分支结构
第一种语法:
if <条件表达式>
then
指令
fi
第二种语法:
if <条件表达式>; then
指令
fi 如果 <你有房>
那么
我就嫁给你
果如 if条件句的双分支结构语法为:
if <条件表达式>
then
指令集1
else
指令集2
fi 如果 <你有房>
那么
我就嫁给你
否则
我再考虑下
果如 多分支:
if <条件表达式1>
then
指令1...
elif <条件表达式2>
then
指令2...
elif <条件表达式3>
then
指令3...
else
指令4...
fi 范例7_2:开发Shell脚本判断系统剩余内存的大小,如果低于100MB就邮件报警给系统管理员,
并且将脚本加入系统定时任务,即每3分钟执行一次检查。 分析思路:
、取内存
free -m|awk 'NR==3{print $NF}'
、发邮件
mail -s "主题" 邮件地址 </etc/hosts
echo ""|mail -s "主题" 邮件地址
、开发脚本判断发邮件
full="内存充足。"
leak="内存不足。"
free=`free -m|awk 'NR==3{print $NF}'`
if [ $free -lt ]
then
echo "$leak"|tee /tmp/mail.log
mail -s "$leak`date`" -@qq.com </tmp/mail.log
else
echo "$full"
fi 、加入定时任务
[root@db03 scripts]# crontab -l|tail -
###########
*/ * * * * /bin/sh /server/scripts/judge.sh >/dev/null >& 课后练习:开发Shell脚本判断系统根分区剩余空间的大小,如果低于1000MB报警空间不足,
如果低于500M,就报警空间严重不足,最后把结果邮件发给系统管理员,
并且将脚本加入系统定时任务,即每3分钟执行一次检查。 预习:
函数
case
for
while

Shell编程第一章节前六小节复习

Shell编程实战:第一模块前六节复习:Shell编程基础

-第一章:如何学好shell编程。
必备基础:
)熟练vim编辑器,.vimrc配置。
)120个左右Linux命令。(跟老男孩学习Linux运维:核心命令实战)
)网络服务,rsync,nfs,lamp,lnmp,ltmp,keepalived,lvs 如何学好:
、锻炼编程思维
比如要先有大纲
第一章
1.1
1.1.
1.1.
第二章
2.1
2.1.
2.1.
、多练,多思考,不要拿来主义。
、有一本教科书。跟老男孩学习Linux运维:Shell编程实战 -第二章:Shell基础入门
什么是shell
什么是shell脚本 shell脚本的建立
#!/bin/bash
#### shell脚本的执行
4种方式:
)bash/sh oldboy.sh #推荐使用
)source/. oldboy.sh *****
)sh/bash<oldboy.sh
)./oldboy.sh或/server/scripts/oldboy.sh #必须要有执行权限。 Shell的执行过程
oldboy.sh:
pwd
ls
oldgirl.sh #子shell
ls oldgirl.sh & 放到后台执行。 并行,执行的同时,也执行下面的额ls 重点也是难点
source/. oldgirl.sh 相当于子Shell和父Shell相当于在一个shell里运行。 -第三章 变量基础
、什么是变量?
oldboy="I am oldboy"
oldboy是变量名,= 是赋值符号,"I am oldboy"是变量的内容。
OldboyAge
oldboyAge #推荐。
oldboy_age 、变量类型,shell里面是弱类型
decalre -i A #定义一个整形,一般没有这种需求 、变量分类
环境变量(全局变量)
特点:大写
全局生效
)系统的环境变量
  PS1,PATH,LANG 直接用。
)自定义环境变量
export OLDBOY=
OLDBOY=
export OLDBOY
decalre OLDBOY=
查看:
env/set
echo $变量名
取消:
unset 变量名 普通变量(局部变量)
局部生效:
oldboy="I am oldboy"
oldboy是变量名,=是赋值符号,"I am oldboy"是变量的内容。
变量名:
OldboyAge
oldboyAge #推荐。
oldboy_age
= 两边不能有空格
变量内容:
4种方式
a=test #不加引号,也会解析变量,推荐连续数字用此方法。
a='test' #所见即所得。
a="test" #默认双引号,解析变量。
a=`date` #解析一个命令结果。就用``或$()。 输出变量:
$oldboy_age
${oldboy_age}dddd -第四章 变量的扩展
)特殊位置变量
$ ***** 企业应用-脚本的结尾
$,$,$n *****
$# ***** 获取参数的个数 $* 两个的相同点和不同点
$@
)特殊状态变量
$? *****
$$ 进程号
$!上一个脚本的进程
$_ 上一个脚本的最后一个参数 相当于 esc+点
)变量的子串
${oldboy}
${#oldboy}
wc -L ,expr length "$oldboy",awk '{print length }'
${oldboy:}
${oldboy::}
${oldboy#word}
${oldboy##word}
${oldboy%word}
${oldboy%%word}
${oldboy/dd/ff}
${oldboy//dd/ff} )变量特殊扩展
result=${oldboy:-word} # 推荐 ****
result=${oldboy:=word}
result=${oldboy:?word}
result=${oldboy:+word} 霸道 第五章 变量的数值计算
整数:
(()) 推荐
let 推荐
$[]
expr
declare declare -i a=4+3 echo $a
小数:
bc 推荐加减
awk 乘除推荐 expr:
)判断是否为整数。
)扩展名 。忘记判断,记忆窍门 vim ·which ssh-copy-id·
)取字符串长度 变量的定义:
)a=
)传参
)read读入 read -t -p "输入提示:" a
用途:菜单选择,和用户交互
第六章 条件测试与比较
6种:
[] #推荐
[[]]
test
(())
(命令)
`命令` 等价if单分支
[]&&{
dddd
} 等价if双分支
[]&&{
dddd
}||{
ddd
}
===================================
[ -f /etc/hosts ] || exit 5 常用的推荐用法,简简洁,命令多的时候,用if比较好
make && make install
=================================
if,whlie 当做一个条件判断。
文件、字符、整数 测试
逻辑符
都可以用man test 找到

if、case、while、for、函数、数组和企业实践

if、case、while、for、函数、数组和企业实践

Shell案例实战和企业面试题

Shell案例实战和企业面试题

第五阶段-模块作业

章节一
试题1:用source执行脚本和用bash执行Shell脚本的区别是什么?
考试题2:如何自定义环境变量?
考试题3:定义变量内容,不加引号、单引号、双引号、反引号结果有什么不同?应该怎么用?
考试题4:请分别说出2个以上用于整数运算特殊符号或命令,以及适合小数运算的命令。
考试题5:写出特殊变量对应的意义及应用
$、$n、$#、$*、$@、$?、$$、$!、$_
考试题6:写出下面特殊变量扩展的意义
${oldboy}、${#oldboy}、${oldboy:offset:length}、${oldboy#word}、${oldboy##word}、${oldboy%word}、${oldboy%%word}、${oldboy/pattern/string}、${oldboy//pattern/string}、${oldboy:-word}
考试题7:在条件测试与表达式中,[]和[[]]有何区别?
考试题8:说出适合在[]以及test中整数比较的特殊运算符号?
考试题9、输出下面菜单
.install MySQL
.install Tomcat
.exit
当用户选择对应的数字就开始安装对应的服务(可echo输出替代),需要对用户输入的数字进行判断是否为整数(用条件测试表达式实现)。
考试题10、使用read读入方式比较两个整数大小(用条件表达式实现)。 章节二
考试题1:开发Shell脚本判断系统根分区剩余空间的大小,如果低于1000MB就提示不足,否则提示充足。

考试题2:分别使用变量定义、read读入及脚本传参方式实现比较2个整数的大小。

考试题3:打印一个菜单如下,当用户选择对应的数字时,就执行对应项的应用,最好对用户的输入进行是否为整数判断。
1.install lamp
2.install lnmp
3.exit 考试题4:通过脚本传参的方式,检查Web网站URL是否正常(要求主体使用函数)。 考试题5:利用case语句开发Rsync服务启动停止脚本,并能通过chkconfig实现开机自启动。 考试题6:猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,如果不符合要求,就给予高或低的提示,猜对后则给出猜对用的次数,请用while语句实现。 考试题7:分析nginx访问日志(自备),把日志中每行的访问字节数对应字段数字相加,计算出总的访问量。给出实现程序,请用while循环实现。 考试题8:计算从1加到100之和(要求用for和while,至少给出两种方法)。 考试题9:利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。I am oldboy teacher welcome to oldboy training class 考试题10:使用read读入方式比较两个整数大小,要求对用户输入的内容严格判断是否为整数,是否输入了两个数字。