배시 셸 스크팁트 프로그래밍(bash shell script programming)
- 자꾸 까먹어서 정리.
- 작성한 스크립트는 https://www.shellcheck.net/ 에서 코드 리뷰
For loop 사용
문법
for VARIABLE in 1 2 3 4 5 .. N do command1 ${VARIABLE} command2 ${VARIABLE} commandN ${VARIABLE} done
in 뒤에 조건문에는 $(COMMAND) 구문으로 명령어 실행 결과를 넣을 수 있음.
세 번 수행하면서 변수 출력
$ for i in 1 2 3;do echo $i;done
외부 명령어 결과 출력
$ for i in $(ls);do echo $i;done
{START..END..INCREMENT} 구문 사용
{ } 구문으로 루프의 조건을 지정할 수 있음. INCREMENT 를 생략할 경우 1 로 설정됨.
for i in {1..5} do echo "Welcome $i times" done
INCREMENT 지정
1, 3, 5 세 번 실행
for i in {1..5..2} do echo "Welcome $i times" done
Runtime Parameter 처리
파라미터의 갯수(argc) 는 $# 변수에 담기며 개별 파라미터(argv)는 $숫자 에 저장됨.
$0 은 프로그램 이름(쉘 스크립트명)이 저장되며 $1 부터 파라미터가 저장.
$@ 는 $1 .. $n 의 의미 - http://stackoverflow.com/questions/9994295/what-does-mean-in-a-shell-script
#!/bin/bash echo "Total Param= $#, PROG: $0, param1 = $1, param2 = $2";
bash 는 args 배열에 파라미터를 저장하므로 처리가 용이
#!bin/bash ## 파라미터가 없으면 종료 if [ "$#" -lt 1 ]; then echo "$# is Illegal number of parameters." echo "Usage: $0 [options]" exit 1 fi args=("$@") ## for loop 를 파라미터 갯수만큼 돌리기 위해 three-parameter loop control 사용 for (( c=0; c<$#; c++ )) do echo "$c th parameter = ${args[$c]}"; done
실행 결과
$ ./param.sh 0 is Illegal number of parameters. Usage: ./p.sh [options] $ ./param.sh first second third 0 th parameter = first 1 th parameter = second 2 th parameter = third
getopt
option 처리 라이브러리인 getopt 가 내장되어 있으므로 런타임 파라미터 작성시 사용하면 가독성에 많은 도움이 됨
compare oper
-eq, -lt 등의 연산자는 integer 비교만 가능하고 문자열 비교는 ==, != 사용
if [ "$a" == "OK" ];then //doit fi
조건문(if-else,elif)
if 문
Arithmetic tests
-eq, -ne 등의 연산자 사용 가능
if [ $var -eq 0 ];then echo "\$var is 0"; else echo "\$var is not 0"; fi
File test
-d(디렉터리 여부), -f(파일 존재) 등 파일 조건 검사 가능
## /etc/nginx/sites-available/ 디렉터리가 없으면 생성 if [ ! -d "/etc/nginx/sites-available/" ];then mkdir /etc/nginx/sites-available/ fi
String test
-z(문자열이 empty), -n(문자열이 none empty) 등
## $var 문자열이 공백인지 검사 if [ -z $var ];then echo "\$var is empty"; fi
if 문 안의 이중 대괄호( [[ ]])
bash(ksh, zsh 포함) 의 확장 기능으로 [] 에 비해 다양한 연산자를 사용할 수 있음
정규식
=~ 로 정규식 사용 가능.
#!/bin/bash -x line=' abcde fg' if [[ $line =~ [[:space:]]*(abc)?(de)* ]];then echo "${BASH_REMATCH[2]}" fi
File 처리
외부 파일을 입력값으로 사용
파일을 라인별로 읽어서 입력값으로 사용
#!/bin/sh while IFS='' read -r line || [[ -n "$line" ]]; do echo "Text read from file: $line" done < "$1"
Back ground 로 구동
bg 명령어로 백그라운드로 실행시 terminal 이 연결되어 있으므로 logout 하면 종료될 수 있다. 터미널과 연결을 끊어주는 nohup 명령어와 함께 표준입력과 표준 출력을 전환해 주면 로그아웃해도 의도한대로 백그라운드에서 작업이 수행된다.
nohup myprogram > foo.out 2> foo.err < /dev/null &
이제는 nohup 대신 systemd-run 명령어를 권장함.
root 로 실행했는지 여부
EUID 환경 변수 체크
if [ "$EUID" -ne 0 ];then echo "Please run as root" exit fi
외부 프로그램 실행 및 결과 확인
실행후 $? 변수를 체크해서 성공 여부 확인
exec "command" "option1" "option2" if [ $? -ne 0 ];then echo "command failed..." exit 1 fi
test 명령어 사용
변수 값이 empty 인지 확인
test 의 -z 연산자를 사용하면 변수에 값이 있는지 확인할 수 있음
if [ -z $VAR ]; then echo "$VAR is empty"; else echo "$VAR has value"; fi;
실행 파일이 존재하는지 확인
bash script 에서 실행 파일이 있는지 여부를 확인하려면 file 연산자를 사용해서 다음과 같이 코딩해야 함.
if [ ! -x "/usr/local/bin/stow" ] && [ ! -x "/usr/bin/stow" ];then # do somthing fi;
하지만 다른 PATH 에 실행 파일이 있을수 있으므로 다음과 같이 실행 파일의 존재 여부를 확인하면 됨.
#!/bin/bash # 체크 대상 프로그램 PROG=gawk if ! command -v ${PROG} &> /dev/null; then echo "${PROG} not found"; else echo "${PROG} is exist"; fi;