배시

From PGWiki
Revision as of 16:13, 21 May 2018 by Potatogim (talk | contribs) (배열을 매개 변수로 전달하기: 추가)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

배시(Bash, Bourne again shell)는 본셸을 GNU 프로젝트의 자유 소프트웨어로 대체하기 위해 브라이언 폭스가 작성한 유닉스/리눅스 셸이다.


구동 흐름

셸의 흐름.jpg


색상 정보

# Reset
Color_Off='\e[0m'       # Text Reset

# Regular Colors
Black='\e[0;30m'        # Black
Red='\e[0;31m'          # Red
Green='\e[0;32m'        # Green
Yellow='\e[0;33m'       # Yellow
Blue='\e[0;34m'         # Blue
Purple='\e[0;35m'       # Purple
Cyan='\e[0;36m'         # Cyan
White='\e[0;37m'        # White

# Bold
BBlack='\e[1;30m'       # Black
BRed='\e[1;31m'         # Red
BGreen='\e[1;32m'       # Green
BYellow='\e[1;33m'      # Yellow
BBlue='\e[1;34m'        # Blue
BPurple='\e[1;35m'      # Purple
BCyan='\e[1;36m'        # Cyan
BWhite='\e[1;37m'       # White

# Underline
UBlack='\e[4;30m'       # Black
URed='\e[4;31m'         # Red
UGreen='\e[4;32m'       # Green
UYellow='\e[4;33m'      # Yellow
UBlue='\e[4;34m'        # Blue
UPurple='\e[4;35m'      # Purple
UCyan='\e[4;36m'        # Cyan
UWhite='\e[4;37m'       # White

# Background
On_Black='\e[40m'       # Black
On_Red='\e[41m'         # Red
On_Green='\e[42m'       # Green
On_Yellow='\e[43m'      # Yellow
On_Blue='\e[44m'        # Blue
On_Purple='\e[45m'      # Purple
On_Cyan='\e[46m'        # Cyan
On_White='\e[47m'       # White

# High Intensity
IBlack='\e[0;90m'       # Black
IRed='\e[0;91m'         # Red
IGreen='\e[0;92m'       # Green
IYellow='\e[0;93m'      # Yellow
IBlue='\e[0;94m'        # Blue
IPurple='\e[0;95m'      # Purple
ICyan='\e[0;96m'        # Cyan
IWhite='\e[0;97m'       # White

# Bold High Intensity
BIBlack='\e[1;90m'      # Black
BIRed='\e[1;91m'        # Red
BIGreen='\e[1;92m'      # Green
BIYellow='\e[1;93m'     # Yellow
BIBlue='\e[1;94m'       # Blue
BIPurple='\e[1;95m'     # Purple
BICyan='\e[1;96m'       # Cyan
BIWhite='\e[1;97m'      # White

# High Intensity backgrounds
On_IBlack='\e[0;100m'   # Black
On_IRed='\e[0;101m'     # Red
On_IGreen='\e[0;102m'   # Green
On_IYellow='\e[0;103m'  # Yellow
On_IBlue='\e[0;104m'    # Blue
On_IPurple='\e[0;105m'  # Purple
On_ICyan='\e[0;106m'    # Cyan
On_IWhite='\e[0;107m'   # White

\e\033과 대체될 수도 있으며, 변수명을 echoprintf 등에 인라인으로 넣을 수도 있다.


재지향

  • 3.6 ᅟRedirections의 Duplicating File Descriptors와 Moving File Descriptors를 좀 더 이해할 필요가 있다.
  • N>&-는 파일 기술자 N을 닫아버린다.
  • N>/dev/null는 파일 기술자 N의 출력을 모두 널(NULL) 장치로 보내버린다.
  • >/dev/null1>/dev/null의 축약형 정도로 보면 된다. 표준 출력을 널 장치로 보낸다.
  • N>&M은 파일 기술자 N의 출력을 모두 M으로 보낸다.
  • |&2>&1 |의 축약형 정도로 보면 된다.[1]
  • &>/dev/null>/dev/null 2>&1의 축약형 정도로 보면 된다. 표준 출력/오류(STDOUT/STDERR)를 모두 널 장치로 보낸다.


SSH로 파이프 활용


