初识shell编程

摘要:
这叫做幻数。如果内核能够识别,则必须在第一行中写入。如果不是第一行,编程脚本的注释行也可以写成#!如果执行脚本具有路径,则它包括脚本
一、shell编程基础

什么是shell

命令解释器:你输入的命令,谁来给你运行、解释

Centos默认的Shell是bash

[root@luffy-001 log]# echo $SHELL    SHELL变量
/bin/bash
[root@luffy-001 log]# cat /etc/shells   所有的命令解释器
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
[root@luffy-001 log]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash      root用户 的命令解释器
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
saslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
pizza:x:500:500::/home/pizza:/bin/bash
oldboy:x:501:501::/home/oldboy:/bin/bash

什么是Shell脚本

命令大礼包,就是一个程序文件,包含若干行Linux命令语句

循环,条件语句

一般以.sh结尾,或者通过file命令查看,其类型是shell script

[root@luffy-001 log]# file /server/scripts/ip.sh 
/server/scripts/ip.sh: Bourne-Again shell script text executable

创建Shell脚本

1、统一脚本存放目录,/server/scripts/

2、推荐使用vim编辑器编辑脚本,脚本以.sh结尾

3、第一行支出是由哪一个解释器来执行脚本中的内容

#!/bin/bash

/sbin/ifconfig eth0|awk -F '[ :]+' 'NR==2{print $4}'

#! 称为幻数,能被内核识别

必须写在第一行,如果不是第一行就编程脚本注释行

又可以写成#!/bin/sh

4、版权声明

# desc:     show  ip address
# author:   pizza
# time:     20191111
# version:  v1.0

5、题目:写一个简单的脚本(切换目录显示文件实行)并运行

二、shell脚本深入

变量

用一个固定的字符串,替代更多更复杂的内容,省事

x=1
[root@luffy-001 scripts]# x=1
[root@luffy-001 scripts]# echo $x
1
devPath=/server/ filelist=`ls`或者$(ls)
$LANG
$PATH

变量又分为局部变量(普通变量)、全局变量(环境变量)、特殊变量

局部变量(普通变量)

只能在创建他们Shell函数或者Shell脚本中使用

形式:变量名=value

变量名要求:
#1、字母、数字、下户线组成
#2、必须以字母开头
#3、见名知意,规范变量名写法定义
#4、驼峰写法:RedPizzaCar

应用变量尽量使用${}
[root@luffy-001 scripts]# week=10
[root@luffy-001 scripts]# echo ${week}day
10day
[root@luffy-001 scripts]# echo $weekday
#这样写什么也没有
[root@luffy-001 scripts]# 

可以把一个命令作为变量
普通字符串via你来定义测试

全局变量(环境变量)

大写、linux里面哪里都可以用(常用的$PATH、$LANG、$PS1)

在创建他们的Shell及其派生出来的子Shell中使用

与普通变量的区别

注意:普通变量是无法直接调用的,需要使用export将其转化成全局变量后方能使用,例子见下面代码

[root@luffy-001 scripts]# vim pizza.sh
#!/bin/bash

echo $PIZZA

~                                                                                                      
~                                                                                                      
~                                                                                                      
                                                                                                     
"pizza.sh" 4L, 26C written
[root@luffy-001 scripts]# PIZZA=10
[root@luffy-001 scripts]# echo $PIZZA
10
[root@luffy-001 scripts]# sh pizza.sh 


[root@luffy-001 scripts]# export PIZZA
[root@luffy-001 scripts]# sh pizza.sh 
10
[root@luffy-001 scripts]# 

分类

1、Shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录(LANG、PATH、SHELL、UID)

2、自定义环境变量:

建议所有环境变量均为大写

必须用export命令定义

查看全局变量:env

取消全局变量:unset  PIZZA

与用户环境变量有关的文件目录

全局环境变量配置文件

/etc/profile  

/etc/bashrc

/etc/profile.d/    用户登录到系统,会运行这个目录下面的脚本(脚本要有执行权限chmod +x)

用户环境变量配置文件

~/.bash_profile

~/.bashrc

特殊变量

位置变量

$0  获取当前执行脚本的文件名。如果执行脚本带路径,那么就包括脚本路径。模拟系统脚本使用$0

$n  n代表脚本后面的参数,

