셸 스크립트 프로그래밍 실습

Seong Woong Kim·2023년 3월 7일
0

Linux / Ubuntu

목록 보기
13/14

💡 이 문서는 한빛미디어 - 이것이 우분투/리눅스다를 기반으로 공부하면서 체화를 위해 정리하는 글입니다. 💡


  • 리눅스의 셸 스크립트는 C 언어와 유사한 방법으로 프로그래밍 가능

    • 리눅스의 대부분을 C 언어로 작성했기 때문
  • 셸 스크립트도 일반적인 프로그래밍 언어와 비슷하게 변수, 반복문, 제어문 등을 사용할 수 있다.

  • 별도로 컴파일하지 않고 텍스트 파일 형태로 셸에서 바로 실행 가능

    • 그래서 셸 스크립트는 주로 vi 에디터나 gedit으로 작성하는 편



1. 셸 스크립트 작성과 실행


💡 환경 변수란 ?? 💡

  • 셸 스크립트 파일의 확장명을 지정하지 않거나 다른 것으로 지정해도 되지만, 사용자가 작성한 셸 스크립트 파일은 되도록 확장명을 sh로 지정



name.sh

/bin/sh

특별한 형태의 주석 (#!)으로 bash를 사용하겠다는 의미

첫 행에 꼭 써줘야 함


echo "사용자 이름 : " $USER

echo 명령은 화면에 출력하는 명령어

먼저 “사용자 이름 :" 이라는 글자를 출력하고, 옆에는 $USER라는 환경 변수의 내용을 출력


exit 0

종료 코드를 반환하게 해줌

  • 만약 다른 스크립트에서 이 스크립트를 호출한 후 제대로 실행되었는지 확인하려면 적절한 종료 코드를 반환하는 것이 중요

즉, 이 행은 실제 스크립트 실행과 무관하지만, 셸 스크립트는 실행 중간에 문제가 생겨도 무조건 성공했다는 메세지를 반환하기 때문에 마지막 행에서 직접 성공인지 실패인지를 반환하는 것이 좋다

  • 0은 성공을 의미



sh 명령으로 실행

sh 스크립트파일 명령으로 실행 가능

  • 셸 스크립트 파일의 속성을 변경할 필요가 없다는 장점



'실행 가능' 속성으로 변경 후 실행

셸 스크립트 파일의 속성을 ‘실행 가능’으로 변경한 후, ./스크립트파일 명령을 실행

💡 ./스크립트파일 명령에서 '.'은 현재 디렉터리를 의미 💡

그러므로 현재 디렉터리의 스크립트 파일을 실행하라는 의미
현재 디렉터리인 ‘./’를 입력하는 이유는 현재 디렉터리가 $PATH 환경 변수에 설정되어 있지 않기 때문

일반적으로 명령이나 스크립트 이름을 입력하면 $PATH 환경 변수에 설정된 디렉터리만 찾아봄

작성한 셸을 모두 사용할 수 있게 설정하려면 /usr/local/bin 디렉터리에 복사하고 권한을 755로 변경

  • 셸 스크립트 파일의 확장명을 지정하지 않거나 다른 것으로 지정해도 되지만, 사용자가 작성한 셸 스크립트 파일은 되도록 확장명을 sh로 지정




2.변수


변수는 필요한 값을 계속 변경해 저장한다는 개념

  • 셸 스크립트의 구조는 변경할 필요가 없는데 설정해야 하는 값이 상황에 따라 다르다면 변수에 필요한 값을 계속 바꿔가는 방법으로 프로그래밍해서 다양한 상황에 대처할 수 있다.



변수의 기본

셸 스크립트에서는 변수를 사용하기 전에 미리 선언하지 않으며, 처음 변수에 값이 할당되면 자동으로 변수가 생성된다.

  • 변수에 넣는 모든 값은 문자열(string)으로 취급한다. 즉 숫자를 넣어도 문자로 취급

  • 변수 이름은 대소문자를 구분한다. 즉 $aa와 $AA는 다르다.

  • 변수를 대입할 때 '=' 좌우에는 공백이 없어야 한다.

testval = Hello     # 오류 --> '=' 앞뒤에 공백이 있다.
testval=Hello
testval=Yes Sir     # 오류 --> 값의 공백은 ""로 묶어야 한다.
testval="Yes Sir"
testval=7+5         # 정상이지만 "7+5"라는 문자열로 인식



변수의 입력과 출력

‘$'라는 문자가 들어간 글자를 출력하려면 ‘’로 묶거나 앞에 '\’를 붙여야 한다.

““로 변수를 묶어도 되고, 묶지 않아도 된다.

셸의 구조

3행 - echo $myvar

  • ‘Hi Woo’라는 정상적인 값을 출력한다.

4행 - echo "$myvar"

  • 3행과 동일한 효과

5행 - echo '$myvar'

  • $myvar라는 글자를 출력

6행 - echo \$myvar

  • \$$를 글자로 취급하게 한다. 결국 5행과 동일한 효과

8행 - read myvar

  • 변수 myvar에 키보드로 값 (문자열)을 입력



숫자 계산

변수에 넣은 값은 모두 문자열로 취급함

변수에 들어 있는 값에 +. -, *, / 등의 연산을 하려면 expr 키워드를 사용

  • 단, 수식과 함께 꼭 키보드 숫자 1왼쪽에 있는 역따옴표 ()로 묶어줘야 한다.

  • 수식에 괄호를 사용하려면 그 앞에 꼭 역슬래시(\)를 붙여야 한다.

  • +, -,/와 달리 곱하기(*) 기호는 예외적으로 앞에 역슬래시(\)를 붙여야 한다.

3행 - num2=$num1+200

  • 문자열로 취급한다 → 모두 붙여서 써야 한다.

5행 - num3=expr $num1 + 200

  • 숫자로 취급해서 계산한다. → 각 단어마다 띄어쓰기를 해야 한다.

7행 - num4=expr \( $num1 + 200 \) / 10 \* 2

  • 괄호와 '*' 앞에는 역슬래시()를 붙인다.



파라미터 변수

파라미터 변수는 $0, $1, $2 등의 형태를 갖는다.

  • 명령어에 포함된 모든 단어를 $변수 형식으로 지정한다.

예를 들어 apt -y install gftp 명령을 실행한다고 가정하면, 파라미터 변수는 다음과 같다

  • 명령 전체의 파라미터 변수는 $*로 표현



3. if문과 case문


기본 if문

기본 문법은 다음과 같다

주의할 점은 ‘[ 조건 ]’ 사이의 각 단어에는 모두 공백이 있어야 함

if [ 조건 ]
then
  참일 경우 실행
fi

if [ "woo" = "woo" ]

  • ‘[ ]’ 사이에는 참과 거짓을 구분하는 조건식이 들어간다.

    • ‘='은 문자열이 같은지 비교하며, '!=’은 문자열이 같지 않은지 비교한다.

    • if1.sh에서는 조건식이 참이므로 이 행을 실행한다.

  • ‘[ ]’ 대신 test라는 키워드를 사용할 수 있다.

    • if test “woo” = “woo”



if~else문

참인 경우와 거짓인 경우를 구분해서 실행한다.

💡 중복 if문을 위해서 else if가 합쳐진 elif 구문도 사용할 수 있다. 💡

if [ 조건 ]
then
  참인 경우 실행
else 
  거짓인 경우 실행
fi



조건문에 들어가는 비교 연산자

조건문에 들어가는 비교 연산자에는 문자열 비교 연산자와 산술 연산자가 있다



문자열 비교 연산자



산술 비교 연산자



파일과 관련된 조건

if문에서 파일을 처리하는 조건은 다음과 같다.

2행 - fname=/lib/systemd/system/cron.service

  • fname 변수에 cron 서버 실행 파일인 /lib/systemd/system/cron.service를 저장

3행 - if [ -f $fname ]

  • fname 변수에 저장된 /lib/systemd/system/cron.service 파일이 일반 파일이면 참이므로 5행을 실행하고, 그렇지 않으면 거짓이므로 7행 - echo "cron 서버가 설치되지 않았습니다."을 실행한다.

5행 - head - 5 $fname

  • fname에 들어 있는 파일의 앞에 5줄을 출력한다.



case~esac문

if문은 참과 거짓이라는 두 가지 경우만 사용할 수 있다. (이를 ‘2중 분기’라고 한다.)

여러 가지 경우의 수가 있다면 if문을 계속 중복해서 사용해야 하므로 구문이 복잡해짐

  • 이 때 사용하는 것이 case문이다. 이를 다중 분기라고 한다.

2행 - case "$1" in

  • 첫 번째 파라미터 변수 (명령 실행 시 추가한 값)인 $1 값에 따라 3행, 5행, 7행, 9행으로 분기한다.

  • start), stop), restart) 이외의 값은 모두 9행 *) 부분으로 분기한다.