파일에 기록하면서 터미널에도 출력하기

# Setup pipe for redirection stdout/stderr.
pipe=/tmp/$$.tmp
mknod $pipe p
tee < $pipe $$.log &

# Save stdout/stderr to 5/6.
exec 5>&1 6>&2

# Close stdout/stderr and re-open with pipe.
exec 1>&- 2>&-
exec 1>$pipe 2>$pipe

# Do something here.

# Restore stdout/stderr with 5/6 which save original stdout/stderr.
exec 1>&5 2>&6

# Close FD 5, 6.
exec 5>&- 6>&-

파일에서 바로 입력 받기

exec < $FILE

while read line
do
    ...
done


"${PARAMETER+WORD}"의 의미

${PARAMETER+WORD}으로 표현할 때, PARAMETER가 값이 있다면 WORD에 해당하는 문자열로 치환된다.


"${PARAMETER:-WORD}"의 의미

${PARAMETER:-WORD}으로 표현할 때, PARAMETER가 NULL이거나 설정되지 않았다면 WORD로 치환된다. 반대라면 PARAMETER로 치환된다.


비교 연산

문자열 비교 연산에서 주의점

[[ $a == z* ]]   # $a가 z로 시작하면 참 (패턴 일치)
[[ $a == "z*" ]] # $a가 z*이면 참 (문자열 일치)

[ $a == z* ]     # 파일 글로빙과 단어 분할이 일어난다.
[ "$a" == "z*" ] # $a가 z*이면 참 (문자열 일치)


중복 값 제거

for x in /path/to/add ... ; do
  case ":$PATH:" in
    *":$x:"*) : ;;         # 중복되는 항목이 있음
    *) PATH="$x:$PATH" ;;  # 중복되는 항목이 없음
  esac
done

혹은

export PATH="$MyPath${PATH+:}${PATH//$MyPath/}";


인용 및 회피

Bash Hackers Wiki의 Quotes and escaping에 다양한 예제들이 있다.


작은 따옴표(') 회피

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\'' (X)
alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'" (O)
                      12345

위 예에서 후자가 어떻게 동작하는지를 설명하면,

  1. 작은 따옴표를 사용하는 첫번째 인용구의 종료
  2. 큰 따옴표를 사용하는 두번째 인용구의 시작
  3. 인용 문자열
  4. 큰 따옴표를 사용하는 두번째 인요구의 종료
  5. 작은 따옴표를 사용하는 세번째 인용구의 시작

간단히 생각하자면 작은 따옴표로 둘러쌓이는 인용구 사이에 공백이 없다면 그냥 분리된 인용구로 만들어 버리고, 이를 읽는 셸에서는 하나로 취급하는 특징을 활용한 것이다.

그 외에도 아래와 같은 방법도 있다.

alias rxvt=$'urxvt -fg \'#111111\' -bg \'#111111\''


파이프 사용 시 각 명령의 종료 상태 얻기

# variable=$(a | few | commands; echo ": ${PIPESTATUS[*]}")
# PIPESTATUS=(${variable##*: })
# variable=${variable%:*}
# variable=${variable%$'\n'}

배열

[@][*]의 차이

두 가지 모두 배열의 모든 원소를 다루기 위해 사용되며, 다음과 같은 차이가 있다.

  • [@] - 배열의 원소 각각을 분리된 단어로 취급
  • [*] - 모든 배열의 원소를 IFS 기준으로 결합된 하나의 단어로 취급

예를 들어 perls=(perl-one perl-two)과 같은 배열이 있다고 할 때, ls "${perls[*]}"ls "perl-one perl-two"와 같이 확장되고, ls "${perls[@]}"ls "perl-one" "perl-two"와 같이 확장된다.

배열을 매개 변수로 전달하기

function myfunc
{
    declare -a arr1=("${!1}")
    echo "arr1: ${arr1[@]}"

    declare -a arr2=("${!2}")
    echo "arr2: ${arr2[@]}"

    return 0
}

ARR1=('a' 'b' 'c' 'd')
ARR2=(1 2 3 4)

myfunc ARR1[@] ARR2[@]
$ sh test.sh
arr1: a b c d
arr2: 1 2 3 4

주석

  1. Bash 버전 4부터 지원된다.


바깥 고리