Shell Programming 문법
Category: System Programming
Tags: shell
What is Shell, Shell Script
- Shell : kernel 과 user 사이의 인터페이스
-
Shell Script : shell command들의 집합, collection
-> task 자동화, 사용하기 쉬움, portable, transparency
Running Shell Script
Hashbang #! : 맨 위쪽 상단에 어떤 쉘을 사용할 것인지 정의
-> bash shell 사용 : #!/bin/bash
, sh shell 사용 : #!/bin/sh
Shell Script 실행 방법
- 권한 부여하고 실행 :
chmod a+x scriptname
후./scriptname
- 새로운 shell에서 실행 :
bash scriptname
-
현재 shell에서 실행 :
source scriptname
,. scriptname
-> shell에서 정의한 변수 값들이 그대로 남아있게 된다
ex. bash, source, ./ 명령어의 차이점
-
간단한 Shell Script 실행 : Hello World! 출력하기
#!/bin/bash echo "Hello World!" # echo : 입력 문자열을 터미널에 출력하는 명령어
Shell Variables
-
Environment variable : 모든 shell에 값을 유지, export 명령어로 생성
-> 주로 프로그램에 대한 정보를 제공할 때 사용, 프로그램 실행시 환경 변수 설정
->
env
,printenv
명령어로 현재 저장된 환경변수 목록 확인 - Shell variable : 해당 shell 안에서만 값을 유지
- Global variable : shell script 내에 모든 줄에서 값을 유지
- Local variable : shell script 내에 선언된 함수 안에서만 값을 유지
-
Set variable 변수 지정하기
# set environment(global) variable export global_var=2 global_var=2; export global_var # set shell(local) variable shell_var=3 local shell_local_var=4 # print variables in terminal echo "global_var : $global_var" # global_var : 2 echo "local_var : $local_var" # local_var : 3 echo "shell_local_var : $shell_local_var" # local_var : 4
- Unset variable 변수 삭제하기 :
unset variablename
- Variable naming : letter나 _로 시작, 대소문자 구분, 숫자 사용 가능(맨 앞 제외), special character 사용 불가
-
$PATH
: 명령어를 실행할 때, shell은 PATH에 등록된 경로에 있는 디렉토리에 해당 프로그램이 있는지 검색-> 자주 실행하는 프로그램을 저장해놓는 편이 좋음, ex.
PATH=$PATH:/home/binnie/myfolder
Arrays
Bash 쉘은 배열 자료구조를 지원하고 있다.
Array 사용 방법
# Create list
A=(abc 1 123 xyz) # ,가 아닌 띄어쓰기로 구분
# Set element
A[3]=zyx
# View element of array
echo $A # just first element
echo ${A[3]} # third index element
echo ${A[@]} # all elements
echo ${#A[@]} # number of elements
# Get input in array
echo -n "Insert number: " # -n : no newline!
read -a arr
Quotation
- Single Qutataton
‘‘
: literally 문자열을 출력 → ‘$myvar’ - Double quotation
“”
: semantically 문자열을 출력 → “hello” -
Back Quotation ```` : command substitution,
$( )
와 같은 기능->
type -a
,command -V
: 사용할 수 있는 built-in commands 확인ex. 각 quotation별 결과 확인
Boolean, Arithmetic Operations
-
Boolean 연산 : 0 (True), 1 (False)
-> other language : 1 (True), 0 (False) 헷갈리지 말기 !
-
Arithmetic 연산
-> integer expansion :
$[ ]
,$(( ))
,$(expr)
,expr
# 수학 연산할 때 사용 가능한 syntax들 정리
$((num3=num1+num2)) # 3 (앞에 $ 생략 가능)
$((num4=$num1+$num2)) # 3 (앞에 $ 생략 가능)
num5=$((num1+num2)) # 3
num6=$(($num1+$num2)) # 3
num7=$[num1 + num2] # 3
num8=$[$num1 + $num2] # 3
$[num9=num1+num2] # 3
$[num10=$num1+$num2] # 3
let num11=$num1+$num2 # 3
num12=`expr $num1 + $num2` # 3 (띄어쓰기 중요)
num13=$(expr $num1 + $num2) # 3 (띄어쓰기 중요)
Redirection and Here document
-
Redirection > : standard input이나 standard output을 바꿔준다
sort array.txt > array2.txt
: 출력 스트림을 파일로 설정 -
Here document < < : tag가 들어올 때까지 넣은 입력이 입력 스트림에 들어간다
cat << EOF > multi-line text > can now be inserted here. > EOF # 여기까지 입력으로 같이 들어가게 됨 # multi-line text # can now be inserted here.
- EOF : End of File의 약자로 파일 종료 코드를 의미, 리눅스에서는 ctrl+D
—
- EOF : End of File의 약자로 파일 종료 코드를 의미, 리눅스에서는 ctrl+D
Flow Control : if condition
-
if - elif - else 조건문 사용하기
if [ condition ] # [ ] 안에 띄어쓰기 중요 # if [ condition ]; then도 가능 then command-list elif [ condition2 ] # [[ ]]도 사용 가능 then command-list else command-list fi
Operations for Conditions
-
test Expression : 리턴 값이 true인지 false인지 판별
=
[ Expression ]
=[[ Expression ]]
같은 의미지만, [[ ]] 가 더 범용적 -
Special arguments
| $# | argument 갯수 | | | — | — | — | | $0 | 현재 shell script 이름 | | | $1 ,$2 | positional parameters 직접 입력 받는 parameter들 | C의 argv[0], argv[1]와 유사 | | $* | 모든 parameters 전부 | 하나의 문자열로 출력 | | $@ | 모든 parameters 전부 | 각각 문자열로 출력 | | $? | 최근에 실행한 명령어 값 | | | $$ | 현재 프로세스 pid | |
- Logical Operations : ! not, [[ && and, || or ]], -a and, -o or
-
Relational Operations
Meaning Numeric String greater than (str1) -gt str1 > str2 greater than + equal -ge less than (str1) -lt str1 < str2 less than + equal -le equal -eq = or == not equal -ne != strlen > 0 -n str strlen = 0 -z str ex. 입력 받은 2개의 argument를 출력하는 shell script
- File testing : 입력 받은 파일의 종류 확인 (True 또는 False 반환)
- -e file : 파일이 존재하는지
- -r -w -x file : 파일 읽기, 쓰기, 실행 가능한지
- -l file : 파일이 존재하고 symbolic link인지
- -o file : user가 파일을 own하고 있는지
- -f -d file : 파일이 regular file, directory file인지
- -s -z file : 파일의 크기가 0보다 큰지, 0인지
Flow Control : For, While, Until loop
-
for 반복문 사용하기
for [ condition ] # for [ condition ]; do 도 가능 do command-list done
ex. for 문으로 array와 list의 element를 하나씩 불러와서 출력 -
while 반복문 사용하기
while [ condition ] # while [ condition ]; do도 가능 do command-list done
ex. 입력받은 파일을 while read line로 한 줄씩 불러와서 출력
-
until 반복문 사용하기
until [ condition ] # until [ condition ]; do도 가능 do command-list done
Operations for loop
-
shift n
: n만큼 뒤로 이동시키는 명령어, default n은 1로 설정됨-> 작동 방식 : $2 → $1, 기존의 $1 argument는 삭제
ex. 4, 5, 6을 입력하고 shift 1을 실행시킨 결과
-
break문 : iteration을 멈추고 나가는 구문
- continue문 : 다음 iteration으로 이동하는 구문
break문 : 조건문 완전히 탈출
Flow Control : case, select
-
case 조건문 사용하기
str과 일치하는 블럭이 있을 때, 해당 command list를 수행한다
case str in pattern_1) commandlist1 ;; pattern_2) commandlist2 ;; pattern_3|pattern_4|pattern_5) # 다수의 조건을 하나의 패턴에 적용 commandlist3 ;; *) command-list4 # default, 조건에 일치하지 않는 항목 ;; esac
ex. case문 : 사용자로부터 입력 받은 이름이 올바른지 확인하는 예제
-
select 조건문 사용하기
wordlist 하나를 선택할 수 있는 옵션을 주고, 선택한 것을 적용한 command 수행
-> 조건문을 나갈 때까지 loop가 반복된다 (^C or ^D)
PS3="input message: " #select 명령어에서 제공하는 프롬프트 메시지 select word in wordlist do commands done
ex. select 문 : 사용자가 선택한 파일을 private 파일로 권한 변경
Shell Function
shell script 내에서 함수 선언하기
-> 참조되기 전에 선언되어야 함, 주로 shell script 시작 부분에 위치
function function_name { # function keyword 사용하는 경우
statements
}
function_name () { # keyword 대신 bracket 사용하는 경우
statements
}
- 함수 실행하기 :
function_name arg1 arg2
-
함수 삭제하기 :
unset -f function_name
ex. 함수에 multiple argument를 입력해서 실행하는 예제
- 함수 return 값 반환하기 :
**return** [n]
(n : 0-255)- 정수 외에 다른 값 리턴 : standard output(echo) 또는 global variable 사용
- 리턴 값을 받아오기 :
**$?**
또는var=$(function)
사용
ex. 함수에서 $? 를 사용해서 multiple return을 받아올 때
-
Recursion 재귀 함수 : 자기 자신을 호출하는 경우 (no limit)
최대한 재귀 함수를 사용하지 않는 편이 좋음
→ 속도가 매우 느리고, call stack을 많이 잡아먹음 → stack overflow도 발생 가능
ex. recursion 종료 조건의 필요성
Handling Signals : Trap
UNIX에서 특정 signal을 통해 프로세스를 멈추게 하는 것이 가능하다
kill -signal pid
: 프로세스에 특정 signal을 보내기
- -1 : hangup
- -2 : interrupt with ^C
- -9 : kill
- no argument : terminate
Trap 설정하기 : trap ‘handler commands’ signals
1, 2 등의 signal을 받아도 terminate 하지 않고 특정 명령어를 대신 수행
Trap 리셋하기 : trap signals
수행할 command 지정하지 않으면 원래의 default handler로 돌아감
ex. trap을 설정하고 signal을 부여했을 때 나타나는 결과
-> 다른 터미널에서 signal을 발생시킨 결과 : terminate 하지 않음
Debugging Shell Script
shell script를 디버깅하는데 사용되는 명령어
echo
를 사용한 debugging : printf 와 유사하게 값을 직접 출력해보면서 확인set
을 사용한 debugging- -v : read line할 때마다 값을 출력
- +x : command랑 argument 출력
- -x : statement 출력하는 것 중단
- -n : syntax error 찾아줌
ex :
set -xv
또는#!/bin/bash -xv # -> shell script 전체를 디버깅 모드로 설정
@Advanced Programming in the UNIX environment, Third edition 내용을 참고함