리눅스와 유닉스를 사용중이라면 쉘 스크립트를 자주 사용하게 될것이다.
명령어들을 다양하게 조합하여, 명령어를 일일히 입력하지 않고 간편하게 실행이 가능하게 해준다.
빌드의 자동화 개발 환경 셋팅등 수많은 작업을 간편하게 도와주는 팔방 미인이다.
본래는 깃허브에 레포지토리로 만들었었으나, 블로그로 옮겼다.
이 포스트 또한 vi 단축키와 같이 주기적으로 업데이트 할 예정이다.


[Guide] 쉘 스크립트 가이드

[Introduction] 소개

이 글은 쉘 스크립트를 처음 공부하면서, 여기 저기 내용을 보고 정리하여 만든 문서입니다.
부정확한 내용이나 오탈자가 있을수 있으니 유의 하면서 읽으시기 바랍니다.
기초를 다루는 문서이니 만큼 어렵고 심화적인 내용은 다루지 않습니다.
심화적인 내용을 다루는 문서는 추후에 추가하도록 하겠습니다.

[Index] 목차

  • 1.쉘 스크립트에 관하여
    • 1.1. 쉘 스크립트란 무엇인가?
      • 1.1.1. 쉘이란?
      • 1.1.2. 쉘 스크립트란?
      • 1.1.3. 쉘 스크립트 사용하는 이유
        • 1.1.3.1. 장점
        • 1.1.3.2. 단점
  • 2.쉘 스르크립트 사용 법
    • 2.1. 쉘 스크립트 문법
      • 2.1.1. 쉘스크립트 파일에 대해서
      • 2.1.2. 주석
      • 2.1.3. 출력
      • 2.1.4. 입력
      • 2.1.5. 변수
      • 2.1.5.1 연산자
      • 2.1.6. 함수
      • 2.1.7. 배열
      • 2.1.8. 조건문
      • 2.1.9. 반복문
      • 2.1.10. 선택문

[Text] 본문

1. 쉘 스크립트에 관하여

1.1. 쉘 스크립트란 무엇인가?

1.1.1. 쉘이란?

쉘은 운영체제 커널(kernel)과 사용자간의 인터페이스 역할을 수행 합니다.
현재는 GUI(그래픽 사용자 인터페이스)가 널리 사용되고 있지만, 예전에는 CLI(커맨드라인 인터페이스)가 사용되었습니다.
CLI환경에서는 터미널에 명령어를 입력 하여 컴퓨터를 사용하였습니다.
GUI환경이 널리 발달헀지만 여전히 CLI환경은 여전히 많이 사용되고 있습니다.
쉘이란 사용자가 입력한 명령어를 해석하고, 운영체제에 전달하여 실행하는 역할을 하는 명령어 해석기입니다.

※ 커널: 운영체제의 일부로써 컴퓨터 메모리상에 항상 존재하는 프로그램이라고 할 수 있다.

1.1.2. 쉘 스크립트란?

스크립트 언어는 소스코드를 컴파일 하지 않고도 실행 할 수 있는 프로그래밍 언어를 지칭한다.
컴파일을 하지 않기 때문에 바로바로 실행 결과를 확인 할 수 있다.
쉘 스크립트란? 텍스트 형식으로 저장되는 프로그램으로써 한줄씩 순차적으로 읽어 실행되도록 작성된 프로그램이다.

1.1.3. 쉘 스크릡트를 사용하는 이유?

1.1.3.1. 장점

1. 반복적인 작업을 연산자와 옵션들로 편리하고 효율적으로 처리 할 수 있다.
2. 기존의 명령어의 결과를 원하는 형태로 표시할 수 있다.
3. 손쉽고 빠른 개발과 보완이 가능하다.

1.1.3.2. 단점

1. 하나의 명령어를 실행함에 따라 새로운 하부 프로세스를 필요로 하는 경우 속도가 느려질 수 있다.

2. 쉘 스크립트 사용법

2.1. 쉘 스크립트 문법

2.1.1. 쉘스크립트 파일에 대해서

