섹션 9. 파이프와 작업제어

 

리눅스 서버를 자동화하여 관리하기 위한 쉘 스크립트(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