Shell script (Bash/sh) 기본

sosimeow·2022년 8월 9일
0

Linux/Ubuntu

목록 보기
1/5

주로 대표 참조 를 참고해 공부 및 기록 목적으로 작성한 포스팅으로, 현재 맡은 프로젝트에서 필요했던 내용이 추가로 포함되어 있습니다.




0. /bin/sh 와 /bin/bash


Ubuntu 20.04.4 기준 기본 쉘로 dash 를 사용하고 있다

아래 command 를 통해 "/bin/sh" 은 dash 쉘에 링크를 걸어둠을 알 수 있다

$ ls -al /bin/sh
lrwxrwxrwx 1 root root 4 Apr 23  2020 /bin/sh -> dash

하지만 여전히 bash 쉘도 사용되고 있는데,

개발용 shell sctipt 등 상당 수 스크립트가 아직 #!/bin/bash 를 달고 있고, 로그인은 dash 대신 bash 쉘을 사용하고 있기 때문이다.

# 로그인 쉘로 bash 사용함을 확인

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash

dash 와 bash 가 각자 사용되어지는 기능을 더 자세히 알고자 하면 아래 참조를 참고하자

https://storycompiler.tistory.com/101

또한 기본 쉘을 bash 로 바꾸는 방법은 아래 참조를 참고하자

https://faq.hostway.co.kr/Linux_ETC/7267



1. 문자 출력

echo > 문장을 출력하는데 자동으로 줄바꿈 됨

printf > C언어와 비슷

#!/usr/bin/env bash
echo "hello world"
printf "hello world"
printf "%s %s" hello world



2. 주석

#으로 시작



3. 함수 (Function)


string_test() {
    echo "string test"
}

function string_test2() {
    echo "string test 2"
    echo "인자값: ${@}"
}
string_test
string_test2

# 함수에 인자값 전달하기(공백의로 뛰어서 2개의 인자값을 넘김)
string_test2 "hello" "world"



4. 변수 (Variable)


  • 변수 사용시에는 "=" 기호 앞뒤로 공백이 없이 입력하면 대입연산자가 됨

  • 선언된 변수는 기본적으로 전역 변수(global variable)

  • 함수 안에서만 지역 변수(local variable) 사용 가능 -> 그 외에 사용하려면 변수 명 앞에 local 을 붙여주면 됨

  • 변수 명 앞에 export 을 붙여주면 환경 변수(environment variable) 로 설정되어 자식 스크립트에서 사용 가능
    -> 환경 변수 사용시 예약 변수 (reserved variable) 에 주의, 환경 변수는 .bash_profile 에서 정의


# 전역 변수 지정
string="hello world"
echo ${string}

# 지역 변수 테스트 함수
string_test() {
    # 전역 변수와 동일하게 사용함. 만약 local 뺀다면 전역 변수에 덮어씌어지게 됨
    local string="local"
    echo ${string}
}
# 지역 변수 테스트 함수 호출
string_test
# 지역 변수 테스트 함수에서 동일한 변수 명을 사용했지만 값이 변경되지 않음
echo ${string}

# 환경 변수 선언
export hello_world="hello world..."
# 자식 스크립트 호출은 스크립트 경로을 쓰면된다.
/home/export_test.sh

#환경 변수를 테스트하기 위해 export_test.sh 파일을 만들고 선언한 변수를 확인해본다.
echo ${hello_world}