쉘 스크립트 파일은 test.sh와 같이 .sh가 확장자이다.
test.sh 파일을 생성한후에 제일 첫번째 줄에 #!/bin/bash를 입력해준다.
다음과 같은 선언을 해주는 이유는 간단히 말해서 bash 쉘임을 미리 알려주는 것입니다.
#은 주석으로 알고 있는데 첫 라인의 #은 주석이 아닙니다.
#!은 스크립트의 제일 앞에서 이 파일이 어떤 명령어해석기의 명령어 집합인지를 시스템에게 알려주는 역할을 합니다.
#!는 2바이트의 매직 넘버로 She-bang 또는 Hash-bang 이라고 합니다.
여러가지로 부를 수 있으니 깔끔하게 ‘쉬뱅’으로 정하도록 하겠습니다.
쉬뱅은 #! 으로 시작하는 문자열이며, 스크립트의 맨 첫번째 라인에 있습니다.
이 스크립트를 실행시켜줄 프로그램의 경로를 지정하는 역할을 합니다.
예를 들면,

#!/bin/bash
#!/usr/bin/python

와 같이 다양한 인터프리터를 지정할 수 있습니다.
그후 두번째 줄에 echo “Hello world”를 입력해보자. 이젠 쉘 스크립트를 실행해보도록 하겠다.
실행하려면 ./test.sh 를 통해 실행하면 된다. 또는 sh test.sh로도 실행이 가능하다.
아마 처음에는 실행이 안될 것이다. 실행모드로 변경해줘야 한다. chmod 555 test.sh 명령어로 권한을 변경해준다.
다른 방식으로 권한을 변경해도 무관 하나 읽기 권한을 없애서는 안된다. shell 을 실행하기 위해서는 파일을 반드시 읽어야 하기 때문이다.

2.1.2. 주석

# 기호로 시작하면 주석이다.
사용하면 해당 줄을 주석처리 되어 실행되지 않는다. (한 줄 주석)
주석 처리하고 싶은 줄에는 모두 #를 사용해 주석처리를 해주어야 한다.
여러 줄을 주석처리 하고 싶을 때 에는 다음과 같이 사용한다.

:<<'COMMENT'   
    echo 여러줄   
    echo 주석    
    echo 입니다.   
COMMENT   

해당 블록안에 있는 문장은 주석처리 됩니다.

2.1.3. 출력

echo와 printf를 통해 출력을 할 수 있다.
echo는 자동으로 줄 바꿈을 해주지만 printf는 줄 바꿈을 해주지 않는다.
echo 사용시에 줄 바꿈을 하지 않으려면 -n 옵션을 사용하면 된다.
Printf의 경우 C언어의 printf와 비슷한 사용법을 가지고 있으며 다양한 포맷으로 출력이 가능하다.
추가 옵션과 상세한 사용방법은 후에 추가하기로 한다.

2.1.4. 입력

read를 사용한다.
예를 들면,

echo -n "단어를 입력하세요"
read str
echo "입력한 단어는: $str"

와 같이 사용한다.
두개 값을 입력 받을 때에는 read str1 str1와 같이 사용한다. 더 많은 값을 입력 받을 때에는
-a 옵션을 통해서 입력 값을 배열로 받을 수 있다.

read -a str  
echo "첫번째 인덱스: ${str[0]}, 두번째 인덱스: ${str[1]}, 세번째 인덱스: ${str[2]}" 

2.1.5. 변수

변수 사용시에 변수 값 대입을 위해 대입연산자인 = 를 사용해서 공백없이 입력해야 합니다.
변수명은 영문자, 숫자, ‘_’ (언더바)로 사용이 가능합니다. 그이외의 문자는 변수명으로 인식하지 못합니다.
에를 들어 $TEST-VAR 에서 “-VAR” 부터는 “-“으로 인해 변수명이 될수 없습니다.
변수의 사용은 다음과 같습니다.

str=123   
echo ${str} 또는 echo $str  

헷갈릴 수 있는 개념을 표로 정리 보았습니다.

