이번 게시글에서는 UNIX나 Linux에서 기본 쉘로 많이 사용되는 bash 쉘에서 스크립트를 작성하는 방법에 대해 다루어 볼 것이다. 물론 bash 쉘 환경을 준비해 놓았다는 가정 아래에서이다. 참고로 글쓴이는 Kali Linux 2018.4-amd64 환경에서 vim 편집기로 실습을 했다. 1
Hello, World!
1 2 | #!/bin/bash echo "Hello, World!" | cs |
파일 이름은 HelloWorld.sh로 저장하였다. 이때 유의해야 할 것은 방금 작성한 스크립트를 실행하려면 실행 권한을 부여해야 한다는 것이다. 아래와 같이 입력하여 실행할 수 있는 파일로 만들어주자. 2
1 | chmod u+x HelloWorld.sh | cs |
실행하려면 커맨드 라인에 ./HelloWorld.sh라고 입력하면 된다. 명령어 앞에 있는 ./ 부분은 파일 시스템에 있는 HelloWorld.sh라는 명령어나 스크립트가 아닌 현재 디렉터리에 있는 HelloWorld.sh 스크립트를 실행하기 원한다는 의미이다.
Hello World! 라고 출력되는 것을 확인했으면 다시 아까 작성했던 스크립트로 돌아가보자. 첫 번째 줄에 입력된 '#!/bin/bash' 는 '#!'와 '/bin/bash', 이렇게 두 부분으로 나눌 수 있다. '#!'는 셔뱅(shebang)이라고 하는 것으로, 운영체젱에게 어떤 인터프리터로 아래에 있는 스크립트를 인터프리트하고 싶다고 알려주는 것이다. '/bin/bash'는 사용하고 싶은 인터프리터이다. 다른 쉘 환경에서 인터프리트하고 싶다면 셔뱅 뒤에 오는 부분을 바꾸어 주면 된다. 파일 시스템 다른 곳에 bash가 설치되어 있을 가능성도 배제할 수는 없으므로, which나 bash 명령어로 bash의 위치를 미리 확인해두자. 두 번째 줄의 echo "Hello World!"는 단순히 Hello World!를 출력하는 명령문이다. 3
변수
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash function localmessage { local MESSAGE="Hi there! We're inside the function." echo $MESSAGE } MESSAGE="Hello, World! We're outside the function." echo $MESSAGE localmessage echo $MESSAGE | cs |
HelloWorld1.sh 에서는 함수와 변수라는 두 가지 개념에 대해 알아볼 수 있다. 2행부터 6행까지는 localmessage라는 함수가 구현되어 있다. 함수는 반복해서 사용할 수 있는 특정 코드 부분을 따로 분리하여 몇 번이고 재사용할 수 있게 해 준다. 또한 함수 내에 선언된 변수를 함수의 지역 변수로 정의하여 전체 스크립트에서 따로 분리시킬 수도 있다.
예시에 있는 함수 안에는 지역 변수 MESSAGE가 하나 있고, "Hi there! We're inside the function." 이라는 메시지가 저장되어 있다. 5행에서 echo 명령어로 출력하는데, 변수라는 것을 알려주기 위해 변수 이름 앞에 '$'을 붙인다. 함수를 호출하기 위해서는 9행에서처럼 그냥 간단히 함수의 이름을 적어주면 된다. 4
함수 밖에서도 MESSAGE 변수가 있는데, 7행의 MESSAGE는 4행의 MESSAGE와는 달리 전역 변수이다. 하나는 함수 안에서, 하나는 함수 밖에서 호출되는 것이다. 프로그램 실행 결과를 한 번 보자.
매개변수
1 2 3 | #!/bin/bash MESSAGE="Wake up, "$1"!" echo $MESSAGE | cs |
다음과 같은 내용이 저장된 스크립트 variables.sh를 실행할 때에는 조금 다르게 해야 한다. 위에서 했던 대로라면 ./variables.sh 와 같이 해야 하겠지만, 그렇게 하면 "Wake up, !" 이라고밖에 안 나온다. 매개변수를 주지 않았기 때문이다.
그러면 어떻게 해야 할까? 3행에서 MESSAGE 변수에 "Wake up, "이라는 문자열에 $1라는 값이 추가로 더 붙어있는 것을 볼 수 있다. 쉘에서 각각의 매개변수는 입력되는 순서대로 번호가 매겨진다. 따라서 $1은 첫 번째로 입력한 매개변수라는 뜻이다. 우리는 MESSAGE 라인에 $1을 입력함으로써 쉘이 "Wake up, ", "!" 텍스트 사이에 첫 번째 매개변수의 내용을 MESSAGE 변수에 저장하게 해야 한다. 5
※ 매개변수, 어디까지 쓸 수 있을까?
대부분의 UNIX 계열 시스템에서는 getconf ARG_MAX 명령어로 사용할 수 있는 매개변수의 한계를 확인할 수 있다. 작성자의 가상환경에서는 2097152KB만큼 입력받을 수 있었다.
매개변수 |
의미 |
$0 |
스크립트 이름 |
$1 |
첫 번째 매개변수 |
$2 |
두 번째 매개변수 |
$50 |
50번째 매개변수 |
$# |
가지고 있는 매개변수의 개수 |
이 다음에는 제어문에 대해서 알아볼 것이다. 제어문은 스크립트가 실행되는 동안 그 흐름을 제어할 수 있게 해 주는 구문들이다. 간단히 조건문과 반복문에 대해서만 살펴보자.
조건문
조건문은 입력값, 변수에 저장된 값, 또는 다른 요소에 따라 프로그램이 어떻게 작동할 지 선택해주는 역할을 한다. 조건문에도 여러 종류가 있지만, 역시 가장 흔히 사용되는 조건문은 if문이다. 아래의 if.sh 코드를 통해 if문을 사용하는 방법에 대해 알아보자.
1 2 3 4 5 6 7 | #!/bin/bash if [ "$1" = "Vallhalla" ]; then MESSAGE="Wake up, "$1"!" else MESSAGE="Hey, you're not Vallhalla." fi echo $MESSAGE | cs |
첫 번째 매개변수를 어떻게 입력하느냐에 따라 출력되는 결과가 달라진다. 따라서 두 가지 결곽밧을 모두 보려면 스크립트 실행을 두 번 해야 한다.
다시 코드로 돌아가 보자. 셔뱅 다음에 있는 if [ "$1" = "Vallhalla" ]; then 부분이 if.sh 스크립트의 핵심이다. 입력받은 첫 번째 매개변수의 값이 Vallhalla와 동일하다면 MESSAGE의 값을 "Wake up, "$1"!" 로 저장한다. 여기서 if문 첫 번째 행 앞에 있는 문자열과 $1의 값을 비교한다. 비교하여 나온 값이 거짓이면 4행으로 건너뛰어서 else 부분에 있는 코드를 실행한다. 이렇게 되면 MESSAGE는 "Hey, you're not Vallhalla." 가 된다. 마지막으로 fi는 if문이 끝났음을 표시하는 구문이다.
값들을 비교하는 방법에는 여러 가지가 있는데, 문자열의 경우에는 문자를 하나만 추가하여 앞에서 예시로 보였던 if.sh의 구조를 완전히 뒤바꿀 수 있다. if문 첫 번째 라인에서 '='를 '!='으로 바꾸면 의미가 '같은'이 아니라, '같지 않은'으로 바뀐다. 한편 아래 표에 있는 수학 기호들을 사용하여 if문을 작성할 수도 있다.
연산자 | 의미 |
-eq | ~과 같다 |
-ne | ~과 같지 않다 |
-gt | ~보다 크다 |
-lt | ~보다 같다 |
-le | ~보다 작거나 같다 |
표에 있는 값은 다음과 같이 응용할 수 있다. (comparenum.sh)
1 2 3 4 5 6 7 8 | #!/bin/bash NUM1 = $1 NUM2 = $2 if [ "$NUM1" -eq "$NUM2" ]; then echo "$NUM1 is equal to $NUM2." else echo "$NUM2 is not equal to $NUM2." fi | cs |
매개변수 두 개를 받아서 서로 같으면 if문을, 같지 않다면 else문 안 에 있는 명령어를 실행하는 스크립트이다.
반복문
1 2 3 4 5 | #!/bin/bash for files in /media/* do echo $files done | cs |
파일 실행 결과와 ls /media 명령어의 출력 결과를 둘 다 나타내어 보았다. formedia.sh를 실행하였을 때 /media의 파일 및 디렉터리를 보여주는 것이 ls 명령어와 비슷한 것을 알 수 있다. 2행의 for files in /media/*에서 for문이 시작되었는데, 여기서 각 파일을 저장할 변수(예제에서는 files)를 설정하였다. 이어 /media/*를 사용하여 특정 디렉터리의 특정 내용을 읽게 하였다. 예제에서는 /media에 있는 모든 파일과 디렉터리(*)를 지정한 것이다. do와 done 구문이 반복문의 시작과 끝을 표시하고, 그 사이에 앞에서 정의 한 files 변수를 출력하게 했다. 이 스크립트를 조금 변경하면 전 파일 시스템에서 어떠한 파일을 찾게 해서 그 파일을 복사하는 등 다양한 작업을 하게 할 수도 있다.
이번에는 while 문을 사용해 보자. while문은 조건이 참인 동안 계속해서 반복적으로 실행한다. 즉, 조건만 된다면 무한히 반복한다는 것이다. 그 예제인 while.sh 스크립트를 살펴보자.
1 2 3 4 5 6 7 | #!/bin/bash i=0 while [ $1 -lt 5 ] do echo "Strawberry Milk" i=$[$i+1] done | cs |
2행의 i=0에서는 반복문 안에서 사용할 변수를 설정하였다. 여기서 변수 i는 반복 횟수를 지정하는 일종의 카운터 역할을 한다. 3행에 대괄호 안에 있는 구문은 i의 값이 5보다 작으면 do ~ done 사이에 있는 구문을 계속해서 실행한다는 뜻이다. 6행에서는 i값을 1만큼 더 올려준다. while.sh를 실행한 결과는 아래와 같다.
'System > Shell Script' 카테고리의 다른 글
쉘 스크립트 개요 - 쉘, 스크립트, 그리고 쉘 스크립트란? (0) | 2019.03.20 |
---|