shell详解 从原理到应用

第一章 Shell 概述

总的来说,shell其实就是一个命令行解释器,它用来接收应用程序或者用户的命令,然后调用操作系统内核来完成相应的任务。
这里所说的命令行解释器需要好好地理解下,说成大白话,解析器的实质就是将用户输入的指令转化为机器可以运行的程序,从而可以达到满足用户需求的目的。
在这里插入图片描述
我们为什么要用shell:shell是一个强大的编程语言,易编写、易调试、灵活性强。在linux中,我们常常编写shell脚本来满足我们的部分需求。例如,集群启动脚本,文件复制分发脚本。

1)linux中提供的shell解析器有(需要在etc目录下的shells中查看)
在这里插入图片描述
需要重点关注的是前两个/bin/sh和/bin/bash

2)bash和sh的关系
来到/home/atguigu(用户)/bin目录下,输入以下命令

[root@hadoop101 bin]$ ll | grep bash                                        
-rwxr-xr-x. 1 root root 941880 5月  11 2016 bash        //这一行表示我们当前linux默认用的是
                                                           bash解析器
lrwxrwxrwx. 1 root root      4 5月  27 2017 sh -> bash  //这一行表示linux中sh是bash的软连接

从代码中可以看出,**sh是bash的软连接,也就是sh是bash的快捷方式**,所以这样看来sh和bash在功能上,并没有什么实质上的区别。

3)Centos默认的解析器是bash
在这里插入图片描述
linux中我们用的解析器都是bash解析器

第二章 Shell脚本入门

1)脚本格式
脚本以**#!/bin/bash**开头(制定解析器为bash)

2)shell脚本简单示例:helloworld
(1)示例:创建一个shell脚本,输出helloworld
(2)案例实操:

首先打开一台已经创建完成的linux虚拟机,这里笔者的为hadoop101虚拟机,在/home目录下输入mkdir datas创建datas文件夹
然后再datas文件夹下进行以下操作:

[atguigu@hadoop101 datas]$ touch helloworld.sh           //创建helloworld.sh脚本文件
[root@hadoop101 datas]$ vi helloworld.sh                 //编辑helloworld文件

在helloworld.sh中输入如下内容
#!/bin/bash
echo "helloworld"

(3)脚本的常用执行方式
第一种:采用bash或sh加上脚本的相对路径或者绝对路径(这种方式不用赋予+x权限)
sh+脚本的相对路径:

[atguigu@hadoop101 datas]$ sh helloworld.sh
helloworld

扫描二维码关注公众号,回复: 12430499 查看本文章
sh+脚本的绝对路径:

[atguigu@hadoop101 datas]$ sh /home/atguigu/datas/helloworld.sh
helloworld

bash+脚本的相对路径:

[atguigu@hadoop101 datas]$ bash helloworld.sh
helloworld

bash+脚本的绝对路径:
[atguigu@hadoop101 datas]$ bash /home/atguigu/datas/helloworld.sh 
 helloworld

第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x

(a)首先要赋予helloworld.sh 脚本的+x权限
[atguigu@hadoop101 datas]$ chmod +x helloworld.sh

(b)执行脚本
相对路径
[atguigu@hadoop101 datas]$ ./helloworld.sh
helloworld
注意:这里必须加./,表示在当前目录下执行helloworld.sh脚本文件,若不加./则会报错。 绝对路径
[atguigu@hadoop101 datas]$ /home/atguigu/datas/helloworld.sh
helloworld

注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。

第三章 变量

3.1 系统预定义变量

1)常用系统变量
$ HOME、$ PWD、$ SHELL、$ USER等

2)案例实操
(1)查看系统变量的值
在这里插入图片描述
(2)显示当前shell中所有变量:set

     [atguigu@hadoop101 datas]$ set
     BASH=/bin/bash
     BASH_ALIASES=()
     BASH_ARGC=()
     BASH_ARGV=()

3.2 自定义变量

1)基本语法
(1)定义变量:变量=值
(2)撤销变量:upset 变量
(3)声明静态变量(也叫只读变量):readonly 变量 (注意:不能upset)
说明:有的读者会担心创建了静态变量过后,不能upset,也就是说不能撤销变量,使得变量会一直存在。这个大可不必,readonly 变量 只存在于当前连接的shell中,只要刷新一下与虚拟机的连接,或者建立新链接,再或者重启虚拟机,已经定义过的静态变量都不会再存在。

