티스토리 뷰

요즘도 가끔은 Shell Script를 이용하여 환경정보를 조회하거나 수정하는 스크립트를 개발하곤 한다. 특히 관리해야 하는 서버 대수가 많은 경우에는 Ansible Playbook이나 쉘을 이용하여 한번 짜놓으면 계속 사용할 수 있는 코드를 만들기도 한다. 그런데, 그 중 Shell Script는 Ansible Module에서 제공하지 않는 기능을 대신 실행할때도 사용하기 때문에 Shell Script를 사용하는 방법들을 알아두면 유용할 것 같다는 생각이 든다. 물론 요즘은 인터넷이 잘 되고, 지식을 공유하는 사람들이 늘어서 쉽게 찾아볼 수 있지만, 그래도 내 블로그에 정리를 해두면, 오래동안 기억에 남을 것 같아서 이번 기회에 이번에 알게 되었던 Shell Script 사용법을 정리해 보고자 한다.

 

 

Sed를 통해 문자열 변경 및 추가하기

 

시스템을 설치하거나 운영하다보면 환경설정 파일에 특정 문자열을 변경해야 하거나, 특정 문자열 아래나 위줄에 설정 내용을 추가해야 할 경우가 생긴다. 이럴땐 sed 를 이용하면 쉽게 문자열을 변경할 수 있다.

아래 예제는 /etc/lvm/lvm.conf에 "# global_filter ="로 시작하는 문자열 아래에 "global_filter = [ "r|.*|" ]" 라는 문자열을 추가할때 활용할 수 있는 예제이다.

[nalee@localhost ~]$ sudo sed -i -e 's,\(\# global_filter =.*\),\1\n       global_filter = [ "r|.*|" ],g' /etc/lvm/lvm.conf

 

위의 예제를 가지고 공식을 확인해 보면 아래와 같다.

sed -i -e 's,\(찾을 문자열),\1\,변경할 문자열,g' 적용할 파일명

 

sed 뒤에 -i 옵션을 붙이면 뒤에서 선언한 파일에 변경한 값을 적용하겠다는 의미이다.

-e 옵션은 글자를 찾거나 변경할 때 shell이나 정규식을 사용하겠다는 의미이다.

예제의 찾을 문자열을 보면 "(\# global_filter =.*\)" 이렇게 쓰여있는데 이 경우는 # global_filter = 으로 시작하면서 뒤에 어떤 문자가 오든 상관없이 해당 문자열 바로 아래 한줄(\1) 뒤에 "global_filter = [ "r|.*|" ]" 이라는 문자열을 추가하겠다는 뜻이다. 

 

 

주석을 제거한 환경설정 파일 확인하기 

 

이번에 소개할 내용을 정말 많이 사용하는 shell 기능 중 하나로 대부분의 환경 설정 파일들은 환경변수 설명이나 예제가 환경설정 파일에 주석으로 들어가 있다. 그래서 정작 설정되어 있는 환경변수를 보려면 어떤 내용들이 있는지 보기가 힘든 경우가 많은데 이런 경우에는 아래와 같이 grep과 정규식을 이용하면 쉽게 주석을 제거한 환경변수 정보를 확인할 수 있다.

[nalee@localhost ~]$ sudo cat /etc/lvm/lvm.conf | grep -v '^[[:blank:]]*#' | grep -v '^$'

 

위 예제에서 봐야할 부분은 바로 grep 명령어 다음에 나오는 옵션과 문자열들이다. -v 옵션은 문자열에 해당하는 줄을 제외하겠다는 뜻이다. 이때 '^는 그 다음에 오는 문자열로 시작하는 이라는 뜻이다. 여기서는 '^[[:blank:]]*#'이 나왔는데 이 의미는 공백이나 스페이스가 하나 이상 있으며, #으로 시작하는 문자열이라는 뜻이다. 환경설정 파일에는 주석을  #으로 시작하기 때문에 여기서는 주석으로 처리된 줄은 빼겠다는 뜻이다. 그 뒤에 나오는 -v '^$'는 빈문자열로 줄만 있는 부분들이 있는데 해당 부분 역시 제외하겠다는 의미이다.

 

 

