Shell Script 분석 연습 - Hadoop start-all.sh

Halim Kim·2021년 11월 13일
1

Shell Script

목록 보기
1/2

작성계기

요즘 Shell Script에 대해서 공부하고 있다. 연습이 필요해 Hadoop의 start-all.sh라는 스크립트를 분석해보면서 공부했던 내용도 리마인드하고 몰랐던 내용도 새로 알아보기 위해 시도해보았다.

start-all.sh라는 스크립트는 Hadoop Binary 파일 내에 포함되어 있으며, 클러스터 내에 존재하는 HDFS(Hadoop File System)의 Namenode와 Datanode는 물론 클러스터 매니저인 Yarn의 Resource Manager와 Node Manager를 같이 실행시켜 Hadoop 클러스터 운영을 시작하는 스크립트이다.

start-all.sh 파일은 $HADOOP_HOME_DIR/sbin에서 찾을 수 있다.


  • start-all.sh
#!/usr/bin/env bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

## @description  catch the ctrl-c
## @audience     private
## @stability    evolving
## @replaceable  no
function hadoop_abort_startall()
{
  exit 1
}

# let's locate libexec...
if [[ -n "${HADOOP_HOME}" ]]; then
  HADOOP_DEFAULT_LIBEXEC_DIR="${HADOOP_HOME}/libexec"
else
  this="${BASH_SOURCE-$0}"
  bin=$(cd -P -- "$(dirname -- "${this}")" >/dev/null && pwd -P)
  HADOOP_DEFAULT_LIBEXEC_DIR="${bin}/../libexec"
fi

HADOOP_LIBEXEC_DIR="${HADOOP_LIBEXEC_DIR:-$HADOOP_DEFAULT_LIBEXEC_DIR}"
# shellcheck disable=SC2034
HADOOP_NEW_CONFIG=true
if [[ -f "${HADOOP_LIBEXEC_DIR}/hadoop-config.sh" ]]; then
  . "${HADOOP_LIBEXEC_DIR}/hadoop-config.sh"
else
  echo "ERROR: Cannot execute ${HADOOP_LIBEXEC_DIR}/hadoop-config.sh." 2>&1
  exit 1
fi

if ! hadoop_privilege_check; then
  trap hadoop_abort_startall INT
  hadoop_error "WARNING: Attempting to start all Apache Hadoop daemons as ${USER} in 10 seconds."
  hadoop_error "WARNING: This is not a recommended production deployment configuration."
  hadoop_error "WARNING: Use CTRL-C to abort."
  sleep 10
  trap - INT
fi

# 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

1. Shebang

먼저 Shebang이란 스크립트 파일이 어떤 스크립트인지 알려주는 역할을 한다. (예를 들면 Python인지, Bash인지..)

추가! 정확히 말하면 스크립트를 실행할 인터프리터의 절대경로를 지정하는 것이다.

참고! '#!'인지 '!#'인지 헷갈려하는 사람이 있을 수도 있는데, 이름이 Shebang인 이유 자체가 '#(Hash 혹은 Number sign)'과 '!(Bang 혹은 exclamation mark)'인 것을 기억하면 된다.

스크립트 첫 라인부터 보이는 "#!/usr/bin/env bash"가 shebang이다. 그런데 책에서는 bash 스크립트를 작성할 때, "#!/bin/bash"로 shebang을 작성했는데, 여기서는 "#!/usr/bin/env bash"로 달랐다. 분명 bash 스크립트인 것은 같은 것이지만 무언가 차이가 있을 것이라고 생각하고 조사를 했더니 보통은 start-all.sh 파일에 붙은 shebang처럼 "#!/usr/bin/env bash" 형태를 많이 사용한다고 한다.

그 이유는 시스템마다 환경 구성이 다르기 때문이다. 나는 지금 CentOS 7 버전을 사용하고 있는데, Linux 배포판마다 인터프리터의 위치가 다를 수도 있을 것이다. 그러면 bash 인터프리터가 /bin 디렉토리에 존재하지 않을 수도 있고, 그렇게 되면 Shebang을 "#!/bin/bash"로 입력했을 때 인터프리터를 제대로 찾지 못할 수도 있는 것이다. 그래서 보통 "#!/usr/bin/env bash" 형태로 shebang을 입력하여 다양한 환경에서 스크립트가 실행될 수 있도록 한다.