예약 변수 (Reserved Variable)

  • HOME : 사용자의 홈 디렉토리
  • PATH : 실행 파일을 찾을 경로
  • LANG : 프로그램 사용 시 기본 지원되는 언어
  • PWD : 사용자의 현재 작업중인 디렉토리
  • FUNCNAME : 현재 함수 이름
  • SECONDS : 스크립트가 실행된 초 단위 시간
  • SHLVL : 쉘 레벨 (중첩된 깊이를 나타냄)
  • SHELL : 로그인해서 사용하는 쉘
  • PPID : 부모 프로세스의 PID
  • BASH : BASH 실행 파일 경로
  • BASH_ENV : 스크립트 실행 시 BASH 시작 파일을 읽을 위치 변수
  • BASH_VERSION : 설치된 BASH 버전
  • BASH_VERSINFO : BASH_VERSINFO[0] ~ BASH_VERSINFO[5] 배열로 상세 정보 제공
  • MAIL : 메일 보관 경로
  • MAILCHECK : 메일 확인 시간
  • OSTYPE : 운영체제 종류
  • TERM : 로긴 터미널 타입
  • HOSTNAME : 호스트 이름
  • HOSTTYPE : 시스템 하드웨어 종류
  • MACHTYPE : 머신 종류 (HOSTTYPE 과 같은 정보지만 조금 더 상세하게 표시됨)
  • LOGNAME : 로그인 이름
  • UID : 사용자 UID
  • EUID : su 명령에서 사용하는 사용자의 유효 아이디 값 (UIDEUID 값은 다를 수 있음)
  • USER : 사용자의 이름
  • GROUPS : 사용자 그룹(/etc/passwd 값을 출력)
  • HISTFILE : history 파일 경로
  • HISTFILESIZE : history 파일 크기
  • HISTSIZE : history 저장되는 개수
  • HISTCONTROL : 중복되는 명령에 대한 기록 유무
  • DISPLAY : X 디스플레이 이름
  • IFS : 입력 필드 구분자 (기본값: -빈칸)
  • VISUAL : VISUAL 편집기 이름
  • EDITOR : 기본 편집기 이름
  • COLUMNS : 현재 터미널이나 윈도우 터미널의 컬럼 수
  • LINES : 터미널의 라인 수
  • LS_COLORS : ls 명령의 색상 관련 옵션
  • PS1 : 기본 프롬프트 변수 (기본값:bash\$)
  • PS2 : 보조 프롬프트 변수 (기본값: >), 명령을 "\" 를 사용하여 명령행을 연장시 사용됨
  • PS3 : 쉘 스크립트에서 select 사용 시 프롬프트 변수 (기본값: \?)
  • PS4 : 쉘 스크립트 디버깅 모드의 프롬프트 변수 (기본값: + )
  • TMOUT : 0 이면 제한이 없으며 time 시간 지정 시 지정한 시간 이후 로그아웃

위치 매개 변수 (Positional Parameters)

  • $0 : 실행된 스크립트 이름
  • $1 : $1 $2 ... ${10} 인자 순서대로 번호가 부여된다. 10번째 부터는 "{}" 감싸야 함
  • $* : 전체 인자 값
  • $@ : 전체 인자 값 ($* 동일하지만 쌍따옴표로 변수를 감싸면 다른 결과가 나옴)
  • $# : 매개 변수의 총 개수

특수 매개 변수 (Special Parameters)

  • $$ : 현재 스크립트의 PID
  • $? : 최근에 실행된 명령어, 함수, 스크립트 자식의 종료 상태
  • $! : 최근에 실행한 백그라운드(비동기) 명령의 PID
  • $- : 현재 옵션 플래그
  • $_ : 지난 명령의 마지막 인자로 설정된 특수 변수




5. 매개 변수 확장 (Parameter Expansion)