$#  脚本一共有多少个参数,参数的个数

进程状态变量

$? 显示上一个命令的执行结果

###命令执行正确  结果0

###命令执行错误  结果非0

变量赋值-如何向变量中放内容

1、直接给!

x=1
y=2
echo $x $y

w=$1
s=$2
echo $w $s

[root@luffy-001 scripts]# sh pizza.sh  10 20 
10
1 2
10 20

2、read

[root@luffy-001 scripts]# read -p "input x y:" x y
input x y:10 20
[root@luffy-001 scripts]# echo $x $y
10 20

可以将该语句直接放入脚本中执行

read得到的输入默认存储在变量REPLY中

可以存储在一个或者多个变量中

-p  “提示语句”, 屏幕就会显示交互式语句

-t   等待时间

-s  关闭回显,用于密码输入

条件表达式

[ <测试表达式> ]注意两边要有空格

判断文件

-f 判断文件是否存在
[root@luffy-001 scripts]# [ -f /server/scripts/pizza.sh ] [root@luffy-001 scripts]# echo $? 0
-d 判断目录是否存在 [root@luffy
-001 scripts]# [ -d /server/scripts/ ] [root@luffy-001 scripts]# echo $? 0

判断整数

等于equal                              -eq     

不等于not equal                     -ne

大于 greater than                   -gt

大于等于 greater equal           -ge

小于less than                          -lt

小于等于 less equal                -le

[root@luffy-001 scripts]# [ 1 -eq 1 ]
[root@luffy-001 scripts]# echo $?
0

简单案例:判断命令行参数个数等于2(配合&&)

1
[ $# -eq 2 ]  && echo "arg:"$#

题目:如果/oldboy目录不存在则创建

[ -d /oldboy ] || mkdir -p /oldboy


题目:如果/root/oldboy.txt存在则提示文件已存在

[ -f /root/oldboy.txt ] && echo file esists

if条件语句

单分支条件语句

语法:if [条件];then 命令 fi

题目:如果第一个数比第二个数大,显示第一个数大于第而个数

num1=$1
num2=$2

if [ $num1 -gt $num2 ]; then
    echo $num1 bigger than $num2
fi

多分支条件语句

语法:if [条件];then 命令 else 命令 fi

num1=$1
num2=$2

if [ $num1 -gt $num2 ]; then
    echo $num1 bigger than $num2
elif [ $num1 -lt $num2 ]; then 
  echo $num1 less than $num2
else
    echo $num1 equal $num2
fi

现在有一个问题是这样的:如果参数过多,也会运行,后面多余的参数变成了无用参数,只有一个参数会报错

num1=$1
num2=$2

if [ $# -ne 2 ];then
    echo "Usage:"please  input 2 num : num1 num2
    exit   
fi

if [ $num1 -gt $num2 ]; then
    echo $num1 bigger than $num2
else
    echo $num1 less than $num2
fi

[ -d /oldboy ]   相当于 test -d /oldboy

man test

for循环语句

语法格式:

for  变量名字  in  列表
do
  命令
done

例子:

[root@luffy-001 scripts]# for num in 1 2 3 4 5 
> do
> echo "the num is:$num"
> done
the num is:1
the num is:2
the num is:3
the num is:4
the num is:5

生成序列seq 或者{}

[root@luffy-001 scripts]# for num in {1..10}; do echo "the num is:$num"; done
the num is:1
the num is:2
the num is:3
the num is:4
the num is:5
the num is:6
the num is:7
the num is:8
the num is:9
the num is:10

题目:优化linux开机启动项,只保留crond;sshd;network;rsyslog;sysstat,其他的都关闭

提示:chkconfig 服务  off

初识shell编程第1张初识shell编程第2张
for name  in  $(chkconfig |egrep  "crond|sshd|rsyslog|network|sysstat" -v |awk '{print $1}')
do
     chkconfig $name off
done
View Code

查看脚本执行过程 -x

三、Shell脚本初步入门

什么是是shell?

shell原意,是贝壳,

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

什么是shell脚本?

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

先看一个清除日志的脚本

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

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

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

下面看一个完善的版本

#! /bin/bash
LOG_DIR=/var/log
ROOT_UID=0

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

# 第四关,通关失败,给出提示
echo 'cleaned logs fail!'
exit 1

shell脚本在Linux中的地位

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

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

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

初识shell编程第3张

初识shell编程第4张

Shell脚本的建立

1、脚本的第一行

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

2、bash和sh的区别

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

3、需要注意的地方

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

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

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

Shell脚本的执行

1. bash script-namesh 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-namecat scripts-name|sh

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

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

初识shell编程第5张

当我们登陆命令行,就相当于开启一个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编程第6张

shell脚本的编程规范和习惯

1.开头加脚本解释器
2.附带作者及版权信息
3.脚本扩展名为*.sh
4.脚本存放在固定的目录下
5.脚本中不用中文
6.成对的符号一次书写完成
7.循环格式一次性输入完成
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编程第7张

上图是文件加载的顺序

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

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

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

Shell普通变量

局部变量

当前用户或者脚本中生效

a.变量名:
规则:字母、数字、下划线,3者组合,以字母开头。
要求:见名知意1)OldboyAge=1
2)oldboy_age=1
3) oldboyAge=1  ###驼峰语法