참고! /usr/bin/env는 환경변수를 출력해주는 실행 가능한 프로그램이다. (env 명령어를 입력하면 /usr/bin/env가 실행되는 것이다.)

2. 함수

start-all.sh 파일 내에 함수는 하나 정의가 되어 있다. hadoop_abort_startall()이 그것인데, 함수 내용은 exit 1으로 내용은 딱히 없다. 다만 exit 0이 아니라 1이기 때문에 무언가 문제가 생겼을 때 사용되는 함수라는 것을 예상할 수 있다.

3. Locate libexec

첫 번째 if문을 보면 표현식 내에 -n 옵션$HADOOP_HOME이라는 변수가 있다. -n 옵션은 변수의 길이가 0이 아닐 때 True를 반환한다.(즉 $HADOOP_HOME 변수가 설정이 되어 있어야 조건문을 실행한다는 말이다.)

만약 $HADOOP_HOME 변수가 설정이 되어 있으면 HADOOP_DEFAULT_LIBEXEC_DIR라는 변수를 "$HADOOP_HOME/libexec"라고 설정한다.

그렇지 않으면 this라는 변수를 "${BASH_SOURCE-$0}"로 설정한다. 이 때 ${BASH_SOURCE-$0}은 변수 확장 변경자를 이용한 것으로 변수를 치환할 때, BASH_SOURCE가 설정되어 있지 않으면 $0로 치환되고 그렇지 않으면 BASH_SOURCE가 된다는 것이다.

그리고 bin 변수에는 $(cd -P -- "(dirname"(dirname -- "{this}")" >/dev/null && pwd -P)를 할당한다. cd와 pwd에 붙은 -P 옵션은 심볼릭 링크가 아닌 피지컬 링크를 사용한다는 의미이고, 리다이렉션을 통해 cd 명령의 출력값을 /dev/null로 보냈으니 출력하지 않겠다는 의미이다. 그리고 '&&'은 앞의 cd 명령어가 에러 없이 실행되었을 경우 뒤의 pwd 명령을 실행한다는 것이다.

마지막으로 HADOOP_DEFAULT_LIBEXEC_DIR 변수를 방금 전 설정한 bin 변수를 이용하여 할당하고 if문이 끝난다.

HADOOP_LIBEXEC_DIR 변수값은 변수 확장 변경자를 사용하여 HADOOP_LIBEXEC_DIR가 NULL이 아니라면 그대로 HADOOP_LIBEXEC_DIR 값을 가지고 그렇지 않으면 위의 if 조건문에서 설정된 HADOOP_DEFAULT_LIBEXEC_DIR값으로 치환된다.

4. start Hadoop & Yarn daemons

Hadoop과 Yarn Daemon들을 실행시키는 부분은 2개의 if문으로 구성되어 있다. 먼저 Hadoop Daemon을 실행시키는 if문을 보면 표현식 내에 -f 옵션이 들어가 있는데, 이는 file이 존재하고 보통의 파일이면 True를 반환한다.

if문 내에 기재된 파일은 ${HADOOP_HDFS_HOME}/sbin/start-dfs.sh이며 start-all.sh 파일과 같은 디렉토리에 존재하는 start-dfs.sh 파일이다. 그리고 함수의 내용은 그 파일을 실행하는 것이다.(--config 옵션으로 설정파일의 디렉토리도 설정된다.)

즉 start-all.sh는 그 자체로 Hadoop Daemon을 실행하도록 되어 있는것이 아니라 스크립트 파일이 또 다른 스크립트 파일(start-dfs.sh)을 실행시키는 것이다.

Yarn도 마찬가지이다. start-yarn.sh 파일이 있으면 그것을 실행한다.

profile
나는 하림

0개의 댓글