2)变量定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
(2)等号两侧不能有空格
(3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来

3)案例实操
(1)定义变量A

  [atguigu@hadoop101 datas]$ A=5
  [atguigu@hadoop101 datas]$ echo $A
   5

(2)给变量A重新赋值

    [atguigu@hadoop101 datas]$ A=8
    [atguigu@hadoop101 datas]$ echo $A
     8

(3)撤销变量A

     [atguigu@hadoop101 datas]$ unset A
     [atguigu@hadoop101 datas]$ echo $A

(4)声明静态的变量B=2,不能unset

       [atguigu@hadoop101 datas]$ readonly B=2
       [atguigu@hadoop101 datas]$ echo $B
       2
      [atguigu@hadoop101 datas]$ B=9
       -bash: B: readonly variable

(5)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算

        [atguigu@hadoop101 ~]$ C=1+2
        [atguigu@hadoop101 ~]$ echo $C
        1+2

(6)变量的值如果有空格,需要使用双引号或单引号括起来

         [atguigu@hadoop101 ~]$ D=I love banzhang
         -bash: world: command not found
        [atguigu@hadoop101 ~]$ D="I love banzhang"
        [atguigu@hadoop101 ~]$ echo $D
        I love banzhang

(7)可把变量提升为全局环境变量,可供其他Shell文件使用(当前的Shell对象中)

       export 变量名
       [atguigu@hadoop101 datas]$ vim helloworld.sh 

在helloworld.sh文件中增加echo $B

#!/bin/bash
      echo "helloworld"
      echo $B
     [atguigu@hadoop101 datas]$ ./helloworld.sh 
      Helloworld

发现并没有打印输出变量B的值。

    [atguigu@hadoop101 datas]$ export B
    [atguigu@hadoop101 datas]$ ./helloworld.sh 
    helloworld
     2

3.3 特殊变量

3.3.1 $ n
1)基本语法
$ n:n为数字,$ 0代表该脚本名称,$ 1-$ 9代表第一到第九个参数,十以上的参数需要用大括号包含,比如$ {10}

2)案例实操
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
chmod +x表示加上执行权限
在这里插入图片描述
3.3.2 $ #

1)基本语法
$ #:获取参数个数,常用语循环

2)案例实操

      [root@hadoop101 datas]$ vim parameter.sh
 #!/bin/bash
 echo "$0  $1   $2"
 echo $#

[atguigu@hadoop101 datas]$ chmod 777 parameter.sh

[atguigu@hadoop101 datas]$ ./parameter.sh cls  xz
parameter.sh cls xz 
 2

第四章 运算符

1) 基本语法
变量名=$ ((运算式))或 变量名=$ [运算式]
注意:这里的$ 符号必须加,表示对该运算式进行取值,若不加,将无法达到运算的效果。

2)案例实操
在这里插入图片描述
第五章 条件判断

1)基本语法
[ condition ]:condition为判断的条件。
注意:这里需要特别注意的是判断条件前后都必须要加上空格,不然会报执行错误,shell条件判断的语法较为特殊,需要重点记忆一下这里的前后空格符号。

2)常用判断条件
(1)两个整数之间比较
= 字符串比较
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
特别注意:在判断相等时,“=”是用来比较字符串,“-eq”是用来比较数值的
(2)按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write)
-x 有执行的权限(execute)
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence) -d 文件存在并是一个目录(directory)

第六章 流程控制(重点)

6.1 if判断

1)基本语法
(1)单分支
if [ 条件判断式 ]
then
程序
fi

(2)多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi

注意事项:
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格。
(2)if后要有空格。

2)案例实操
输入一个数字,如果是1,则输出banzhang zhen shuai,如果是2,则输出cls zhen mei,如果是其它,什么也不输出。
在这里插入图片描述 创建test3.sh脚本

在这里插入图片描述编写脚本程序

在这里插入图片描述增加test3.sh的执行权限

在这里插入图片描述执行结果

6.2 for循环

1)基本语法
for ((初始值;循环控制条件;变量变化))
do
程序
done

2)案例实操
从1加到100
在这里插入图片描述
在这里插入图片描述

6.3 while循环