예시 변수 : string = "abc-efg-123-abc"

  • ${변수} : ${변수} 와 동일하지만 {} 사용해야만 동작하는 것들이 있음 (예: echo ${string})
  • ${변수:위치} : 위치 다음부터 문자열 추출 (예: echo ${string:4} )
  • ${변수:위치:길이} : 위치 다음부터 지정한 길이 만큼의 문자열 추출 (예: echo ${string:-HELLO})
  • ${변수:-단어} : 변수 미선언 혹은 NULL 일때 기본값 지정, 위치 매개 변수는 사용 불가 ( 예: echo ${string:-HELLO} )
  • ${변수:=단어} : 변수 미선언 혹은 NULL 일때 기본값 지정, 위치 매개 변수 사용 가능 (예: ehco ${string:=HELLO} )
  • ${변수=단어} : 변수 미선언 시만 기본값 지정, 위치 매개 변수 사용 가능 (예: echo ${string=HELLO}
  • ${변수:?단어} : 변수 미선언 혹은 NULL 일때 단어 출력 후 스크립트 종료 (예: echo ${string:?HELLO}
  • ${변수?단어} : 변수 미선언 시만 단어 출력 후 스크립트 종료
  • ${변수:+단어} : 변수 선언시만 단어 사용




6. Command (추가 업데이트 예정)


위에서 살펴본 내용 외의 자주 사용하는 명령어를 정리해보자

unset (쉘환경변수 설정 해제)

리눅스 쉘 로컬변수환경변수 로 설정된 변수들의 설정을 해제할 수 있는 쉘내부명령어

즉, 로컬변수와 환경변수 및 설정된 함수들의 설정을 메모리에서 제거하는 명령어

unset [-fv] [변수명 ...]

-> 변수명의 사용이 끝나, 그 변수명을 제거하기 위해 사용되는 명령어 (쉘 상태에서도 사용되지만, 주로 쉘스크립트 내에서 사용)
-> 읽기전용 변수에 대해서는 unset 명령어로 제거 불가
-> unset 사용 시 -f 옵션을 사용하면, shell function 의 정의를 제거함



export

쉘 상태 또는 쉘스크립트 내에서 특정 변수명에 그 값을 할당하기 위해 사용하는 명령어
즉, export 로 할당된 변수들에 대해 unset 은 그 변수를 제거하여 사용하지 못하도록 함



uname (시스템에 대한 정보 출력)

  • 옵션 지정하지 않을 시 -s 옵션과 동일하게 출력 (커널 이름)

  • -a 옵션은 시스템의 전체 정보를 확인

$ uname -a

Linux ooo 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux


>> or >

https://twpower.github.io/114-difference-between-single-and-double-greater-than-sign




7. 배열 (Array Variable)


선언

# 출처 : https://blog.gaerae.com/2015/01/bash-hello-world.html

# 배열의 크기 지정없이 배열 변수로 선언
# 'declare -a' 명령으로 선언하지 않아도 배열 변수 사용 가능함
declare -a array


# 4개의 배열 값 지정 (배열 변수 사용은 반드시 괄호를 사용해야 한다.)
array=("hello" "test" "array" "world")

추가

# 기존 배열에 1개의 배열 값 추가(순차적으로 입력할 필요 없음)
array[4]="variable"


# 기존 배열 전체에 1개의 배열 값을 추가하여 배열 저장(배열 복사 시 사용)
array=(${array[@]} "string")

출력

# 위에서 지정한 배열 출력
echo "hello world 출력: ${array[0]} ${array[3]}"
echo "배열 전체 출력: ${array[@]}"
echo "배열 전체 개수 출력: ${#array[@]}"

printf "배열 출력: %s\n" ${array[@]}

삭제

# 배열 특정 요소만 지우기
unset array[4]
echo "배열 전체 출력: ${array[@]}"

# 배열 전체 지우기
unset array
echo "배열 전체 출력: ${array[@]}"




8. 변수 타입 지정(Variables Revisited)


Bash 변수는 타입을 구분하지 않고 기본적으로 문자열이다. (단, 문맥에 따라 연산 처리)

declare, typeset 으로 타입 지정 명령을 지원하지만, 불완전한 형태이므로 주석처리 된 문법을 사용하는 것이 좋다.

# 읽기 전용
# readonly string_variable="hello world"
declare -r string_variable

# 정수
# numver_variable=10
declare -i number_variable=10

# 배열
# array_variable=()
declare -a array_variable

# 환경 변수
# export export_variable="hello world"
declare -x export_variable="hello world"

# 현재 스크립트의 전체 함수 출력
declare -f

# 현재 스크립트에서 지정한 함수만 출력
declare -f 함수이름




9. 연산 (Computation)


논리 연산자 (Logical Operators)

문 자설 명
&& , -a논리 AND
| | , -o논리 OR



산술 연산자 (Arithmetic Operators)

산술 연산자는 python 과 동일

문 자설 명
+더하기
-빼기
*곱하기
/나누기
**누승(exponentiation), 거듭제곱(power)
%modulo 나 mod (정수 나누기에서 나머지 값)
+=상수값 만큼 증가 (plus-equal)
-=상수값 만큼 감소 (minus-equal)
*=상수값을 곱함 (times-equal)
/=상수값으로 나눔 (slash-equal)
%=상수값으로 나눈 나머지 값(mod-equal)



비트 연산자 (Bitwise Operators)

문 자설 명
<<비트 왼쪽 쉬프트 ( 쉬프트 한 번당 2를 곱하는 것과 동일 )
<<=left-shift-equal
>>비트 오른쪽 쉬프트 (쉬프트 한 번당 2로 나눔)
>>=right-shift-equal(<<=와 반대)
&비트 and
&=비트 and-equal
|비트 OR
`=`
~비트 negate
!비트 NOT
^비트 XOR
^=비트 XOR-equal



기타 연산자(Miscellaneous Operators)

문 자설 명
.콤마 연산자(comma operator), 2개 이상의 산술 연산을 묶어줌



정수 비교 (Integer Comparison)

문 자설 명
-eq같음
-ne같지 않음
>, -gt더 큼 (> 이중 소괄호에서 사용 가능)
>=, -ge더 크거나 같음 (>= 이중 소괄호에서 사용 가능)
<, -lt더 작음 (< 이중 소괄호에서 사용 가능)
<=, -le더 작거나 같음 (<= 이중 소괄호에서 사용 가능)



문자열 비교 (String Comparison)

문 자설 명
=, ==같음
!=같지 않음
<ASCII 알파벳 순서에 더 작음
>ASCII 알파벳 순서에 더 큼
-z문자열이 NULL, 길이가 0인 경우
-n문자열이 NULL 이 아님



파일 비교 (File test operators)

문 자설 명
-e파일이 존재
-f파일이 존재하고 일반 파일인 경우 (디렉토리 혹은 장치파일이 아닌 경우)
-s파일이 존재하고 0보다 큰 경우
-d파일이 존재하고 디렉토리인 경우
-b파일이 존재하고 블록장치 파일인 경우
-c파일이 존재하고 캐릭터 장치 파일인 경우
-p파일이 존재하고 FIFO 인 경우
-h파일이 존재하고 한 개 이상의 심볼릭 링크가 설정된 경우
-L파일이 존재하고 한 개 이상의 심볼릭 링크가 설정된 경우 (위와 동일)
-S파일이 소켓 디바이스인 경우
-t파일 디스크립터가 열려있고, 터미널 디바이스와 연관이 있음
-r파일이 존재하고 읽기가 가능한 경우
-w파일이 존재하고 쓰기가 가능한 경우
-x파일이 존재하고 실행 가능한 경우
-g파일이 존재하고 SetGID 가 설정된 경우
-u파일이 존재하고 SetUID 가 설정된 경우
-k파일이 존재하고 Sticky bit 가 설정된 경우
-O자신이 소유자임
-G그룹 아이디가 자신과 같음
-N마지막으로 읽힌 후에 변경 됐음
file1 -nt file2file1 파일이 file2 파일보다 최신임
file1 -ot file2file1 파일이 file2 파일보다 예전것임
file1 -ef file2file1 파일과 file2 파일이 같은 파일을 하드 링크하고 있음
!조건이 안 맞으면 참 (예: ! -e file )




10. 조건문 (if...elif...else...fi)


_FILE:="/home/Documents/temp.py"

if [ ! -f "$_FILE" ]; then
  echo "Missing Python script, ${_FILE}"
  return 22
fi
  • 조건은 [ ] 로 감싸준 후 ; 로 마무리

  • '[' 사이에 공백(스페이스바) 필수

  • then 뒤 실행 문장 없을 시 오류 발생

  • fi 작성 시 조건문 종료

  • 조건문 종류 참조

https://blog.gaerae.com/2015/01/bash-hello-world.html
https://www.linux.co.kr/bbs/board.php?bo_table=lecture&wr_id=2168&sst=wr_datetime&sod=desc&sop=and&page=24




11. 반복문 (for in, while, until ... do ... done)


  • 흐름제어 명령어
    break : 반복문을 빠져나갈 때
    continue : 현재 반복문이나 조건 건너뜀

# 지정된 범위 안에서 반복문 필요 시
for string in "hello" "world" "..."; do
  echo ${string}
done

# 수행 조건이 true 일때 실행 (실행 횟수 지정이 필요하지 않은 반복문 필요 시)
count=0
while [ ${count} -le 5 ]; do
  echo ${count}
  count=$(( ${count}+1 ))
done

# 수행 조건이 false 일때 실행됨 (실행 횟수 지정이 필요하지 않은 반복문 필요 시 좋음)
count2=10
until [ ${count2} -le 5 ]; do
  echo ${count2}
  count2=$(( ${count2}-1 ))
done

bash script, shell script 관계 없이

for in / while / until ... do ... done 형식으로 동일하다


Shell Script 반복문 참조

Bash 반복문 참조



profile
데이터 엔지니어 ing

0개의 댓글