启动$HADOOP_HOME/bin或者$HADOOP_HOME/sbin下的脚本,shell终端会显示输出信息;

根据输出信息,利用bash -x [script-name]的信息以及脚本本身,可以定位出错误是从什么位置开始的;

以下是在这些过程中,自己遇到的问题,以及是如何解决的;

1.在调用stop-yarn.sh脚本,关闭ResourceManager以及NodeManger的时候,会出现no NodeManager to stop;

  但是自己ssh到自己的slave节点,jps之后仍然显示有NodeManager进程;

  解决如下:

要点一: HADOOP_PID_DIR, 配置该环境变量,会在master节点的该目录下生成NameNode进程的PID文件(文件名的格式由脚本指定),该文件保存着NameNode进程的pid号;同理会在各个slave节点的该目录下生成DataNode进程的PID文件;以及SecondaryNameNode节点;

 YARN_PID_DIR,配置该环境变量,会在master节点的该目录下生成ResourceManager进程的PID文件,同理会在各个slave节点的该目录下生成NodeManager进程的PID文件;

 这两者的默认值为: /tmp;

要点二:  kill进程的时候,根据发出的信号值的不同,对进程的操作不同,比如kill 15 PID与kill 9 PID,在yarn-deamon.sh中:

(stop)
   if [ -f $pid ]; then
      TARGET_PID=`cat $pid`
      if kill -0 $TARGET_PID > /dev/null 2>&1; then  #kill -0 应该是判断进程是否存在
        echo stopping $command
        kill $TARGET_PID             #此处kill默认信号选项为15,term信号
        sleep $YARN_STOP_TIMEOUT
        if kill -0 $TARGET_PID > /dev/null 2>&1; then #发送term信号之后,并sleep之后,查看进程是否仍然存在
          echo "$command did not stop gracefully after $YARN_STOP_TIMEOUT seconds: killing with kill -9"
          kill -9 $TARGET_PID  #发送kill信号,给进程,强行杀死进程;
        fi
      else
        echo no $command to stop
      fi
      rm -f $pid
    else
      echo no $command to stop
    fi
    ;;

要点三:显示no NodeManager to stop; 一种是/tmp目录下的NodeManger的PID文件不存在,一种就是NodeManager的PID文件存在,但是当前没有NodeManager启动;排除后一种情况,因为slave节点仍然有NodeManager进程;可以通过更改这两个环境变量,自己分别指定生成PID的目录;

2. 在一个脚本中,调用另外一个脚本的多种方式:

1 # 不会产生sub-shell(子shell),就在当前进程中加载执行,执行完成后,其生成的变量,仍有效,执行完毕后会返回上一个脚本调用该脚本之后的命令
2 . $path/yarn-config.sh   #相当于source, 注意 .与路径之间有空格;
3 
4 # 会产生sub-shell,脚本在新建的进程中执行,相当于fork(),exec();其对变量的改变不会反应到父shell;
5 # 父shell在子shell执行完毕之后,仍继续执行
6 $path/yarn-daemon.sh   
7
8 #不会产生sub-shell,脚本在当前进程中执行完成之后,退出;不会返回上一个脚本继续执行后面的命令
9 #可以做个试验: exec ls;会发现执行完毕以后,shell就退出了;
10 exec java -cp $path [classname]

3.  bash -x [script-name]

#!/usr/bin/env bash
#hello.class在$HOME目录下

build_command(){
   java -cp $HOME hello
   return 3
} 

var=`build_command`   ++ build_command
                      ++ java -cp /home/mickeysun hello
                      ++ return 3
                      + var='Hello World!'

echo $?               + echo 3
                      3
echo $var             + echo Hello 'World!'
                      Hello World!

显示结果如下:
3
Hello World!

分析:
echo $? 显示的是build_command的返回值;
echo $var 显示的是build_command向标准输出中写入的内容;

右边是使用bash -x [script-name],显示的结果如右面所示;

4. CMD=():关于CMD的用法

 

  

6. IFS

7. while condition;do

        cmd

         ...

         cmd

  done < <()

8. read -d '' -r ARG

9.  $#   $@  shift   $0  $1  $?(在3中已有解释)

#!/usr/bin/env bash
                        #mickeysun@mickeysun:~$ ./test.sh mickey sun name
echo $@              #   mickey sun name
echo $#              #   3
echo $0              #   ./test.sh
echo $1              #   mickey
echo $2              #   sun
shift                 
echo $1              #   sun
echo $@              #   sun name
echo $#              #   2