一起学习Shell脚本

640?wx_fmt=png

 什么是shell脚本? 

  脚本最初是从演艺界中的一个词,指表演戏剧、拍摄电影等所依据的底本或者书稿的底本。后来,IT行业引用了这个词,我们现在所说的脚本(script)是使用一种特定的描述性语言,依据一定的格式编写的可执行文件,又称作宏或批处理文件。脚本通常可以由应用程序临时调用并执行。shell脚本就是脚本语言中的一种。它不是一门正式的编程语言,因为跑在Linux的shell中,所以就称它为shell脚本。说白了,shell脚本就是一些命令的集合。我们可以利用shell脚本将很多个操作指令记录到一个文档中,然后调用文档中的指令,一次完成所有指令的操作。例如在hadoop中我们启动集群常用到start-all.sh来启动集群中的多个服务。这个start-all.sh就是一个shell脚本,我们今天就来看看start-all是怎样启动集群的。


学习之前,我们要指定两项规定:


  • 我们的自定义脚本建议都放在/user/local/sbin/目录下边,这样做是为了以后更好管理文档,也让以后接管你工作的同事知道脚本放在哪里。

  • 我们的shell脚本文件要将其设置为.sh文件。这样做的目的是为了让别人一看就知道这是一个shell脚本。

下面我们就来写一个Hello World的shell脚本:


  • 创建一个文件:

vi shellTest.sh
  • 编写shell脚本

#!/bin/bash	
echo "hello World" #这是一条输出语句

输出结果为:hello World


脚本解析:


  • 第一行中的#是一个约定标记,他告诉系统这个脚本需要什么解释器来执行,后面的/bin/bash就是指明了解释器的具体位置。

  • 第二行echo命令用于向标准输出文件(Standard Output,stdout,一般就是指显示器)输出文本。在.sh文件中使用命令与在终端直接输入命令的效果是一样的。

  • 第二行的#及其后面的内容是注释。(shell中除了开头的#!不是注释,其他的#都是注释)

后续文档参考命令符解释:


$        #$加变量名代表引用这个变量$0        #Shell本身的文件名$1~$n    #添加到Shell的各参数值。$1是第1参数、$2是第2参数…。$#       #是传给脚本的参数个数.        #如果使用” . "执行,则程序继承当前shell中的环境变量,同时,若在程序中改变了当前shell中的环境变量,则当前shell中该环境变量的值也会改变另外一个区别点在于, “ ./ "只能用于拥有执行权限的文件, 而 ” . " 则可以暂时提升执行权限if    ***    fi        #判断语句类似于Java中if{}-f        #判断给定的是不是文件case   ***    in    ***   esac    #类似java中的caseshift    #命令表示参数向左偏移,后面可跟数字(数字大小在参数个数范围内)


下面我们再来写一个稍微复杂一点的脚本:


#!/usr/bin/env bash	
bin=`dirname "${BASH_SOURCE-$0}"`  	
bin=`cd "$bin"; pwd`   #bin中存储当前脚本所在路径	

	
DEFAULT_LIBEXEC_DIR="$bin"/../libexec	
#获取HADOOP_LIBEXEC_DIR路径,如果系统环境变量已经配置则用环境变量中路径,否则用获取到的默认的路径	
HADOOP_LIBEXEC_DIR=${HADOOP_LIBEXEC_DIR:-$DEFAULT_LIBEXEC_DIR} 	
. $HADOOP_LIBEXEC_DIR/hadoop-config.sh	

	
# start hdfs daemons if hdfs is present	
if [ -f "${HADOOP_HDFS_HOME}"/sbin/start-dfs.sh ]; then	
  "${HADOOP_HDFS_HOME}"/sbin/start-dfs.sh --config $HADOOP_CONF_DIR	
fi	

	
# start yarn daemons if yarn is present	
if [ -f "${HADOOP_YARN_HOME}"/sbin/start-yarn.sh ]; then	
  "${HADOOP_YARN_HOME}"/sbin/start-yarn.sh --config $HADOOP_CONF_DIR	