Shell Script를 이용한 오픈스택 명령어로 오픈스택 명령어 만들기

 

아래 예제는 Shell Script를 이용하여 특정 컴퓨트 노드의 vm를 다른 컴퓨트 노드로 라이브마이그레이션 하는 오픈스택 명령어를 파일로 저장하는 내용을 쉘 스크립트로 구현해 놓은 내용이다. 여기서 사용된 유용한 명령어들은 문자열을 찾기 위한 grep, 찾은 문자열 중 특정 문자열을 출력하기 위한 awk가 사용되었다. 

#!/bin/bash 

source /home/stack/overcloudrc 

HNAME=$1 
TNAME=$2 

if [ -n "$HNAME" ] && [ -n "$TNAME" ] 
then 
  Shost=$(openstack compute service list -c Binary -c Host | grep compute | grep $HNAME | awk '{print $4}') 
  Dhost=$(openstack compute service list -c Binary -c Host | grep compute | grep $TNAME | awk '{print $4}') 

  echo $Shost 
  echo $Dhost 

  openstack server list --host $Shost  --all-projects -c ID | grep -v '+-' | grep -v ID | awk -v t=$Dhost '{print "openstack server migrate "$2" --live "t" --wait"}' > /home/stack/vm_migrate_$HNAME.sh 
else 
  echo "Please input source and target hostnames." 
  echo "ex) sh migrate_vm_command.sh com01 com02" 
fi

 

awk의 print 기능을 이용하면 앞에서 찾은 문자열들 중 특정 인덱스에 있는 문자열만을 추출할 수 있다. 특히 awk에서 앞에서 찾은 문자열 이외에 외부에서 정의한 변수를 사용할 경우에는 아래와 같이 -v 옵션뒤에 다시 변수를 사용하여 print시 함께 사용할 수 있다.

awk -v t=$Dhost '{print "openstack server migrate "$2" --live "t" --wait"}' 

 

이번에 알게된 기능들은 시스템 운영시 자주 사용되는 명령어와 옵션들이므로 알아두면 매우 유용할 듯하여 이렇게 블로그에 남겨본다. 내가 자주 쓴다면 다른 사람들도 자주 쓴다는 이야기 아닐까? 하는 생각으로 정리해 본다.

댓글
  • 프로필사진 ioazs1240 질문있습니다.

    su -s /bin/sh -c "keystone-manage db_sync" keystone
    이명령어를 치면 트러블 슈팅 정보라던지 에러에 대한정보가 나와야하는거잖아요?
    아에 안나오면 무슨문제인가요?


    그리고 wsgi-keystone.conf 파일만든후 링크복사하고 service apache2 restart하니까 에러가나옵니다.

    Job for apache2.service failed because the control process exited with error code. See "systemctl status apache2.service" and "journalctl -xe" for
    2020.05.11 10:20
  • 프로필사진 Favicon of https://naleejang.tistory.com BlogIcon 나리 짱!!! naleejang 전 요즘 su -s /bin/sh -c "keystone-manage db_sync" keystone 이런 명령어는 잘 사용하지 않아요. 이 명령어는 트러블슈팅을 위한 정보나 에러 정보를 보여주는 명령어가 아니예요. 데이터베이스 동기화를 하기위한 명령어예요~!!

    그리고, service apache2 restart 했을때 에러가 나온다면 생성한 wsgi-keystone.conf 파일을 확인하셔야하지 않을까 싶습니다.

    어떤 문제가 있는지 journalctl -xe 명령어를 실행해서 확인해 보세요~!!
    2020.05.13 19:02 신고
댓글쓰기 폼