[Shell Script] 기본 문법

2018. 2. 22. 13:50Programming/Linux

반응형

시작하기에 앞서 쉘 스크립트를 만들고 나서 실행하려고 하면 권한이 없어서 실행을 못할 수도 있다. 따라서 먼저 권한을 바꿔주는 명령어에 대해 짚고 넘어가자.

- $chmod

권한을 바꿔주는 명령어로 쉘 스크립트를 실행하기 위해서는 실행 권한 뿐만 아니라 안에 내용을 읽을 수 있는 읽기 권한도 있어야 한다.

- chmod 사용자 권한 파일

권한 변경은 문자 말고 3자리 숫자로도 변경할 수 있으며 첫번째 숫자부터 각각 소유자, 소유 그룹, 제 3자를 나타낸다.

- chmod 각 권한을 더한 값(3자리) 파일


- 변수

x=12 와 같이 선언하며, 연산자 “=” 사이에는 공백 문자가 있으면 안된다는 것에 주의하자. 선언한 변수의 값은 변수 이름 앞에 $을 붙임으로써 사용할 수 있다.

변수가 선언될 때는 기본적으로 문자열로 선언되기 때문에 수학 연산을 하고 싶을 때에는 따로 명령어가 필요하다. 수학 연산을 위한 명령어는 뒤에서 다시 보기로 하자.



- 문자 출력

문자를 출력하는 명령어는 대표적으로 echo가 있는데 이 명령어 말고도 C언어에 쓰이는 printf로도 문자를 출력할 수 있다.

* 출력 방식

- echo $a   : a의 변수값 출력

- echo "$a" : a의 변수값 출력