b.变量内容
字符串:
变量名=value     #<==不加引号。 ##解析变量或者命令,然后输出,纯数字选择不加引号。
变量名=’value’   #<==加单引号。 ###所见即所得
变量名=”value”   #<==加双引号。 ##解析变量或者命令,然后输出,字符串默认选择双引号,可以把要定义的内容作为一个整体。

命令变量,把一个命令的结果赋值给变量
变量名=`ls`
变量名=$(ls)

小结:
针对变量名:
  1、变量名一定要有一定的命令规范,并且要见名知意,推荐使用驼峰法
  2、变量名仅能使用字母、数字、下划线的任意多个字符,并且要字母开头
针对变量内容:
  3、在脚本中定义普通字符变量,尽量使用双引号括起来。
  4、单纯数字的变量内容可以不加引号
  5、希望变量的内容鸳鸯输出需加单引号
  6、希望变量值引用命令并获取命令的结果就用反引号或者$()
针对赋值符号:
  7、变量定义使用赋值等号(=),赋值符号两端不要有空格
针对变量输出:
  8、使用或者输出变量的内容,可用 $ 变量名,$PS1
  9、若变量名(db)后面有其他字符链接的时候,就必需给变量名加上大括号

Shell特殊位置参数变量

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

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

初识shell编程第8张

特殊位置变量:
$0  获取脚本的名字,如果脚本前面跟着路径的话,那就获取路径加上脚本名字。
[root@web01 scripts]# cat test.sh
#!/bin/bash
echo $0
[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

$1,$2----$n
$1表示脚本后的第一个参数
$2表示脚本后的第二个参数
....
超过$9,${10}  要加{}大括号
企业应用:
case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)

