LinuxShell编程
4.shell的变量
4.1Shell的变量的介绍
4.2.1基本句型
*4.2.3定义变量的规则
*4.2.4*将命令的返回值赋给变量
*4.2.5单冒号与双冒号的区别
5.设置环境变量
5.1基本句型
6.位置参数变量
6.1介绍
7.预定义变量
7.1基本介绍
8.运算符
9.条件判定
9.1基本句型
10.流程控制
10.1if判定
比较$*和$@区别
*for循环体中使用cat
11.read读取控制台输入
12.函数
12.1系统函数
13.Shell编程综合案例
1.为何要学习Shell编程
1)Linux运维工程师在进行服务器集群管理时,须要编撰Shell程序来进行服务器管理。
2)对于JavaEE和Python程序员来说,工作的须要,你的老大会要求你编撰一些Shell脚本进行程序或则是服务器的维护,例如编撰一个定时备份数据库的脚本。
3)对于大数据程序员来说,须要编撰Shell程序来管理集群。
2.Shell是哪些
Shell是一个命令行类库,它为用户提供了一个向Linux内核发送恳求便于运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编撰一些程序.
Linux中的Shell有好多类型,其中最常用的几种是:
1)Bourneshell:是UNIX最初使用的shell,而且在每种UNIX上都可以使用,在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。
2)BourneAgainshell:Linux操作系统缺省的shell是BourneAgainshell,它是Bourneshell的扩充,简称Bash,与Bourneshell完全向后兼容嵌入式linux驱动程序设计从入门到精通,但是在Bourneshell的基础上降低、增强了好多特点。Bash置于/bin/bash中,它有许多特色linux设置环境变量,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了好多Cshell和Kornshell中的优点,有灵活和强悍的编程插口,同时又有很友好的用户界面。
Linux提供的Shell解析器有:
1
2
3
4
5
6
7
8
9 1[tom@hadoop101 ~]$ cat /etc/shells
2/bin/sh
3/bin/bash
4/sbin/nologin
5/bin/dash
6/bin/tcsh
7/bin/csh
8
9
bash和sh的关系:
1
2
3
4
5 1[tom@hadoop101 bin]$ ll | grep bash
2-rwxr-xr-x. 1 root root 941880 5月 11 2016 bash
3lrwxrwxrwx. 1 root root 4 5月 27 2017 sh -> bash
4
5
Centos默认的解析器是bash:
1
2
3
4 1[tom@hadoop102 bin]$ echo $SHELL
2/bin/bash
3
4
3.快速入门shell脚本3.1哪些是脚本
脚本是针对于解释型语言,编译型语言没有这个东西。由于编译型语言直接编译为机器码,不须要解释执行。
脚本究竟是啥呢?
脚本就是解释型语言命令行的一个集合。
3.2脚本格式要求
1.脚本以#!/bin/bash开头
#!/bin/bash是指:此脚本使用/bin/bash来解释执行
虽然第一句的#!是对脚本的类库程序路径,脚本的内容是由类库解释的,我们可以用各类各样的类库来写对应的脚本。
例如说/bin/csh脚本,/bin/perl脚本,/bin/awk脚本,/bin/sed脚本,甚至/bin/echo等等。
2.脚本须要有可执行权限
chmod744myshell.sh
3.3脚本的常用执行方法
1.方法1:赋于脚本文件可执行权限
当使用命令./shell.sh自执行该脚本时,首先得有执行权限;其次脚本得指定类库(如以#!/bin/bash开头);假如没有指定,则默认以bash类库执行。
2.方法2使用指定原语执行脚本:sh+脚本
当脚本使用指定例程时,使用该例程执行脚本。
3.4shell脚本的显存环境
当使用shell通过SSH远程登陆到linux系统时,系统会创建一个对应的shell进程,该进程是sshd进程的子进程,每位登陆的shell都有一个自己的进程。
比如,使用Xshell打开两个系统会话,同时在一个会话中输入命令bash。系统中会有如下进程:
1
2
3
4
5
6
7
8
9 1当前用户 当前进程ID 父进程ID 启动进程所用的命令和参数
2root 2345 1 0 10:02 ? 00:00:00 /usr/sbin/sshd
3root 3153 2345 0 10:29 ? 00:00:02 sshd: root@pts/0
4root 3157 3153 0 10:29 pts/0 00:00:00 -bash
5root 3506 2345 0 14:46 ? 00:00:00 sshd: root@pts/1
6root 3512 3506 0 14:47 pts/1 00:00:00 -bash
7root 3533 3512 0 14:48 pts/1 00:00:00 bash
8
9
可以看出,每一个SSH联接就会创建一个sshd进程的子进程,如2345进程的3153、3506子进程,并为当前shell——bash创建一个子进程。
而进程3533是在进程3512对应的bash环境中输入bash命令开启的子进程,属于3512shell的子shell。
shell变量储存在哪?
在当前shell中定义的变量储存在自身进程的显存中,当进程结束(如当前会话结束),相应的显存也就释放,变量也都会释放。
怎么永久使用?
将shell变量储存到系统变量中。
注意:执行的shell脚本与自己使用的shell不是一个shell
如有以下脚本a.sh
1
2
3
4
5
6 1#!/bin/bash
2mkdir a
3cd a
4touch b.txt
5
6
运行以后,并不会转入a目录。
由于:执行脚本时,会在当前shell下启动一个子shell——这是一个独立的shell。同样的,在当前shell中直接输入以下命令也是同样的疗效:
1
2
3
4
5
6
7 1bash ->即启动一个bash环境的子shell
2mkdir a
3cd a
4touch b
5exit ->退出到自己的shell
6
7
为何要使用bash启动一个子shell?
由于,当前shell并不一定是bash环境。
脚本中不能使用父shell中的变量,除非:
1)exporta->将shell变量输出为环境变量
或
2)sourcea.sh->将脚本在当前shell环境中执行脚本,并不创建子shell
4.shell的变量4.1Shell的变量的介绍
1)LinuxShell中的变量分为:
2)系统变量:$HOME、$PWD、$SHELL、$USER……
echo$HOME
myshell.sh中的内容:
3)显示当前shell中所有变量:set
4.2shell变量的定义4.2.1基本句型
案例
案例1:定义变量Alinux中read p的使用,撤消变量A
案例2:定义静态变量B,尝试撤消静态变量
a)脚本内容:
b)脚本运行结果:
4.2.3定义变量的规则
1)变量名称可以由字母、数字和顿号组成,而且不能以数字开头。
2)等号两边不能有空格****
3)变量名称通常习惯为小写
4.2.4*将命令的返回值赋给变量
1)A=
1`
ls-la
1`
反顿号:运行上面的命令,并把结果返回给变量A
2)A=$(ls-la)等价于反顿号
4.2.5单冒号与双冒号的区别
单冒号会手动对引入的内容作通配符,即清除特殊字符的意义。
1
2
3
4 1[root@hadoop100 shell]# ./a.sh b
2ccc
3
4
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1#!/bin/bash
2# 双引号括起,$1依旧表示为传入的第一个参数
3if [ "$1"x = ax ]
4then
5 echo aaa
6# 单引号括起,$1表示为一个普通字符串
7elif [ '$1'x = bx ]
8then
9 echo bbb
10else
11 echo ccc
12fi
13
14
5.设置环境变量5.1基本句型
export变量名=变量值(功能描述:将shell变量输出为环境变量)
source配置文件(功能描述:让更改后的配置信息立刻生效)
echo$变量名(功能描述:查询环境变量的值)
案例:
1)在/etc/profile文件中定义TOMCAT_HOME环境变量
2)查看环境变量TOMCAT_HOME的值
echo$TOMCAT_HOME
3)在另外一个shell程序中使用TOMCAT_HOME
注意:在输出TOMCAT_HOME环境变量前,须要让其生效
source/etc/profile
5.2自定义环境变量
不建议在/etc/profile文件直接配置环境变量。看该文件的注释:去/etc/profile.d/文件夹,自定义自己的文件配置!!
1
2
3
4
5
6
7
8
9
10
11
12
13 1[zxy@hadoop101 software]$ sudo vi /etc/profile
2# /etc/profile
3
4# System wide environment and startup programs, for login setup
5# Functions and aliases go in /etc/bashrc
6
7# It's NOT a good idea to change this file unless you know what you
8# are doing. It's much better to create a custom.sh shell script in
9# /etc/profile.d/ to make custom changes to your environment, as this
10# will prevent the need for merging in future updates.
11……
12
13
除非你晓得你在做哪些,否则改变这个文件不是一个好主意。在/etc/profile.d/中创建一个custom.shshell脚本来对环境进行自定义修改要好得多,由于这将满足将来的更新中的合并需求。
案例:配置JDK环境变量
1
2
3
4
5
6
7 1[zxy@hadoop102 ~]$ cd /etc/profile.d/
2[zxy@hadoop102 profile.d]$ sudo vim jdk.sh
3#JAVA_HOME
4export JAVA_HOME=/opt/module/jdk1.8.0_144
5export PATH=$PATH:$JAVA_HOME/bin
6
7
保存后退出,让更改后的文件生效,并测试JDK是否安装成功:
1
2
3
4
5 1[atguigu@hadoop101 jdk1.8.0_144]$ source /etc/profile
2[atguigu@hadoop101 jdk1.8.0_144]$ java -version
3java version "1.8.0_144"
4
5
6.位置参数变量6.1介绍
当我们执行一个shell脚本时,假若希望获取到命令行的参数信息,就可以使用到位置参数变量。
例如:./myshell.sh100200,这个就是一个执行shell的命令行,可以在myshell脚本中获取到参数信息
6.2基本句型
$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数须要用大括弧包含,如${10})
案例:编撰一个shell脚本positionPara.sh,在脚本中获取到命令行的各个参数信息
7.预定义变量7.1基本介绍
就是shell设计者事先早已定义好的变量,可以直接在shell脚本中使用
7.2基本句型7.3应用实例
在一个shell脚本中简单使用一下预定义变量
8.运算符
学习怎样在shell中进行各类运算操作。
基本句型
$((运算式))或$[运算式]exprm+n
注意expr运算符间要有空格
exprm–nexpr*,/,%乘,除,取余
9.条件判定9.1基本句型
[condition](注意condition前后要有空格)
或
testcondition
[condition]:当条件非空返回true,可使用$?验证(0为true,>1为false)
9.3常用判定条件
1)两个整数的比较
[2-le5](2大于等于5)
2)根据文件权限进行判别
[-r文件]
3)根据文件类型进行判别
4)多条件判定(&&表示前一条命令执行成功时linux中read p的使用,才执行后一条命令,||表示上一条命令执行失败后,才执行下一条命令)
案例实操:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 1(1)23是否大于等于22
2[zxy@hadoop101 datas]$ [ 23 -ge 22 ]
3[zxy@hadoop101 datas]$ echo $?
40
5
6(2)helloworld.sh是否具有写权限
7[zxy@hadoop101 datas]$ [ -w helloworld.sh ]
8[zxy@hadoop101 datas]$ echo $?
90
10
11(3)/home/atguigu/cls.txt目录中的文件是否存在
12[zxy@hadoop101 datas]$ [ -e /home/atguigu/cls.txt ]
13[zxy@hadoop101 datas]$ echo $?
141
15
16(4)多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
17[zxy@hadoop101 ~]$ [ condition ] && echo OK || echo notok
18OK
19[zxy@hadoop101 datas]$ [ condition ] && [ ] || echo notok
20notok
21
22
9.4应用实例
案例1:“ok"是否等于"ok”
案例2:23是否小于等于22
案例3:/root/install.log目录中的文件是否存在
案例4:myshell.sh文件是否有可执行权限
判定条件也可以使用test替换,详情见mantest
10.流程控制10.1if判定
1.if判定基本句型
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1if [ 条件判断式 ]
2then
3 程序
4fi
5或者
6if [ 条件判断式 ]
7 then
8 程序
9 elif [条件判断式]
10 then
11 程序
12fi
13
14
2.注意事项:
3.应用实例
案例:请编撰一个shell程序,倘若输入的参数,小于等于60,则输出“及格了”,假如大于60,则输出“不及格”
10.2case句子
1.基本句型
1
2
3
4
5
6
7
8
9
10
11
12
13
14 1case $变量名 in
2"值 1")
3 如果变量的值等于值 1, 则执行程序 1
4;;
5"值 2")
6 如果变量的值等于值 2, 则执行程序 2
7;;
8 …省略其他分支…
9*)
10如果变量的值都不是以上的值, 则执行此程序
11;;
12esac
13
14
2.实例
当命令行参数是1时,输出“周一”,是2时,就输出"周日",其它情况输出“other”
10.3for循环
1.基本句型1
1
2
3
4
5
6 1for 变量 in 值 1 值 2 值 3…
2do
3 程序
4done
5
6
应用实例
案例1:复印命令行输入的参数【会使用到$*与$@】
比较$*和$@区别
1)$*和$@都表示传递给函数或脚本的所有参数,不被双冒号“”包含时,都以$1$2…$n的方式输出所有参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 1[tom@hadoop101 datas]$ touch for.sh
2[tom@hadoop101 datas]$ vim for.sh
3
4#!/bin/bash
5# 不加双引号
6for i in $*
7do
8 echo "ban zhang love $i "
9done
10
11for j in $@
12do
13 echo "ban zhang love $j"
14done
15
16[tom@hadoop101 datas]$ bash for.sh cls xz bd
17ban zhang love cls
18ban zhang love xz
19ban zhang love bd
20ban zhang love cls
21ban zhang love xz
22ban zhang love bd
23
24
2)当它们被双冒号“”包含时,“$*”会将所有的参数作为一个整体,以“$1$2…$n”的方式输出所有参数;“$@”会将各个参数分开,以“$1”“$2”…”$n”的方式输出所有参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 1[tom@hadoop101 datas]$ vim for.sh
2
3#!/bin/bash
4#$*中的所有参数看成是一个整体,所以这个for循环只会循环一次
5for i in "$*"
6do
7 echo "ban zhang love $i"
8done
9
10#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
11for j in "$@"
12do
13 echo "ban zhang love $j"
14done
15
16[tom@hadoop101 datas]$ chmod 777 for.sh
17[tom@hadoop101 datas]$ bash for.sh cls xz bd
18ban zhang love cls xz bd
19ban zhang love cls
20ban zhang love xz
21ban zhang love bd
22
23
2.基本句型2
1
2
3
4
5
6 1for (( 初始值;循环控制条件;变量变化 ))
2do
3 程序
4done
5
6
应用实例
案例1:从1加到100的值输出显示
for循环体中使用cat
1
2
3
4
5
6
7
8
9 1# 将文件中的数据作为遍历对象
2for i in `cat $HADOOP_HOME/etc/hadoop/workers`
3do
4 echo "========== Start Zookeeper in $i =========="
5 ssh $i '$ZOOKEEPER_HOME/bin/zkServer.sh start'
6 echo $?
7done
8
9
10.4while循环
1.基本句型
1
2
3
4
5
6 1while [ 条件判断式 ]
2do
3 程序
4done
5
6
2.应用实例
案例1:从命令行输入一个数n,统计从1+…+n的值是多少?
11.read读取控制台输入
1.基本句型
read[选项][参数]
1)选项:
2)参数:
2.应用实例
案例1:读取控制台输入一个num值
案例2:读取控制台输入一个num值,在10秒内输入。
12.函数
函数介绍:
shell编程和其它编程语言一样,有系统函数,也可以自定义函数,(系统函数中,我们这儿就介绍两个)。
12.1系统函数
**1)basename**
基本句型:
basename[pathname][suffix]
basename[string][suffix](功能描述:basename命令会删除所有的前缀包括最后一个(‘/’)字符,之后将字符串显示下来。
选项:
**2)dirname**
基本句型:
dirname文件绝对路径
12.2自定义函数
1)基本句型
1
2
3
4
5
6
7
8 1[ function ] funname[()]
2#方括号表示可选
3{
4 Action;
5 [return int;]
6}
7
8
2)应用实例
案例1:估算输入两个参数的和(read):getSum
3)经验方法
13.Shell编程综合案例
1.需求剖析