리눅스 서버를 자동화하여 관리하기 위한 쉘 스크립트(Shell Script) 심화 강좌를 정리합니다.
출처 : inflearn
1. 파이프
named pipe 나 fifo 라는 명칭으로 불리움 파이프에는 읽기 끝과 쓰기 끝이 있습니다. 파이프의 쓰기 쪽에 기록된 데이터는 파이프의 읽기 쪽에서 읽을 수 있습니다. 프로세스(echo)가 파이프에 쓰기를 시도하는 경우, 반대쪽 프로세스에서 파이프에서 충분한 데이터를 읽을 때까지는 쓰기 동작이 완료되지 못하고 echo 명령은 블록(block)됩니다.
SHKIM:/home/shkim$ pwd
/home/shkim
SHKIM:/home/shkim$ mknod /tmp/mypipe p
SHKIM:/home/shkim$ echo hello world >/tmp/mypipe # 파이프에 쓰기동작
|
새로운 터미널을 실행해 mypipe 파일의 상태를 확인 합니다. 파이프에서 읽기 동작을 마친 후에는 파이프는 비워짐.
SHKIM:/home/shkim$ ls -l /tmp/mypipe
prw-r--r-- 1 shkim admin 0 2월 22 23:39 /tmp/mypipe
SHKIM:/home/shkim$ cat /tmp/mypipe # 파이프에서 읽기 동작
hello world
SHKIM:/home/shkim$
SHKIM:/home/shkim$ cat hello.txt | more # unnamed pipe
hello
# pipe를 통한 처리 흐름
SHKIM:/home/shkim$ find . -name "*.o" -print0 | xargs -0 rm -rf
2. 프로세스 대체
comm : 두개의 비교 대상 디렉토리의 차이점을 확인할 때 유용한 명령어 프로세스 대체(command substitution)<(명령어…)
SHKIM:/home/shkim/edu/shell_cmd$ ls -R ./images
./images:
Balloon.jpg Candy.jpg glob.gif settings_down.JPG settings_up.JPG shadingimage.tiff smaller.tiff
SHKIM:/home/shkim/edu/shell_cmd$ ls -R ./images_mirror/
./images_mirror/:
Balloon.jpg glob.gif settings_down.png settings_up.png shadingimage.tiff smaller.tiff
comm 옵션은 1,2,3 이 있다. 2 : 두개의 내용을 비교하되, 파일 2에 있는 것은 출력하지 않는다 3 : 두개의 내용을 비교하되, 2개의 파일내에 공통적으로 존재하는 라인은 출력하지 않는다.
SHKIM:/home/shkim/edu/shell_cmd$ comm -23 <(ls -R /home/shkim/edu/shell_cmd/images|sort) <(ls -R /home/shkim/edu/shell_cmd/images_mirror/|sort)
/home/shkim/edu/shell_cmd/images:
Candy.jpg
settings_down.JPG
settings_up.JPG
jpg 확장자의 파일의 갯수 확인하기.
SHKIM:/home/shkim/edu/shell_cmd/images$ i=0
SHKIM:/home/shkim/edu/shell_cmd/images$ pwd
/home/shkim/edu/shell_cmd/images
SHKIM:/home/shkim/edu/shell_cmd/images$ ls
Balloon.jpg Candy.jpg glob.gif shadingimage.tiff smaller.tiff
SHKIM:/home/shkim/edu/shell_cmd/images$ while read file; do
> ((i++))
> done < <(find . -type f -name "*.jpg")
SHKIM:/home/shkim/edu/shell_cmd/images$
SHKIM:/home/shkim/edu/shell_cmd/images$ echo $i
2
3. 서브쉘
() : 프로세스 그룹으로 실행됨
SHKIM:/home/shkim$ echo begin;(for i in {100..110};do echo $i >> num100; sleep 1;done)&
begin
[1] 8290
SHKIM:/home/shkim$ echo end; tail -f num100
end
100
101
102
103
104
105
106
107
108
109
110
images 파일을 묶은 후 /edu 해제 많은 파일을 이동 복사할 때 시간이 단축되는 효과가 있다.
SHKIM:/home/shkim/edu/shell_cmd$ (cd ~/edu/shell_cmd/images && tar cf - .) |(cd ~/edu && tar xpvf -)
./
./Balloon.jpg
./Candy.jpg
./glob.gif
./shadingimage.tiff
./smaller.tiff
SHKIM:/home/shkim/edu/shell_cmd$
# 결과 /images 폴더의 파일들이 /edu 로 복사된다.
4. 함수
함수를 호출할 때는 먼저 정의 하고 호출하여야 한다.(쉘스크립트 특징)
SHKIM:/home/shkim/edu$ sum() { declare -i sum; START=$1; END=$2; for i in `eval echo {$START..$END}`; do ((sum+=i)); done; echo $sum; }
SHKIM:/home/shkim/edu$ total=$(sum 1 100); echo $total
5050
#!/bin/bash
sum() {
declare -i sum
START=$1
END=$2
for i in `eval echo {$START..$END}`
do
((sum+=i))
done
echo $sum; }
5. 명령어(shift)
$# : 전달인자의 갯수 shift 1 : 매개변수 리스트를 하나씩 자리이동
SHKIM:/home/shkim/edu$ set 1 2 3 4 5
SHKIM:/home/shkim/edu$ while [ $# -gt 0 ];do echo $1; shift 1;done
1
2
3
4
5
6. source 와 bashrc
일반 스크립트의 경우 script 내의 환경변수는 한 번 사용하고 소멸되지만, source 를 사용하면 내부에서 선언된 환경변수가 소멸되지 않고 현재쉘에서 유지된다. source = . 동일한 기능을 한다.
SHKIM:/home/shkim$ source ~/.bashrc
SHKIM:/home/shkim$ ~/.bashrc
-bash: /home/shkim/.bashrc: Permission denied
SHKIM:/home/shkim$ . ~/.bashrc
7. 작업제어
리눅스에서 모든 프로세스(프로그램)는 표준 입/출력 오류 장치(파일)을 오픈한 상태로 실행한다. STDIN / STDOUT / STDERR foreground 로 실행 되며 ctrl + c 를 누르면 커널에서 signal 을 주어 종료하게 된다.
SHKIM:/home/shkim$ sleep 1000
hello^C
SHKIM:/home/shkim$
명령어 뒤에 ‘&’ 를 추가하면 백그라운드로 실행하게 된다. fg 명령어를 입력하면 가장 최근에 실행한 프로세스를 foreground로 올리는 기능을 한다. ctrl + z 를 입력하면 해당프로세스를 중지 시킨다.
SHKIM:/home/shkim$ sleep 1000 &
[1] 31910
SHKIM:/home/shkim$ ps
PID TTY TIME CMD
27439 pts/0 00:00:00 bash
31910 pts/0 00:00:00 sleep
32342 pts/0 00:00:00 ps
SHKIM:/home/shkim$
SHKIM:/home/shkim$ fg
sleep 1000
^Z
[1]+ Stopped sleep 1000
sleep 프로세스 2번째 T 가 stop을 의미함. bg 명령어를 입력하면 다시 실행을 재개 함.
SHKIM:/home/shkim$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 R 1001 1029 27439 0 80 0 - 29527 - pts/0 00:00:00 ps
0 S 1001 27439 27438 0 80 0 - 28750 do_wai pts/0 00:00:00 bash
0 T 1001 31910 27439 0 80 0 - 28103 do_sig pts/0 00:00:00 sleep
SHKIM:/home/shkim$ bg
[1]+ sleep 1000 &
8. 디버깅
SHKIM:/home/shkim/edu/shell_cmd$ cat debug.sh
#!/bin/bash
export PS4='+$LINENO:$FUNCNAME: '
### Used for TRACE
trap '(read -p "[$LINENO] $BASH_COMMAND?")' DEBUG
set -x
function sub() {
echo 'my subroutine()'
}
echo hello world1
echo hello world2
echo hello world3
sub 1 2
echo hello world4
echo hello world5
echo hello world6
echo hello world7
echo hello world9
set -x 만으로 간단한 스크립트 디버깅이 가능하다
SHKIM:/home/shkim/edu/shell_cmd$ ./debug.sh
+ echo hello world1
hello world1
+ echo hello world2
hello world2
+ echo hello world3
hello world3
+ sub 1 2
+ echo 'my subroutine()'
my subroutine()
+ echo hello world4
hello world4
+ echo hello world5
hello world5
+ echo hello world6
hello world6
+ echo hello world7
hello world7
+ echo hello world9
hello world9
export PS4=’+$LINENO:$FUNCNAME: ‘ 으로 라인넘버와 함수명, 실행명령도 확인 가능하다.
SHKIM:/home/shkim/edu/shell_cmd$ ./debug.sh
+14:: echo hello world1
hello world1
+15:: echo hello world2
hello world2
+16:: echo hello world3
hello world3
+17:: sub 1 2
+11:sub: echo 'my subroutine()'
my subroutine()
+18:: echo hello world4
hello world4
+19:: echo hello world5
hello world5
+20:: echo hello world6
hello world6
+21:: echo hello world7
hello world7
+22:: echo hello world9
hello world9
trap ‘(read -p “[$LINENO] $BASH_COMMAND?”)’ DEBUG 으로 라인을 한줄 한줄 보면서 디버깅 할 수 있다.(싱글스텝 : 코드를 한 번에 한줄씩 실행한다는 뜻)
SHKIM:/home/shkim/edu/shell_cmd$ ./debug.sh
[8] set -x?
++14:: read -p '[14] echo hello world1?'
[14] echo hello world1?
+14:: echo hello world1
hello world1
9. 명령어(cron)
crontab -e 설정명령어 분 시 일 월 요일 의 순서로 작성하면 된다.
SHKIM:/home/shkim/edu/shell_cmd$ crontab -e
설정 내용 | 설명 |
---|---|
* * * * * | 매 분마다 실행 |
*/10 * * * * | 10분 마다 실행 |
10 * * * * | 매시 10분에 실행 |
10 1 1 12 * | 12월 1일 1시 10분에 실행 |
10 1 * * Mon | 매주 월요일 1시 10분에 실행 |
10 1 * * 1,4 | 매주 월,목요일 1시 10분에 실행 |
10 1 * * 1-5 | 월-금요일 1시 10분에 실행 |
crontab -l : crontab 설정 확인
SHKIM:/home/shkim/edu/shell_cmd$ crontab -l