$# 脚本后面所有参数的个数
企业应用:
[root@web01 scripts]# cat test.sh 
#!/bin/bash
if [ $# -ne 2 ]
then
   echo "Usage:$0 arg1 arg2"
   exit 1
fi
echo ok


$*  获取脚本的所有参数,“$1 $2 $3”
$@  获取脚本的所有参数,"$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编程第9张

$? 获取上一个命令的返回值,如果返回值为0就证明上一个命令执行正确,
非0,就证明上一个命令执行失败的。
*****

$$ 获取当前执行脚本的进程号

$! 获取上一个后台工作进程的进程号

$_ 获取上一个执行脚本的最后一个参数

Shell变量子串

初识shell编程第10张

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

[root@web01 scripts]# oldboy="I am oldboy"
[root@web01 scripts]# echo ${oldboy}
I am oldboy
[root@web01 scripts]# echo ${#oldboy}
11
[root@web01 scripts]# echo $oldboy|wc -L
11
[root@web01 scripts]# expr length "$oldboy"
11
[root@web01 scripts]# echo $oldboy|awk '{print length}'
11
[root@web01 scripts]# echo $oldboy|awk '{print length ($1)}'
1
[root@web01 scripts]# echo $oldboy|awk '{print length ($0)}'
11


练习题:
I am oldboy I teach linux
打印这些字符串中字符数小于3的单词。
涉及知识点:取字符串长度,for,if。

[root@web01 scripts]# echo ${oldboy:2}
am oldboy
[root@web01 scripts]# echo ${oldboy:2:2}
am
[root@web01 scripts]# echo ${oldboy:2:4}
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编程第11张

[root@web-01 ~]# 
[root@web-01 ~]# result=${test:-UNSET}
[root@web-01 ~]# echo $test

[root@web-01 ~]# echo $result
UNSET
[root@web-01 ~]# echo $test

[root@web-01 ~]# #当变量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编程第12张

Bash编程常见运算命令汇总

初识shell编程第13张

只适合整数运算
1、(()) 推荐
2、let 次推荐
3expr
4、$[]
既适合整数,又适合小数运算。
1、bc
2awk 推荐

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

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

[root@web-01 /server/scripts]# vim judge1.sh
#!/bin/bash

echo 6 + $1 &>/dev/null
if [ $? -eq 0 ]
then
        echo "$1 是整数"
else
        echo "$1 不是整数"
fi

"judge1.sh" [New] 9L, 112C written  
[root@web-01 /server/scripts]# bash judge1.sh 123
123 是整数
[root@web-01 /server/scripts]# bash judge1.sh ll
ll 是整数

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

[root@web-01 /server/scripts]# vim judge2.sh
  1 #!/bin/bash
  2 # :冒号两边要有空格
  3 expr "$1" : ".*.txt" &>/dev/null
  4 if [ $? -eq 0 ]
  5 
  6 then
  7         echo "$1 是文本"
  8 else
  9         echo "$1 不是文本"
 10 fi
~                                                                                       
~                                                                                                                                                                  
~                                                                                       
"judge2.sh" 10L, 152C written                                         
[root@web-01 /server/scripts]# bash judge2.sh old
old 不是文本
[root@web-01 /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-01 /server/scripts]# read -p "请输入一个数字:" a
请输入一个数字:11
[root@web-01 /server/scripts]# echo $a
11

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

[root@web-01 /server/scripts]# read -p "请输入两个数字:" a b
请输入两个数字:12 56

[root@web-01 /server/scripts]# echo $((a+b))
68

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

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

#!/bin/bash
cat <<EOF
        1install lamp
        2install lnmp
        3、exit
EOF
read -p "请选择一个序号(必须是一个数字):" num
# 先判断一下是不是数字
expr 2 + $num &>/dev/null if [ $? -ne 0 ] then echo "usage:$0 {1|2|3}" exit 1 fi if [ $num -eq 1 ] then echo "install lamp..." elif [ $num -eq 2 ] then echo "install lamp..." elif [ $num -eq 3 ] then echo "bye" else echo "usage:$0 {1|2|3}" exit 1 fi
数值运算命令:
只适合整数运算
1、(()) 推荐
2、let 次推荐
3expr
4、$[]
既适合整数,又适合小数运算。
1、bc
2awk 推荐

1、(()) 推荐
[root@web01 scripts]# i=$((a+1))
[root@web01 scripts]# echo $i
2
[root@web01 scripts]# 
[root@web01 scripts]# echo $((a+3))
4
[root@web01 scripts]# echo $((1+3))
4
[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

2、let 次推荐
[root@web01 scripts]# let i=$a+1
[root@web01 scripts]# echo $i
2

3、expr用于运算

4、$[]

=============
bc
awk
[root@web01 scripts]# echo 1+2|bc
3
[root@web01 scripts]# 
[root@web01 scripts]# echo 1.1+2|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 2 + 2
4
[root@web01 scripts]# expr 2 + a
expr: non-numeric argument
[root@web01 scripts]# echo $?
2
[root@web01 scripts]# 
[root@web01 scripts]# 
[root@web01 scripts]# 
[root@web01 scripts]# a=2
[root@web01 scripts]# expr 2 + $a &>/dev/null
[root@web01 scripts]# echo $?
0
[root@web01 scripts]# a=oldboy
[root@web01 scripts]# expr 2 + $a &>/dev/null
[root@web01 scripts]# echo $?
2


[root@web01 scripts]# cat judge1.sh
#!/bin/bash
expr 2 + $1 &>/dev/null
if [ $? -eq 0 ]
then
   echo "$1 is 整数"
else
   echo "$1 不是整数"
fi
[root@web01 scripts]# bash judge1.sh 123
123 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 0 ]
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=6
b=2
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))"

变量的赋值:
1、定义法
a=1

2、传参法
[root@web01 scripts]# cat test7.sh 
#!/bin/bash
a=$1
b=$2
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))"