fi


脚本解析:


第一行是指定我们的解释器,并指明了解释器的具体位置。

第二行相当于我们将文件目录的字符串赋值给了bin变量,${BASH_SOURCE-$0}这一串是为了获取当前执行的脚本文件的全路径,于是我们的bin就得到了脚本文件的全路径。

第三行我们首先执行了cd "$bin"($加上变量名可以用来引用这个变量),进入了脚本的目录环境,然后又输出了当前目录,并把这个目录给了bin变量。执行完这行之后我们就进入了脚本文件目录环境。并且bin值成为了当前脚本的所在文件。

第四行中我们获取绝对路径以备后用:

${HADOOP_HOME}/libexec

第五行为HADOOP_LIBEXEC_DIR变量三元赋值。如果HADOOP_LIBEXEC_DIR为空或者环境变量没有配置,就赋值默认的绝对路径,为下一步执行该目录下面的脚本做准备。

   第六行执行下面脚本。为后面执行启动各节点和启动YARN做预处理:

${HADOOP_HOME}/libexec/hadoop-config.sh

另外要提的是:

如果使用" ./ " 执行,可以理解为程序运行在一个全新的shell中不继承当前shell的环境变量的值同时若在程序中改变了当前shell中的环境变量(不使用export)则当前shell的环境变量值不变。如果使用" . "执行,则程序继承当前shell中的环境变量同时,若在程序中改变了当前shell中的环境变量则当前shell中该环境变量的值也会改变另外一个区别点在于" ./ "只能用于拥有执行权限的文件而 " . "则可以暂时提升执行权限。

第七行执行启动脚本,if是判断语句(类似于Java)fi是if的字母倒序,表示if判断语句结束;-f 做判断是不是文件类型。这段脚本的意图是:

如果${HADOOP_HDFS_HOME}/sbin/start-dfs.sh为文件,则联合--config参数及其后面的参数值执行start-dfs.sh。start-dfs.sh后面做详细分析。

第八行执行YRAN调度服务,这段脚本的意图是:

如果${HADOOP_HDFS_HOME}/sbin/start-yarn.sh为文件,则联合--config参数及其后面的参数值执行start-yarn.sh。start-yarn.sh后面做详细分析。

这就是完整的start-all.sh的shell执行流程。其中涉及到的start-yarn.sh和start-dfs.sh脚本,两个脚本十分类似,我们再看看start-dfs.sh脚本。

#!/usr/bin/env bash# Start hadoop dfs daemons.  # Optinally upgrade or rollback dfs state.  # Run this on master node.    usage="Usage: start-dfs.sh [-upgrade|-rollback]"  #定义usage变量,即start-dfs.sh的使用说明,在后面的内容可以看到,当参数输入错误时,会打印该消息  bin=`dirname "$0"`  bin=`cd "$bin"; pwd`    . "$bin"/hadoop-config.sh    # get arguments  if [ $# -ge 1 ]; then      nameStartOpt=$1      shift      case $nameStartOpt in        (-upgrade)          ;;        (-rollback)           dataStartOpt=$nameStartOpt          ;;        (*)            echo $usage            exit 1          ;;      esac  fi    # start dfs daemons  # start namenode after datanodes, to minimize time namenode is up w/o data  # note: datanodes will log connection errors until namenode starts  "$bin"/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode $nameStartOpt  "$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt  "$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR --hosts masters start secondarynamenode

    前面的代码我们上面已经解释过,不再赘述,要提的是,$0是指shell本身的文件名,其他的类似。后面的完整的判断语句的意思是:如果参数值的个数大于等于1的时候(代表还有服务需要开启),如果参数是upgrade,则设置nameStartOpt变量以备后用;如果是rollback,则设置dataStartOpt变量以备后用。

后面的脚本分别则是用来启动NameNode、DataNode、Master。


640?wx_fmt=jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值