변수 대상
${var} var이라는 이름의 변수
“$var” var이라는 이름의 변수
‘$var’ ‘$var’이라는 문자열
$var ‘$var’이라는 문자열
`$var` var라는 변수명의 명령의 실행
`var` var라는 명령의 실행

Bash 변수는 타입을 구분하지 않고 기본적으로 문자열이다.
또한 다른 프로그래밍 언어와 마찬가지로 지역변수와 전역 변수의 개념이 존재한다.
기본적으로 선언된 변수는 전역 변수이다. 함수 내에서 선언된 변수는 지역변수이다.
그러나 만일 동일한 이름의 전역변수가 존재한다면 전역 변수로 처리된다.
예를 들면,

str = "a"

function test()
{   
    str=”123”   
}   

와 같이 사용한다.
인경우에는 test함수 내에서 str이라는 변수가 생성되는 것이 아니라 전역변수 str에 123의 값을 대입한다.
즉, 전역변수에 덮어 씌워지는 것이다. 이를 방지하기 위해서는

str = "a"

function test()
{   
    local test="123"   
}   

과 같이 ‘local’ 키워드를 사용해야 한다.
Readonly 옵션은 상수로 만든다.
Unset은 변수 해제 이다.

2.1.5.1 연산자

할당(assignment)
문자 의미 표현
= 변수값 초기화 및 변경 num=123
산술 연산자(Arithmetic Operators)
연산자 의미 표현 비고
+ 더하기   *
- 빼기    
* 곱하기    
/ 나누기    
** 제곱   배시 쉘 2.02 버전 부터 사용가능
% 나머지    
+= 상수값 만큼 증가    
-= 상수값 만큼 감소    
*= 상수값을 곱함    
/= 상수값으로 나눔    
%= 상수값으로 나눈 나머지 값    
논리 연산자(Logical Operators)
연산자 의미 표현
-a 논리 AND if [ $one -eq 1 -a $zero -eq 0 ]
-o 논리 OR if [ $one -eq 1 -o $zero -eq 0 ]
&& 논리 AND if [ $one -eq 1 && $zero -eq 0 ] </br> if [[ $one -eq 1 ] && [ $zero -eq 0 ]]
|| 논리 OR if [ $one -eq 1 ] || [ $zero -eq 0 ] </br> if [[ $one -eq 1 ] || [ $zero -eq 0 ]]
비트 연산자(Bitwise Operators)
연산자 의미 표현
« 비트 왼쪽으로 쉬프트 (쉬프트 한번당 2를 곱하는것과 동일함)  
«= 왼쪽으로 쉬프트 후 할당  
» 비트를 오른쪽으로 쉬프트 (쉬프트 한번당 2를 나누는것과 동일함)  
»= 오른쪽으로 쉬프트 후 할당  
& 비트 and  
&= 비트 and 후 할당  
| 비트 or  
|= 비트 or 후 할당  
~ 2보수 ~1 은 -2
! 비트 NOT !100은 0
^ 비트 XOR 100^100 은 0
^= 비트 XOR 후 할당  
기타 연산자(miscellaneous operators)
연산자 의미 표현
, 2개 이상의 산술 연산자를 묶어줌  
정수 비교(Integer Comparison)
연산자 의미 표현
-eq 같음  
-ne 같지않음  
>, -gt 더 큼 단 > 를 [ ] 에서 사용시 \를 앞에 붙여줘야함, [[ ]]에선 \ 필요없음
>=, -ge 더 크거나 같음  
<, -lt 더 작음 단 < 를 [ ] 에서 사용시 \를 앞에 붙여줘야함 , [[ ]]에선 \ 필요없음
<=, -le 더 작거나 같음  
문자열 비교(String Comparison)
연산자 의미 표현
=, == 같음  
!= 같지않음  
< ASCII 알파벳 순서에서 더 작음  
> ASCII 알파벳 순서에서 더 큼  
-z 문자열이 NULL, 길이가 0인경우  
-n 문자열이 NULL이 아님  
${변수} 문자열이 NULL이 아님  