3、read读入,读取用户输入。
-p 提示
-t 等待用户输入的时间

read -t 30 -p "请输入一个数字:"
[root@web01 scripts]# read -t 30 -p "请输入一个数字:" a
请输入一个数字:11
[root@web01 scripts]# echo $a
11
[root@web01 scripts]# a=11
[root@web01 scripts]# echo $a
11

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
  1.install lamp
  2.install lnmp
  3.exit
EOF
read -p "请选择一个序号(必须是数字):" num
#1.判断是否为整数
expr 2 + $num &>/dev/null
if [ $? -ne 0 ]
then
    echo "Usage:$0 {1|2|3}"
    exit 1
fi

#2.判断执行处理
if [ $num -eq 1 ]
then
    echo "install lamp..."
elif [ $num -eq 2 ]
then
    echo "install lnmp..."
elif [ $num -eq 3 ]
then
    echo "bye."
    exit 
else
    echo "Usage:$0 {1|2|3}"
    exit 1
fi
Shell的常见条件表达式语法介绍和实践

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

条件表达式常见语法

初识shell编程第14张

条件表达式的编程语法

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

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

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

if  [ 测试表达式 ]

then

  命令1

else

  命令2

fi

当命令很多的时候

[ 测试表达式 ]  && {

  命令1

  命令2

}| |{

  命令3

  命令4

}

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

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

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

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

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

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

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

初识shell编程第15张

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

初识shell编程第16张

注意:

1、字符串就用双引号

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

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

整数测试表达式

初识shell编程第17张

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

逻辑测试表达式

初识shell编程第18张

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

初识shell编程第19张


条件表达式6种写法:if,while
语法1: test <测试表达式>
语法2: [ <测试表达式> ]    #两端有空格
语法3:[[ <测试表达式> ]]  #两端有空格
语法4:((<测试表达式>))    #不需要空格

语法5:(命令表达式) 
语法6:`命令表达式`

编程语法:
[ <测试表达式> ] && 命令1
如果前面表达式成功,那么就执行后面命令。

[ <测试表达式> ] || 命令1
如果前面表达式失败,那么就执行后面命令。

[ <测试表达式> ] && {
命令1
命令2
命令3
}
如果前面表达式成功,那么就执行后面命令。

[ <测试表达式> ] && 命令1 || 命令2
如果前面表达式成功,那么就执行命令1,否则执行命令2。

[ <测试表达式> ] && {
命令1
命令2
}||{
命令3
命令4
}
如果前面表达式成功,那么就执行命令1,2,否则执行命令3,4<测试表达式>有哪些:


文件测试表达式:
为什么需要文件测试表达式?
操作一个对象,就要看对象条件是否满足,否则不要操作。
1、常见功能
2、实践
3、企业应用:启动脚本中的应用。


字符串测试表达式
[ -n "字符串" ]    字符串长度[不]为0,表达式为真。 not zero。
[ -z "字符串" ]    字符串长度为0,表达式为真。 zero。
[ "字符串1" == "字符串2" ]  两个字符串相同则为真。
[ "字符串1" !== "字符串2" ] 两个字符串不相同则为真。


注意:
1字符串就用双引号
2等号可以用一个或者两个3=号两端必须要有空格。
实践:
[root@web01 ~]# [ -n "oldboy" ] && echo 1 || echo 0
1
[root@web01 ~]# [ -z "oldboy" ] && echo 1 || echo 0
0
[root@web01 ~]# char="oldboy"
[root@web01 ~]# [ -z "$char" ] && echo 1 || echo 0
0
[root@web01 ~]# unset char
[root@web01 ~]# [ -z "$char" ] && echo 1 || echo 0
1
[root@web01 ~]# [ "dd" == "dd" ] && echo 1 || echo 0
1
[root@web01 ~]# [ "dd" == "ff" ] && echo 1 || echo 0
0
[root@web01 ~]# [ "dd" = "ff" ] && echo 1 || echo 0
0
[root@web01 ~]# [ "dd" != "ff" ] && echo 1 || echo 0
1
[root@web01 ~]# [ "dd" != "dd" ] && echo 1 || echo 0
0

