1. Shell Script
→ 실행할 명령어를 미리 파일에 작성해두고 매크로처럼 실행
1) 셔뱅을 이용하는 방법
ex) du -h ~ | tall -n 1 : 홈 디렉토리의 파일 사용량 출력
위와 같은 명령어는 직접 타이핑하기 불편함 쉘 스크립트로 작성해두고 짧게 실행하는 것이 효율적
#!/bin/bash : 셔뱅
#! 뒤에 오는 파일/경로를 실행매개로 간주하고 명령을 내린다는 의미 → 어디에서 해당 파일을 실행하든 /bin/bash를 통해 실행
위와 같이 해당 파일에 실행 권한을 준 후 ./파일명을 통해 실행하면 위와 같이 동일한 결과가 출력되는 것을 확인할 수 있다.
2) source 명령어를 이용하는 방법
위와 같이 source 명령어를 이용해서도 쉘 스크립트 실행이 가능하고,
source를 사용하면 셔뱅을 적지 않아도 현재 실행한 쉘을 이용해 스크립트를 실행한다.
위와 같이 "."를 사용하여 source 명령어를 대체할 수 있지만 가독성 문제로 source를 사용하여 실행한다.
3) source와 ./ 실행의 차이점
위와 같이 vim 에디터를 이용해 test1.sh 파일을 생성하고, poiuqwer라는 사전에 지정된 적 없는 리눅스 명령어를 실행한다.
alias 명령어로 별명을 등록할 수 있고, 해당 명령을 실행하면 poiuqwer은 ls -alF로 대체된다.
또한, source 명령어로 해당 파일을 실행해보면 ls -alF 명령을 수행한 결과가 잘 출력되는 것을 확인할 수 있다.
하지만, 위와 같이 . 명령어를 사용하여 실행하면 command not found 오류가 발생하는 것을 확인할 수 있다.
. 명령어로 실행 시 새로운 쉘을 하나 더 순간적으로 열게 되는데 이 때 새로운 쉘에는 alias 설정이 되어 있지 않기 때문에 해당 명령을 수행하지 못한다.
4) 쉘스크립트의 배치
→ 파일 관리 용이성을 위해 쉘스크립트를 모아두어야 함
먼저, ~/bin 디렉토리를 생성하고 해당 경로로 모든 쉘 스크립트를 옮긴다.
어떤 경로에서든 파일명만 적어도 실행되도록 만드는 것이 효율적이다. → 전역 경로 설정
검색 경로에 ~/bin을 추가하기 위해 ~/.profile 파일에 위와 같은 PATH를 추가해준다.
위 명령어를 실행하면 즉시 적용되고, 해당 작업을 수행한 계정은 어디서든 .sh 파일을 호출할 수 있다.
위와 같이 파일명만 입력해도 쉘스크립트에 작성해뒀던 명령어가 잘 실행되는 것을 확인할 수 있다.
5) 전역 경로 비활성화
shopt -u sourcepath 명령어를 사용하면 source 명령어 사용 시 해당 단축경로를 비활성화할 수 있다.
위와 같이 현재 경로에 test.sh 파일이 없기 때문에 source 명령어를 사용하여 실행하면 오류가 발생하는 것을 확인할 수 있다.
2. Shell Script 작성하기
1) 개행
- 실제 쉘 스크립트는 여러줄로 작성
- 여러 줄 명령어를 순차적으로 실행시킬 때 기본적으로 엔터키를 눌러 개행시키면 순차적으로 하나씩 실행
위와 같이 엔터로 개행시킨후 실행해보면 쉘스크립트에 작성했던 명령들이 잘 수행되는 것을 확인할 수 있다.
- 엔터키 개행 대신 ;로 대체 가능
위와 같이 ; 로 수정해도 같은 결과로 동작되는 것을 확인할 수 있다.
2) 개행 무시
\ (역슬래시)를 사용하여 여러줄을 한 줄에 쓴 것처럼 동작시킬 수있다.
위와 같이 개행이 있지만 echo "root" 명령을 한 결과가 출력되는 것을 확인할 수 있다.
3) 주석 : #
4) 변수
변수명=저장할내역 : 변수 저장
$변수명 : 변수값 참조
기본적으로 위와 같이 변수를 저장하고 사용할 수 있다.
\$문자 : 일반문자 그대로 출력
\\$문자 : 백슬래시 문자(변수값) 출력
\\\$문자 : 백슬래시 일반문자 출력
5) quote : 따옴표
홑따옴표 : 변수값 포매팅 X
쌍따옴표 : 변수값 포매팅 O
위와 같이 홑따옴표는 일반 문자를 그대로 출력하고, 쌍따옴표는 해당 이름의 변수값이 출력되는 것을 확인할 수 있다.
만약 변수값 대입이 아닌 $name을 출력하고 싶다면 마찬가지로 \ (역슬래쉬)를 붙여주면 된다.
6) 명령어 치환
특정 명령어를 수행한 결과를 파일 이름 등으로 사용하고 싶은 경우 $(명령어) 로 이용 가능
위와 같이 $(명령어)를 이용해 변수를 생성하고 파일 생성 명령어 touch를 이용하는 쉘스크립트를 작성했다.
쉘스크립트를 실행해보면 위와 같이 touch $filename 명령이 잘 수행된 것을 확인할 수 있다.
7) 파라미터 전달
쉘 스크립트에서는 파라미터의 위치에 따라 $번호에 해당하는 변수에 대입된다. ($0부터 시작)
위와 같은 쉘스크립트를 작성해주고
위 파일을 실행해보면 위와 같이 파라미터 위치에 따라 0부터 순서대로 해당 변수에 대입되는 것을 확인할 수 있다.
위와 같이 전달된 인자의 개수가 몇 개인지는 $#를 사용하여 조회할 수 있다.
8) 제어문
① if문
- if [ 명령어 ]; then ~ else ~ fi
위와 같이 첫번째 파라미터 값이 bin이면 OK를, 아니면 NO를 출력하는 조건문을 작성했다.
※ if [ 명령어 ]; 입력 시 대괄호 안에 공백을 주의해야 한다.
※ 세미콜론이 있다면 then과 조건식이 같이 놓일 수 있지만 생략했다면 다음줄로 내려야 한다.
위와 같이 출력 결과가 잘 수행되는 것을 확인할 수 있다.
- 명령어의 종료 상태
$?를 사용하여 직전에 실행한 명령어의 상태를 조회할 수 있다.
기본적으로 명령어는 정상 종료 시 0을 가지지만, 에러 발생 시 0이 아닌 다른 번호를 가진다.
- if와 종료 상태
조건식을 작성하는 [ ] 역시 명령어이기 때문에 해당 조건식이 참이면 0, 거짓이면 0 이외의 숫자를 반환한다.
조건문 사용 시 반드시 [ ] 를 사용해야 하는 것은 아니고 위와 같이 참과 거짓을 판단할 수 있는 명령어라면 [ ] 없이도 사용이 가능하다.
- test 명령어로 [ ] 대신하기
위와 같은 조건문이 있을 때 [ ]를 test 명령어로 대체할 수 있다.
이처럼 [ ]를 사용했을 때와 같은 결과를 출력하는 것을 볼 수 있지만 [ ]가 가독성이 더 좋으므로 test 명령어를 잘 사용하지는 않는다.
- 문자열 비교
= | 같다 |
!= | 다르다 |
-n | null이 아니다 |
-z | null이다 |
위 스크립트에서는 첫 파라미터(filename)가 null이라면 default.dat을, 값이 있으면 filename을 출력해준다.
위와 같이 결과가 잘 출력되는 것을 확인할 수 있다.
- 정수 비교
-eq | 같다 |
-ne | 다르다 |
-lt | 작다 |
-gt | 크다 |
-le | 작거나 같다 |
-ge | 크거나 같다 |
위와 같이 기본적으로 max 변수에는 첫번째 파라미터 값이 들어 있고, -lt로 두 값을 비교하여 두번째 파라미터 값이 더크다면 max를 두 번째 파라미터로 넣어주는 조건문을 작성했다.
위와 같이 조건에 따라 결과가 잘 수행되는 것을 확인할 수 있다.
- 파일 비교
-e | 파일 존재 |
-d | 파일 존재하고, 디렉터리임 |
-h / -L | 파일 존재하고, 심볼릭링크임 |
-f | 파일 존재하고, 일반파일임 |
-r | 파일 존재하고, 읽기 권한이 있음 |
-w | 파일 존재하고, 쓰기 권한이 있음 |
-x | 파일 존재하고, 실행 권한이 있음 |
file1 -nt file2 | file1이 file2보다 최근에 변경됨 |
file1 -ot file2 | file2가 file1보다 최근에 변경됨 |
- 연산자 결합
-a | and 연산 |
-o | or 연산 |
! | not 연산 |
연산자 결합 역시 ( )를 이용하여 우선순위를 다르게 지정할 수도 있다.
- &&와 ||를 활용한 명령어 순차평가
&& | 왼쪽이 참이어야 오른쪽을 실행 |
|| | 왼쪽이 거짓일 때 오른쪽을 실행 |
위와 같이 && 연산자를 이용하여 iftest.sh 파일이 존재하기 때문에 ifex.sh의 내용을 잘 출력하는 것을 볼 수 있다.
위와 같이 || 연산자를 이용하여 ifor.sh 파일이 존재하지 않기 때문에 ifor.sh 파일을 잘 생성해주는 것을 볼 수 있다.
② for문
- for 변수 in 리스트 ~ do ~ done
위와 같이 반복문을 작성할 수 있고 name이라는 변수에 값을 차례로 넣어 출력하는 것을 확인할 수 있다.
head : 맨 위부터, tail : 맨 뒤부터
위와 같이 경로에 따라서는 와일드카드를 사용할 수도 있고, 현재 경로의 모든 .sh 파일의 내용을 세번째 줄까지 출력해주는 것을 확인할 수 있다.
- seq 1 5 : 1~5 출력
for을 쓰지 않고 seq을 이용하여 더 간단하게 반복문을 사용할 수 있다.
위와 같이 seq을 이용하여 현재 경로에 5개의 파일을 생성하라는 코드를 작성할 수 있다.
실행 후 확인해보면 위와 같이 5개의 파일이 잘 생성된 것을 확인할 수 있다.
- 커맨드라인으로 보낸 인자 일괄처리
"$@"를 in 우변에 사용하면 받은 파라미터를 전부 반복문 타겟으로 잡는다.
위 코드는 paratest.sh를 실행하며 넘긴 모든 인자를 $@에 받아 처리해준다는 의미이다.
이와 같이 파라미터 값들이 다 넘겨지고 출력되는 것을 확인할 수 있다.
③ case문 : if문보다 강한 분기처리
case 문자열 in 패턴1) ~ ;; 패턴2) ~ ;; esac
case문을 사용하여 첫번째 파라미터 값이 start나 stop인 경우에만 checked가 출력되도록 하는 코드를 작성했다.
위와 같이 분기문이 잘 처리되어 결과가 출력되는 것을 확인할 수 있다.
④ while문 : 조건이 거짓이 될 때까지 반복
i 값이 10보다 작은 경우 계속 반복하는 while문을 작성했다.
실행해보면 위와 같이 반복문이 수행된 결과가 잘 출력되는 것을 확인할 수 있다.
⑤ until문 : while문과 반대로 조건이 거짓인 동안만 실행
위와 같이 until은 while과 사용법이 동일하게 수행된다.
⑥ C언어식 반복문
위와 같이 C언어식으로 반복문을 작성하는 것도 가능하다.
이 때 괄호는 겹쳐야 하고, 겹친 괄호 내에서는 변수에 $를 붙이지 않는다는 것을 주의해야 한다.
실행해보면 위와 같이 반복문이 잘 수행되는 것을 확인할 수 있다.
9) 셀 내부에서 함수 활용하기
function 함수명 (){
실행문;
}
function 함수명 {
실행문;
}
함수명(){
실행문;
}
위의 세 가지 방식으로 쉘 내부에서 함수를 활용할 수 있다. 주로 세번째 방식을 사용한다.
date 결과와 디렉터리의 용량을 보여주는 du 명령어를 수행한 결과를 마지막 1줄만 출력하라는 homesize() 함수를 선언했고, 선언 후 homesize 함수를 호출해준다.
※ 쉘 함수는 반드시 호출구문 위쪽에 위치해야 한다.
위와 같이 수행 결과가 잘 출력되는 것을 확인할 수 있다.
또한, 종료코드는 return 상태코드 형식으로 전달하면 된다.
'네트워크캠퍼스 > LINUX' 카테고리의 다른 글
크론잡과 크론탭 (0) | 2024.02.21 |
---|---|
Shell Script 실습 (0) | 2024.02.20 |
Devops와 SE를 위한 리눅스 커널 이야기 (0) | 2024.01.17 |
프로세스 (0) | 2024.01.16 |
텍스트에디터 (0) | 2024.01.15 |