1)基本语法
while [ 条件判断式 ]
do
程序
done

2)案例实操
从1加到100

在这里插入图片描述
编写test5.sh脚本文件

添加脚本
添加test5.sh的执行权限

在这里插入图片描述
结果

第七章 shell工具

7.1 cut
cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

基本用法:
cut [选项参数] filename
说明:默认分隔符是制表符

7.2 sed

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

基本用法
sed [选项参数] ‘command’ filename

7.3 awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

基本用法
awk [选项参数] ‘pattern1{action1} pattern2{action2}…’ filename
pattern:表示AWK在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令

第八章 实战演练

实战一:hadoop集群之间文件分发脚本

需求分析:在实际的大数据工作当中,大数据集群之间通常需要文件的复制和分发。在这里,我们建立一个以三台虚拟机为一个hadoop集群的应用场景,分别为hadoop101,hadoop102,hadoop103。然后编写脚本,实现三个虚拟机之间文件的复制传输。

代码编写:

#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]         //判断命令行输入参数是否小于1
then
  echo Not Enough Arguement!       //如果命令行输入参数小于1,输出“Not Enough Arguement!”
  exit;           //退出脚本程序
fi
#2. 遍历集群所有机器
for host in hadoop101 hadoop102 hadoop103         //遍历集群中的三台虚拟机
do
  echo ====================  $host  ====================
  #3. 遍历所有目录,挨个发送
  for file in $@           //遍历命令行中输入的文件
  do
    #4 判断文件是否存在
    if [ -e $file ]
    then
      #5. 获取父目录
      pdir=$(cd -P $(dirname $file); pwd)
      #6. 获取当前文件的名称
      fname=$(basename $file)
      ssh $host "mkdir -p $pdir"         //在目的虚拟机中的特定目录下(这里指的是获取的父目录)创建新目录或文件
      rsync -av $pdir/$fname $host:$pdir        //将需要分发的文件拷贝到目标虚拟机的制定路径下
    else
      echo $file does not exists!
    fi
  done
done

实战二 :kafka消息队列群起脚本

需求分析:在大数据的实际传输应用场景中,kafka几乎是一种不可或缺的工具。然而在虚拟机数量很大的情况下,一个一个的启动kafka显得十分麻烦,这时候编写一个kafka群起脚本可以十分方便的一键启动所有虚拟机上的kafka,从而解决掉挨个启动的问题。

代码编写:

#!/bin/bash
if [ $# -lt 1 ]
then
  echo "请输入参数!"
  exit
fi

for i in hadoop101 hadoop102 hadoop103
do
 case $1 in
   "start")            //如果命令行输入为start,则群起kafka
        echo "===============启动 $i 上的Kafka================="
    ssh $i /opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties        //启动目标虚拟机的kafka,并且启动守护进程,保证执行过程不会受到干扰  
    ;;
   "stop")        //如果命令行输入为stop,则关闭所有虚拟机的kafka
         echo "===============关闭 $i 上的Kafka================="
    ssh $i /opt/module/kafka/bin/kafka-server-stop.sh    //执行目标虚拟机中的关闭kafka的.sh脚本
    ;;
    *)
     echo "输入的参数不合法!!!"
     exit
    ;;
 esac
done

实战三:zookeeper群起脚本

需求分析:在大数据的实际传输应用场景中,zookeeper几乎是一种不可或缺的工具。然而在虚拟机数量很大的情况下,一个一个的启动zookeeper显得十分麻烦,这时候编写一个zookeeper群起脚本可以十分方便的一键启动所有虚拟机上的zookeeper,从而解决掉挨个启动的问题。

代码编写:


#!/bin/bash

case $1 in
"start"){              //如果命令行输入start则执行一下程序
	for i in hadoop101 hadoop102 hadoop103
	do
        echo ---------- zookeeper $i 启动 ------------
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
	done
};;
"stop"){
	for i in hadoop101 hadoop102 hadoop103
	do
        echo ---------- zookeeper $i 停止 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
	done
};;
"status"){           //如果命令行输入status命令,则查看集群的zookeeper的状态
	for i in hadoop101 hadoop102 hadoop103
	do
        echo ---------- zookeeper $i 状态 ------------    
		ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
	done
};;
esac

猜你喜欢

转载自blog.csdn.net/weixin_41929239/article/details/109511770