改造上面的四则运算的脚本
企业应用:
[root@db03 scripts]# cat yunsuan1.sh
#!/bin/bash
##############################################################
# File Name: yunsuan.sh
# Version: V1.0
# Author: oldboy
# Organization: www.oldboyedu.com
# Created Time : 2018-05-30 09:03:10
# Description:
##############################################################
#!/bin/bash
read -p "pls input two num:" a b

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

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


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

01-第一章:如何学好shell编程。
必备基础:
1)熟练vim编辑器,.vimrc配置。
2)120个左右Linux命令。(跟老男孩学习Linux运维:核心命令实战)
3)网络服务,rsync,nfs,lamp,lnmp,ltmp,keepalived,lvs

如何学好:
1、锻炼编程思维
比如要先有大纲 第一章
1.1 1.1.1 1.1.2 第二章 2.1 2.1.1 2.1.2 2、多练,多思考,不要拿来主义。 3、有一本教科书。跟老男孩学习Linux运维:Shell编程实战 02-第二章:Shell基础入门 什么是shell 什么是shell脚本 shell脚本的建立 #!/bin/bash #### shell脚本的执行 4种方式: 1)bash/sh oldboy.sh #推荐使用 2)source/. oldboy.sh ***** 3sh/bash<oldboy.sh 4)./oldboy.sh或/server/scripts/oldboy.sh #必须要有执行权限。 Shell的执行过程 oldboy.sh: pwd ls oldgirl.sh #子shell ls oldgirl.sh & 放到后台执行。 并行,执行的同时,也执行下面的额ls 重点也是难点 source/. oldgirl.sh 相当于子Shell和父Shell相当于在一个shell里运行。 03-第三章 变量基础 1、什么是变量? oldboy="I am oldboy" oldboy是变量名,= 是赋值符号,"I am oldboy"是变量的内容。 OldboyAge oldboyAge #推荐。 oldboy_age 2、变量类型,shell里面是弱类型 decalre -i A #定义一个整形,一般没有这种需求 3、变量分类 环境变量(全局变量) 特点:大写 全局生效 1)系统的环境变量   PS1,PATH,LANG 直接用。 2)自定义环境变量 export OLDBOY=1 OLDBOY=1 export OLDBOY decalre OLDBOY=1 查看: 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 04-第四章 变量的扩展 1)特殊位置变量 $0 ***** 企业应用-脚本的结尾 $1,$2,$n ***** $# ***** 获取参数的个数 $* 两个的相同点和不同点 $@ 2)特殊状态变量 $? ***** $$ 进程号 $!上一个脚本的进程 $_ 上一个脚本的最后一个参数 相当于 esc+点 3)变量的子串 ${oldboy} ${#oldboy} wc -L ,expr length "$oldboy",awk '{print length }' ${oldboy:2} ${oldboy:2:2} ${oldboy#word} ${oldboy##word} ${oldboy%word} ${oldboy%%word} ${oldboy/dd/ff} ${oldboy//dd/ff} 4)变量特殊扩展 result=${oldboy:-word} # 推荐 **** result=${oldboy:=word} result=${oldboy:?word} result=${oldboy:+word} 霸道 第五章 变量的数值计算 整数: (()) 推荐 let 推荐 $[] expr declare declare -i a=4+3 echo $a 小数: bc 推荐加减 awk 乘除推荐 expr1)判断是否为整数。 2)扩展名 。忘记判断,记忆窍门 vim ·which ssh-copy-id· 3)取字符串长度 变量的定义: 1)a=1 2)传参 3)read读入 read -t 10 -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 条件语句

if是最常见的条件判断语句

初识shell编程第20张

初识shell编程第21张

例1:如果不存在/backup目录就创建。
[root@web-01 /server/tools]# vim 07-01.sh
#!/bin/bas
path=/backup
[ -d $path ] || mkdir $path -p
# 相当于
# :冒号表示什么也不干
if [ -d $path ]
then
        :
else
        mkdir $path -p
fi
# 或者
[ !-d $path ] && mkdir /backdir -p
# 相当于
if [ !-d $path ]
then
        mkdir /backdir -p