4행 - echo "시작~~";;

  • 3행에서 start ) 일 경우 실행된다.

  • 주의할 점은 맨 뒤에 세미콜론을 2개(;;) 붙여서 써야 한다는 것이다.

9행 - *)

  • 그 외의 것들이 모두 해당된다.

11행 - esac

  • case문 종료를 표시한다.

3행 - read answer

  • answer 변수에 입력한 값을 받는다.

5행 - yes | y | Y | Yes | YES)

  • 입력된 값이 yes, y, Y, Yes, YES 중 하나면 6~7행을 실행한다.

6행 - echo "다행입니다"

  • 실행할 구문이 더 있으므로 끝에 ;;을 붙이지 않는다는 점에 주의한다.

7행 - echo "더욱 열심히 하세요 ^^"

  • 실행할 구문이 없으므로 뒤에 ;;을 붙인다.

8행 - [nN]*)

  • [nN]*)는 앞에 n 또는 N이 들어가는 단어를 모두 인정해준다는 의미다.

12행 - exit 1;;

  • 정상적인 종료가 아니므로 exit 1로 종료한다 (꼭 해야 하는 사항은 아님)



AND, OR 관계 연산자

조건문에서는 and와 or의 의미를 갖는 관계 연산자를 사용할 수 있다.

and-a 또는 &&를 사용하며, or-o 또는 ||를 사용한다.

-a나 -o는 테스트문( [ ] ) 안에서 사용할 수 있는데, 이 때 괄호 등의 특수 문자 앞에는 역슬래시 ( \ )를 붙여야 한다.

업로드중..

업로드중..

4행 - if [ -f $fname ] && [ -s $fname ] ; then

입력한 파일 이름이 일반 파일 (-f)이고, 크기가 0이 아니라면 (-s) 5행을 실행한다.

then 구문은 다음 줄에 작성해도 되며, 세미콜론 ( ; ) 이후에 작성해도 된다.

  • 세미콜론은 앞뒤 구문을 행으로 분리해주는 기능

이 구문은 if [\(-f $fname \) -a \(-s $fname \) ] ; then 과 동일





📚 REFRENCE 📚

  1. 이것이 우분투/리눅스다 - 한빛미디어
profile
성장과 연구하는 자세를 추구하는 AI 연구개발자

0개의 댓글