2.1.6. 함수

다른 프로그래밍 언어의 형태와 비슷하다.

function test() 
{
    ...
}

function 명령어를 사용하지 않아도 된다. 하지만 그런 경우에는 ()를 사용해주어야 한다.
호출은 (함수 이름)으로 호출할 수 있다.
인자를 사용할 때는 다음과 같이 사용할 수 있다.

function test()
{   
    echo $1   
    echo $2   
}   

다음과 같이 첫번째 인자는 $1로 사용할 수 있다. 만일 N번째 인자를 사용하려면 $N 으로 사용하면 된다.

2.1.7. 배열

배열은 다음과 같이 선언 할 수 있다.

Array=('first' 'second' 'third')    

배열 사이에 콤마를 넣지 않고 공백으로 구분한다.
인덱스로 값을 할당하는 방법은
Array[1]=”two”와 같이 사용할 수 있다.
배열 전체 가져오기 ${array[@]}로 사용한다.
배열의 길이는 ${#array[@]}이나 ${#array[*]}를 사용한다.
만일 [@]없이 ${#array}을 사용하면 배열인 array의 길이가 아닌 배열 array의 첫번째 인덱스의 길이를 가져오게 된다.

2.1.8. 조건문

※ 주의: 쉘 스크립트 에서 if문은 결과 값이 0일때 true, 아닐때 false 쉘 스크립트의 조건문의 경우 조건식이 문자로 되어있습니다.
C 언어의 경우 A와 B가 같지 않음을 if(A!=B){...} 와같이 표현합니다.
하지만 쉘 스크립트에서는 조건식을 ‘!=’와 같은 기호를 쓰지 않고 ‘-ne’와 같은 문자 형태로 사용합니다.
우선 기본적인 형태를 설명하고 난 뒤에 조건식에대해 알아 보겠습니다.
가장 기본적인 형태는 다음과 같습니다.

if [ 조건 ];
then
    조건이 참일때 수행할 명령어
else
    조건이 거짓일때 수행할 명령어
fi

대괄호 ‘[’ 와’]’의 양 옆에는 모두 한칸 띄어쓰기를 해줘야합니다.
then은 if 문 마다 써주어야 하지만, if의 반대인 fi는 마지막에 한번만 사용하면 됩니다.
elif 사용시에는 반드시 else 역시 사용해주어야 한다. else는 then이 필요없지만 elif는 then이 필요합니다.
조건문에서 사용되는 조건식은 여러가지가 있지만 많이 사용되는 것만 소개 하도록 하겠습니다.

조건식 기능
-eq 값이 같으면 참
-ne 값이 다르면 참
-gt A > B
-ge A >= B
-lt A < B
-le A <= B
-a && 와 동일 and 연산
-o || 와 동일 or 연산

추가로 test 명령어를 사용하는 방법도 있습니다.
if [ 조건 ]if test 로 사용할 수 있습니다.
test 명령어는 파일의 존재 유무 / 타입 / 권한 등을 체크할 때 사용합니다.
test는 명령어의 실행 기준이 아닌 결과를 기반으로 조건을 확인 하도록 하는 명령어 입니다.
if문만 사용했을 경우에는 true와 false의 기준은 명령어의 실행 입니다.

2.1.9. 반복문

for in 형태의 반복문

for 변수 in 값
do
    수행할 문장
done

for () 형태의 반복문

for ((초기값;조건식;증감식))
do
    수행할 문장
done

while 반복문
조건이 참일때 루프를 수행

while [ 조건 ]
do
    수행할 문장
done

until 반복문
조건이 거짓일때 루프를 수행

until [ 조건 ]
do
    수행할 문장
done

select 반복문
원하는 리스트를 출력하고 그 중 선택된 것을 돌려주는 구문
단, select 루프 내에서는 자동적으로 루프를 벗어날 수 없음

반복문 제어 명령

shift
break
continue

2.1.10. 선택문

case 선택문

case 문자열 in
    수행할 문장
esac