如何才能学好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脚本的建立

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脚本中使用。

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脚本的编程规范和习惯

.开头加脚本解释器
.附带作者及版权信息
.脚本扩展名为*.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

上图是文件加载的顺序

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

注意:在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脚本中使用位置参数变量。

特殊位置变量:
$ 获取脚本的名字,如果脚本前面跟着路径的话,那就获取路径加上脚本名字。
[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进程特殊状态变量

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

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个

[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算术运算符

Bash编程常见运算命令汇总

只适合整数运算
、(()) 推荐
、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表示假一样。

条件表达式常见语法

条件表达式的编程语法

[ 测试表达式 ]  && 命令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 中可以找到这些内容

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

注意:

1、字符串就用双引号

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

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

整数测试表达式

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

逻辑测试表达式

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

条件表达式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读入方式比较两个整数大小,要求对用户输入的内容严格判断是否为整数,是否输入了两个数字。
 

shell编程企业级实战的更多相关文章

  1. shell编程企业级实战(2)

    Vim配置文件.vimrc vim配置文件 if 条件语句 if是最常见的条件判断语句 例1:如果不存在/backup目录就创建. [root@web-01 /server/tools]# vim 0 ...

  2. Shell编程(week4_day3)--技术流ken

    本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...

  3. Shell编程、part3

    本节内容 1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变 ...

  4. Shell编程(3)

    1. shell流程控制 2. for语句 3. while语句 4. break和continue语句 5. case语句 6. shell编程高级实战 shell流程控制 流程控制是改变程序运行顺 ...

  5. Shell编程实战

    Shell编程实战   为什么要学习Shell编程 Shell脚本语言是实现Linux/Unix系统管理及自动化运维所必须的重要工具,Linux系统的底层以及基础应用软件的核心大都涉及Shell脚本的 ...

  6. shell编程系列26--大型脚本工具开发实战

    shell编程系列26--大型脚本工具开发实战 大型脚本工具开发实战 拆分脚本功能,抽象函数 .function get_all_group 返回进程组列表字符串 .function get_all_ ...

  7. shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机

    shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机 备份mysql中的库或者表 mysqldump 常用参数详解: -u 用户名 -p 密码 -h ...

  8. shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中

    shell编程系列24--shell操作数据库实战之利用shell脚本将文本数据导入到mysql中 利用shell脚本将文本数据导入到mysql中 需求1:处理文本中的数据,将文本中的数据插入到mys ...

  9. shell编程系列23--shell操作数据库实战之mysql命令参数详解

    shell编程系列23--shell操作数据库实战之mysql命令参数详解 mysql命令参数详解 -u 用户名 -p 用户密码 -h 服务器ip地址 -D 连接的数据库 -N 不输出列信息 -B 使 ...

随机推荐

  1. Windows Server 2012 R2 安装密钥(只适用安装,不支持激活)

    标准版 = NB4WH-BBBYV-3MPPC-9RCMV-46XCB 数据中心版 = BH9T4-4N7CW-67J3M-64J36-WW98Y

  2. Storm入门(十一)Twitter Storm源代码分析之CoordinatedBolt

    作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/811/twitter-stor ...

  3. AI应用开发实战 - 从零开始配置环境

    AI应用开发实战 - 从零开始配置环境 与本篇配套的视频教程请访问:https://www.bilibili.com/video/av24421492/ 建议和反馈,请发送到 https://gith ...

  4. 解决Ajax请求时无法重定向的问题

    今天发现,当使用Ajax请求时,如果后台进行重定向到其他页面时是无法成功的,只能在浏览器地址栏输入才能够实现重定向. Ajax默认就是不支持重定向的,它是局部刷新,不重新加载页面. 需要实现的功能是, ...

  5. JAVA之enum类详解

    目录    一.简介    二.默认枚举类    三.多值枚举类    四.属性和方法    五.构造函数    六.重要方法    七.引用参考 一.简介    1.枚举类代表一组常量:    2. ...

  6. 第4章 简单的C程序设计——选择结构程序设计

    在顺序结构中,各语句是按自上而下的顺序执行的,执行完上一个语句就自动执行下一个语句,是无条件的,不必作任何判断.实际上,很多情况下,需要根据某个条件是否满足来决定是否执行指定的操作任务,或者从给定的两 ...

  7. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║Vue基础:JS面向对象&字面量& this字

    缘起 书接上文<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史>,昨天咱们说到了以我的经历说明的web开发经历的 ...

  8. Vue2.0源码阅读笔记(二):响应式原理

      Vue是数据驱动的框架,在修改数据时,视图会进行更新.数据响应式系统使得状态管理变的简单直接,在开发过程中减少与DOM元素的接触.而深入学习其中的原理十分有必要,能够回避一些常见的问题,使开发变的 ...

  9. Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! WebFlux 系列教程大纲 一.背景 大家都知道,Sprin ...

  10. 一个box-sizing: border-box和felx混合使用中遇到的问题

    之前在项目中遇到一个布局上很趣的问题(也可能是笔者才疏学浅,哈哈).布局大概是这样的: 外层包裹器:采用flex布局,并指定内部子弹性盒子元素水平显示 侧边栏:flex盒子的子元素,可收起和展开.展开 ...