if
"07-01.sh" 18L, 248C writte
vim命令:替换:%s#/backup#$path#g
例2:开发Shell脚本判断系统剩余内存的大小,如果低于100MB就提示内存不足,否则提示内存充足。 考查if双分支: 分析:
1)提取系统内存。 2)if判断, [root@web01 07]# cat 07_02.sh #!/bin/bash ############################################################## # File Name: 07_02.sh # Version: V1.0 # Author: pizza # Created Time : 2018-06-06 22:58:54 # Description: ############################################################## mem=`free -m|awk 'NR==3{print $NF}'` if [ $mem -lt 1000 ] then echo "内存严重不足。" else echo "内存还够" fi

在第一章的中添加了内存不足发邮件的例子
例3:分别使用变量定义、read读入及脚本传参方式实现比较2个整数的大小。 1)变量定义: a=6 b=2 2)read读入: read -p "请输入两个数字:" a b 3)传参: 分析: 大于 等于 小于 #!/bin/bash
##############################################################
# File Name: 07-03.sh
# Version: V1.0
# Author: pizza
# Created Time : 2019-03-28 21:20:46
# Description:
##############################################################
# 第一种,传参
a=6
b=7
# 第二种,read
read -p "请输入两个数字" a b
# 第三种,参数
$a=$1
$b=$2
# 判断输入
# 1、判断数字是不是够,判断b是不是空,或者使用$#
# 2、判断是不是整数,利用expr
# 3、

if [ $a -gt $b ]
then
    echo "$a>$b"
elif [ $a -lt $b ]
then
    echo "$a<$b"
else
    echo "$a=$b"
fi

例4:打印一个菜单如下,当用户选择对应的数字时,就执行对应项的应用。
1.install lamp 2.install lnmp 3.exit 第一章已讲解: bash内置核心命令read的企业级应用实践 read企业应用 [root@web01 scripts]# cat select1.sh #!/bin/bash cat <<EOF 1.install lamp 2.install lnmp 3.exit EOF read -p "请选择一个序号(必须是数字):" num #1.判断是否为整数 expr 2 + $num &>/dev/null if [ $? -ne 0 ] then echo "Usage:$0 {1|2|3}" exit 1 fi #2.判断执行处理 if [ $num -eq 1 ] then echo "install lamp..." elif [ $num -eq 2 ] then echo "install lnmp..." elif [ $num -eq 3 ] then echo "bye." exit else echo "Usage:$0 {1|2|3}" exit 1 fi
Shell函数的知识与实践

函数的作用就是将程序里多次被调用的相同代码组合起来,并为其取个名字。其他所有想重复调用这部分代码的复方都只需要调用这个这个名字就可以了。当需要修稿这部分重复代码的时候,也只需要改变函数内的一份代码即可实现所有的修改,也可以把函数独立写到文件里面,当需要调用的时候,再加载进来。

函数的语法体

初识shell编程第22张

oldboy() {
    echo "I am oldboy."
}
function oldgirl {
    echo "I am oldgirl."
}
test() {
    echo "Hello world."
}
oldboy
oldgirl

[root@web-01 ~]# sh test_hanshu.sh
I am oldboy.
I am oldgirl.
Hello world.
[root@web-01 ~]#

向函数传参

带参数的函数编写执行
oldboy() {
    echo "I am $1."
}
oldboy oldboy
将函数传参转为脚本传参
oldboy() {
    echo "I am $1."
}
oldboy $1

函数和执行函数分离
./etc/init.d/function
pizza $1

Shell函数的执行注意事项

初识shell编程第23张

企业案例:通过脚本传参的方式,检查Web 网站URL是否正常。