- echo '$a'  : $a 출력 ('를 사용하면 쉘이 사용하는 특수문자(\, `, $ 등)를 일반적인 문자로 사용할 수 있다. : 쿼우팅 (Quoting))

- echo \$a : $a 출력 (\ 뒤의 문자를 문자 그대로 출력하게 한다. : 이스케이프)



출력 내용이 너무 많을 때 알아보기 쉽도록 아래와 같이 echo에서 출력내용의 색을 바꿀 수 있다.

    •  -e  : 백슬래쉬(\)가 들어가는 특수문자를 처리하겠다는 옵션
    • \033 [ : ANSI escape code(escape sequences)의 시작을 알리는 것으로 색상을 입히는 시작 표시이다.
    • 31 : SGR(Select Graphic Rendition) parameters, 실제 색상 적용 내용 (31~ 36이 자주 사용되는 색상이다.)
    • m : ANSI escape code(escape sequences)의 끝
    • 변경된 색상은 계속 남아있으모로 \033[0m 을 이용하여 기본값으로 복원한다.
    • 그 외에도 echo -e "\033[31;1m"COLOR_BOLD"\033[m"과 값이 ;을 사용하여 한번에 여러가지 옵션을 줄 수 있다. 지금 사용한 1은 문자를 굵게 출력하는 옵션이다.
    • 더 많은 옵션은 ANSI escape code의 SGR(Select Grapthic Renditio) parameter 표 참고



- 연산자

변수끼리 수학 연산을 하기 위해서 expr과 연산을 역작은따옴표(` 으로 ~표시에 있음)로 묶어주거나 let 명령어를 이용해서 연산할 수 있으며 연산자 사이의 공백에 주의해야 한다.

expr 명령어로 연산을 할 때, 더하기(+), 빼기(-), 나누기(/)는 그대로 써도 되지만 곱하기'*'와 괄호'()'를 쓸 때에는 앞에 \를 붙여줘야한다.







- 입력받기

read 명령어를 이용하여 사용자의 키보드 입력을 변수에 넣을 수 있다. 이때 echo 뒤의 -n은 개행없이 문장 뒤에 바로 이어쓸 수 있게 한다.

  • read : 변수를 정해주지 않으면 자동으로 REPLY 변수에 저장된다.
  • read a : 변수 a에 입력받은 값을 저장한다.
  • read a b : 첫번째 단어는 변수 a에, 두번째 단어는 변수 b에 저장한다.
  • read -a array : array라는 배열에 값을 저장한다.
  • read -p "출력문" a : 출력문을 띄운 후에 입력을 기다린다. 입력된 값은 변수 a에 저장된다.
  • read -r a : 역슬래쉬(\)도 입력값에 포함하여 변수 a에 저장한다.
  • read -e : 입력줄에서 명령어 편집기를 사용할 수 있다.

- 조건문 (if elif else fi)

조건에 해당하는 명령문을 실행시키는 조건문으로 If 뒤에 공백과 [] 사이의 공백에 주의해야 한다.

이때 세미클론(;)은 줄바꿈줄로 세미클론 대신 한줄을 띄고 then을 써도 된다.

* 크기 비교

x -eq y     x가 y와 같은 지 

x -ne y     x가 y와 같지 않은 지 

x -gt y     x가 y 보다 큰지 

x -lt y      x가 y 보다 작은 지 

x -ge y    x가 y 보다 크거나 같은 지

x -le y     x가 y 보다 작거나 같다.



* 문자 비교

"X" = (or ==) "Y"    두 문자열이 같은 경우

"X" ! "Y"                두 문자열이 다른 경우

-z "X"                   문자열의 길이가 0인 경우

-n "X'                   문자열의 길이가 0이 아닌 경우

* 파일 비교

-e "file"        해당 파일이 존재하는 지

-d "file"        해당 파일이 디렉토리인 지

-f "file"         해당 파일이 정규 파일인 지

-r "file"         해당 파일에 읽기 권한이 있는 지

-w "file"        해당 파일에 쓰기 권한이 있는 지

-x "file"         해당 파일에 실행 권한이 있는 지

-O "file"        해당 파일의 소유자가 현재 쉘을 실행한 사용자인 지


* 관계 연산자

-a (or &&) : and  연산자

-o (or ||) : or 연산자


※ 모든 비교조건 앞에 !(not)을 붙여서 반대 의미를 가지게 할 수 있다.

ex) [ ! -e "file" ] : 해당 파일이 존재하지 않으면 참


- &&나 ||로 표현하기

* 조건문 && 실행문 : 왼쪽이 이면 오른쪽을 실행하라는 문장


* 조건문 || 실행문 : 왼쪽이 거짓이면 오른쪽을 실행하라는 문장으로 예시에서는 거짓이면 exit 명령어로 프로그램을 종료하고 참이면 그 밑의 문장을 실행하도록 했다.


- for 문

for 문은 in 뒤에 있는 값들을 순서대로 in 앞에 있는 변수에 대입해서 do와 done 사이에 있는 명령문을 실행한다. 순서대로 하나씩 변수에 대입하므로 in 뒤에 있는 값의 갯수만큼 명령문이 실행된다.

for 변수 in 값1, 값2, 값3...

do

실행하고자 하는 명령문

done

이때 sleep 5는 프로그램이 약 5초정도 쉬었다가 실행되도록 하는 명령어다.


+) C언어와 같이 for 문을 구현할 수 있다.

for (( i=0; i<=10; i++ ))

do

실행문

done



- while 문

while 문은 조건문이 참인 동안 do와 done 사이의 명령문이 실행된다.

while [ 조건문 ]

do

실행하고자 하는 명령문

done

true 말고도 '1'과 ':'도 참을 나타낸다.


- case 문 (switch-case 문)

변수 값에 따른 문장을 실행하는 case 문으로 C언어와 다르게 "|"을 사용하여 여러 조건을 판단할 수 있다. 이때 조건은 왼쪽에서 오른쪽 순서대로 판단되면 왼쪽 조건은 거짓이면 그 오른쪽 조건은 검사하지 않는다.

case 변수 in

조건1)

문장

;;

조건2|조건3) 

문장

;;

조건4|조건5|조건 6...)

문장

;;

*)

문장

;;

esac

* 조건을 이용하여 모든 조건에 해당되는 않을 때 실행되는 default문을 구현한다.



- select 문

선택지 중에 하나를 입력받는 select 문으로 break나 exit로 빠져나가기 전까지 계속 반복한다. 사용자가 입력한 선택지는 in 앞에 있는 변수에 저장된다.

select 변수 in "선택지1" "선택지2" "선택지3" ...

do

실행문

done


- until 문

until 문은 while 문과 반대로 조건에 있는 식이 거짓이면 실행되고 참이 되면 종료된다. 

until [ 조건 ]

do

실행하고자 하는 명령문

done


※ 위의 for, while, until 문과 같은 반복문에서 break로 빠져나오거나 continue로 그 밑의 명령어를 실행안하고 다시 반복하는 명령어를 사용할 수 있다.



- 함수 (function)

함수를 쓰기 전에 미리 선언돼있어야 한다. 함수가 리턴된 다음에 $?라고 하면 함수의 마지막 명령어의 종료 상태를 알려주므로 함수의 "반환값"을 알 수 있다. 함수의 인자는 순서대로 $1, $2, $3, ... 으로 저장되서 사용할 수 있으며 $9 이후부터는 ${10}처럼 중괄호로 묶어줘야 한다. 

모든 변수는 기본적으로 전역 변수이므로 함수에서 선언한 변수도 전역 변수이다. 만약 함수 내에서만 변수를 사용하고 싶다면 변수 앞에 local을 붙여서 지역 변수를 선언하면 된다.

function 함수명(){

실행문

}



- shift

$1 <- $2, $2 <- $3, $3 <- $4, ... 와 같이 매개 변수를 왼쪽으로 옮기는 명령어이다.

until [ -z "$1"]  #$1에 값이 없을 때까지 -> 모든 매개변수를 다 출력할 때까지 반복문 진행

do

echo -n "$1"

shift

done


echo    #출력 후에 개행

* 이때 $#으로 입력받은 값의 갯수를 알 수 있다.



- 출력 재지정

어떤 명령어를 입력했을 때 결과가 화면에 출력되는 것이 아닌 파일 같은 곳에 저장하고 싶다면 ">" 연산자를 사용하면 된다.

위와 같이 Hello World라는 문구가 화면에 출력되지 않고 file안에 저장됐고 문장이 뒤를 이어서 저장되지 않고 덮어 쓰여지는 것을 볼 수 있다. 

만약 이처럼 덮어쓰지 않고 뒤에 붙여서 쓰고 싶다면 ">>" 연산자를 사용하면 된다. ">>" 연산자는 기존에 같은 파일이 있으면 마지막 부분에 이어서 쓰게 되고 파일이 없다면 새로운 파일을 만든다.


- 파이프

파이프는 한 명령어의 출력값을 다른 명령어의 입력값으로 넣어주는 연산자(Shift + \ -> |)이다.

아래의 예시는 /etc/passwd의 파일 전체를 읽어서 "sol"이라는 문자열을 찾는 grep의 입력값으로 넣어준 뒤 출력값을 foo.file에 저장하는 쉘 프로그램이다.


* 출력 재지정과 파이프에서 나온 cat은 파일의 내용을 보기위한 명령어이다.

    • 파일 내용 출력 : cat /etc/passwd
    • 새로운 파일 생성 : cat > test.txt 을 한 뒤에 입력할 내용을 치고 Ctrl + D를 누르면 저장된다.
    • 파일에 내용 추가 : cat >> test.txt

- 리턴

프로그램이 어떻게 종료됐냐에 따라서 특정한 값을 리턴한다. 파이프 예제에 있는 if과 같이 grep 명령어의 경우에 문자열을 발견하면 0을 리턴하고 발견하지 못하면 1을 리턴한다. 이 리턴된 값을 쓰고 싶을 때 $?을 사용해 리턴 값을 얻을 수 있다.


쉘 스크립트가 종료될 때 특정한 값을 리턴하고 싶다면 exit 명령어를 사용하면 된다.



함수에서의 값을 리턴하는 기본적인 방법으로 echo 명령어를 사용한다. 

echo 명령어 말고도 전역변수를 사용하거나 위의 함수 예제에서 사용한 것처럼 return 명령어를 사용한다.

- 디버깅 

- 디버깅 모드 : sh -x 쉘 스크립트 이름

쉘이 실행되는 동안 사용된 변수의 모든 값을 출력한다.


- syntax 오류 : sh -n 쉘 스크립트 이름

syntax 오류만 화면에 출력한다.



출처 : http://gasaesososo.tistory.com/15

반응형