Study/System Engineer

KDT - Shell script

jxx_yxjx 2024. 1. 18. 11:50

1. 셸 스크립트란?

실행할 명령어를 미리 파일에 작성해놓고 파일명만 입력하여 긴 명령어를 매크로처럼 실행할 수 있다.

 

2. 셸 스크립트 종류

셸 스크립트의 종류는 여러가지가 있으나 대부분 호환이 가능하다.

그러나 특정 종류의 셸에서만 실행되는 스크립트가 존재한다면 문제가 될 수 있으므로 범용적으로 셸을 활용하는 것이 좋다.

sh쉘이 기본이지만 bash쉘이 가장 많이 사용되므로 bash쉘을 기반으로 실습해보자.

 

3. 작성

$ du -h ~ | tail -n 1 로 홈 디렉토리의 파일 사용량을 출력해보자.

위와 같은 명령어는 옵션도 많고 파이프 문자도 사용하므로 셸 스크립트를 활용하는 편이 편리하다.

셸 스크립트 파일은 .sh 확장자를 가지므로 $ vim homesize.sh 로 파일을 작성해보자.

첫 줄(셔뱅)은 #!로 시작하는 파일 및 경로를 실행매개로 간주하고 명령을 내린다는 의미이다.

즉, 어떤 위치에서 파일을 실행하더라도 bash 경로로 실행한다는 의미를 갖는다.

작성이 완료되면 $ ./homesize.sh 로 셸 스크립트를 실행한다.

+ ./ 를 붙이지 않으면 command not found 오류가 발생하므로 주의하자

그러나 셸을 실행해도 Permission denied 가 발생하는 경우가 있는데, 이 때는 chmod로 권한을 추가해주면 된다.

 

4. 셔뱅 이외의 방법으로 셸 스크립트 실행하기

$ source ./파일명.sh 로 셔뱅을 적어넣지 않아도 스크립트를 실행할 수 있다.

+ source 대신에 . 을 사용할 수도 있다. 그러나 가독성 문제로 source를 사용하는 경우가 많다. 또한 source 명령어는 현재 셸에서 실행하도록 되어있지만 .은 새로운 셸을 순간적으로 열어서 실행하기 때문에 alias 같은 경우를 인식하지 못한다.

 

5. 셸 스크립트의 배치

셸의 위치를 마음대로 지정하여 작성하다보면 파일이 많아질수록 $ ./파일명.sh 로 실행해야 하는 상황에서 관리하기 힘들어진다. 따라서 셸 스크립트를 모아두는 디렉터리를 작성하여 해결해보자.

$ mkdir ~/bin  $ mv 파일명.sh ~/bin

bin폴더를 생성해주고 셸 스크립트 파일들을 전부 옮겨준다.

그리고 vim으로 ~/.profile 파일을 열어 ( $ vim ~/.profile) 환경변수 PATH에 ~/bin을 추가한다

PATH="$PATH:~/bin"

이후 $source ~/.profile 을 실행하면 즉시 적용되고, $ 파일명.sh 을 입력했을 때 어떤 경로에서건 실행할 수 있다.

 

5. 전역 경로 비활성화

$ ls homesize.sh 는 현재 경로에 homesize.sh 가 없다면 실행되지 않지만 $ source homesize.sh는 실행된다.

$ shopt -u sourcepath 로 해당 단축경로를 비활성화 할 수 잇다.

 

6. 셸 스크립트 여러 줄 작성

여러 줄의 명령어를 순차적으로 실행하고 싶을 때는

#!/bin/bash

echo "root"
cd /
ls -l

1) 엔터키 사용

#!/bin/bash

echo "root";cd /;ls -l

2) ; 사용

의 방법이 있다.

+ 개행 무시 문자로 역슬래시 (\) 가 존재한다.

 

7. 주석

# 을 붙이면 # 이후는 주석으로 처리된다.

 

8. 변수

셸 변수는 변수명 = 저장할내역 형식으로 사용하며 $변수명 형식으로 해당 변수의 값을 참조해서 사용할 수 있다.

 

9. quote 이해

' -> 변수 값 포맷 x 

" -> 변수 값 포맷 o 

ex)

#!/bin/bash

name=jxxyxjx
echo 'my name is $name'
echo "my name is $name"

홑따옴표는 my name is $name 을 출력하는 반면 쌍따옴표는 my name is jxxyxjx 로 출력되며 변수값을 참조해온다.

+ 쌍따옴표 내에서 변수값을 참조하고 싶지 않다면 \$name 과 같이 탈출문자 \을 활용하면 된다.

 

9. 명령어 치환

$(명령어) 로 명령을 실행한 결과를 파일 이름으로 사용할 수 있다.

ex) 날짜를 변수에 저장하고 touch를 통해 날짜로 파일을 생성

#!/bin/bash

filename=$(date '+%Y-%m-%d')
touch "$filename"

 

10. 파라미터 전달

다음과 같이 $ 번호 = 값 을 출력하는 파일을 작성한 후 

#!/bin/bash

echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"
echo "\$5 = $5"

 

$ ./parameteres.sh hi im jxxyxjx 로 입력값을 주면

./ parameters.sh 는 $0, hi는 $1, im은 $2, jxxyxjx는 $3에 저장되는 방식임을 확인할 수 있다.

+ 인자의 개수는 $#으로 조회할 수 있다.

 

11. if문

if문에서는 [ 명령어 ]  의 내용이 true -> 실행할 내용, false -> else나 elif 내용이 출력된다.

if_bin.sh

#!/bin/bash

if [ "$1" = "bin"]; then
	echo "OK"
else
	echo "NO"
fi

코드를 작성하여 파라미터에 bin을 주고 실행하면 OK, 다른 파라미터 값이면 NO가 출력되는 것을 알 수 있다.

* 띄어쓰기 중요

+ $ if [ “$1” = “bin” ] 은 $ if test “$1” = “bin” 으로 대체 가능하지만 [ ] 의 가독성이 더 좋다.

 

12. 명령어의 종료 상태

명령어는 정상 종료시 0, 에러가 발생하면 0이 아닌 다른 번호를 반환한다.

showstatus.sh

#!/bin/bash

ls /
echo "exit ($?)"

ls /test
echo "exit ($?)"

root 폴더를 조회한 경우 있는 경로이므로 정상 종료되어 0이 반환되지만, 없는 경로를 조회한 경우 0이 아닌 다른 번호를 반환한다.