wget命令:
--spider 模拟爬虫
-q 安静访问
-o /dev/null 不输出
-T --timeout 超时时间
-t --tries 重试次数
[root@web01 ~]# wget --spider -T 5 -q -o /dev/null -t 2 www.baidu.com
[root@web01 ~]# echo $?
0
curl命令:
-I 看响应头
-s 安静的 安静模式。不显示进度表或错误信息。使cURL 不反馈信息。
-o /dev/null 不输出
-w %{http_code} 返回状态码,200
-m 超时时间
[root@web01 ~]# curl www.baidu.com -s &>/dev/null [root@web01 ~]# echo $? 0 [root@web01 ~]# curl -I -m 5 -s -w "%{http_code} " -o /dev/null www.baidu.com 200 不用函数的实现写法 #!/bin/sh if [ $# -ne 1 ] then echo $"usage:$0 url" exit 1 fi wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==-T指定超时时间,这里的$1为脚本的参数。 if [ $? -eq 0 ] then echo "$1 is yes." else echo "$1 is no." fi 高端专业的函数写法: [root@oldboy ~]# cat checkurl.sh #!/bin/bash ############################################################## # File Name: checkurl.sh # Version: V1.0 # Author: oldboy # Organization: www.oldboyedu.com # Created Time : 2018-06-07 18:29:19 # Description: ############################################################## usage(){ echo "Usage:$0 url" exit 1 } checkurl(){ wget -q -o /dev/null -t 2 -T 5 $1 if [ $? -eq 0 ] then echo "$1 is ok" else echo "$1 is fail" fi } main(){ if [ $# -ne 1 ] then usage fi checkurl $1 } main $* [root@oldboy scripts]# cat 8_5_1.sh #!/bin/sh function usage() { #<==帮助函数 echo $"usage:$0 url" exit 1 } function check_url() { #<==检测URL函数。 wget --spider -q -o /dev/null --tries=1 -T 5 $1 #<==这里的$1就是函数传参。 if [ $? -eq 0 ] then echo "$1 is yes." else echo "$1 is no." fi } function main() { #<==主函数。 if [ $# -ne 1 ] #<==如果传入的多个参数,则打印帮助函数,提示用户。 then usage fi check_url $1 #<==接收函数的传参,即把结尾的$*传到这里。 } main $* #<==这里的$*就是把命令行接收的所有参数作为函数参数传给函数内部,常用手法。
CASE结构条件句

初识shell编程第24张

几乎所有的case都可以用if替代
case "$1" in
    1)
    dddd
    ;;
    2)
    dddd
    ;;
    *)
    dddd
esac

企业应用:
启动脚本
read 读入 菜单选择。

范例9_2:执行shell脚本,打印一个如下的水果菜单:
1.apple
2.pear
3.banana
4.cherry
当用户输入对应的数字选择水果的时候,告诉他选择的水果是什么,并给水果单词加上一种颜色(随意),要求用case语句实现。
范例9_3:给内容加不同的颜色。
内容的颜色用数字表示,范围为30-37,每个数字代表一种颜色。代码如下:
echo -e "

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Groovy操作符60个数据窗口技巧(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MySQL高可用方案--MHA部署及故障转移

架构设计及必要配置 主机环境 IP                 主机名             担任角色 192.168.192.128  node_master    MySQL-Master| MHA-Node 192.168.192.129  node_slave     MySQL-Slave | MHA-Node(备选Master) 19...

K8S从入门到放弃系列-(3)部署etcd集群

摘要:etcd 是k8s集群最重要的组件,用来存储k8s的所有服务信息, etcd 挂了,集群就挂了,我们这里把etcd部署在master三台节点上做高可用,etcd集群采用raft算法选举Leader, 由于Raft算法在做决策时需要多数节点的投票,所以etcd一般部署集群推荐奇数个节点,推荐的数量为3、5或者7个节点构成一个集群。 官方地址 https...

常见网页错误400/401/403/404/500网页错误代码表示的含义

转载:http://blog.csdn.net/yanchao315/article/details/76686827 HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求。不作修改,客户程序就无法重复此请求。 HTTP 错误 401 401.1 未授权:登录失败 此错误表明传输给服务器的证书与登录服务器所需的证书不匹配。 请与...

linux包之iproute之ip命令

[root@localhost ~]# rpm -qf /sbin/ipiproute-2.6.32-31.el6.x86_64ip 是个命令, ip 命令的功能很多!基本上它整合了 ifconfig 与 route 这两个命令ip - show / manipulate routing, devices, policy routing and tunne...

FTP操作(FTPClient)

//FTP开源封装的类 using System; using System.Collections.Generic; using System.Net; using System.IO; namespace FTP {     /// <summary>     /// FTP客户端操作类     /// </summary>  ...

DMA映射 dma_addr_t

DMA映射 一个DMA映射是要分配的DMA缓冲区与为该缓冲区生成的、设备可访问地址的组合。 DMA映射建立了一个新的结构类型——dma_addr_t来表示总线地址。dma_addr_t类型的变量对驱动程序是不透明的, 唯一允许的操作是将它们传递给DMA支持例程以及设备本身。 根据DMA缓冲区期望保留的时间长短,PCI代码有两种DMA映射: 1) 一致性映射...