Bash – redicrection, pipelin, 문자열 다루기, Quoting, nice와 chrt로 프로세스 우선순위 바꾸기

Table of Content

UNIX I/O Scheme : Standard I/O

Standard I/O : First scheme for interactive users at terminals

  • UNIX의 file은 입력으로 char 바이트 시퀀스를 받는다.
  • UNIX에서는 모든 생성되거나 입력으로 들어가는 데이터를 파일로 다룬다.
    위 두가지 스키마 철학이 UNIX가 타 시스템보다 복잡하지 않으면서도 효율적인 I/O를 제공하도록한다. (다른 시스템에서는 데이터가 block, card, record 등으로 여러가지로 나뉘어지며 그것을 핸들링 하는 I/O Scheme 또한 복잡하다)

I/O Redirection

cat < file1 > file2 == cp file1 file2

Pipeline

cat과 more 예시

cat ~/.bashrc | more
cat ~/.bashrc | more <line-number>
cat ~/.bashrc | more <line-number>

기본 명령어

STDIN와 file을 인자로 받는 cat

cat은 인자가 없으면 stdin을 기다리기 때문에 아래 명령어들은 모두 사용자 입력을 기다렸다 입력을 echo한다.

cat
cat -
cat /dev/stdin
cat /proc/self/fd/0

문자열 검색하고 자르기 : grep, cut

cut의 -d는 delimeter, -f는 컬럼 필드를 의미한다.

# test.txt
dev jun 29 male
dev jisu 29 female
dev gaeun 28 female
dev sungsoo 33 male
cat test.txt | grep "female" | cut -d: -f 2,3
# 출력
jisu:29
gaeun:28

문자열 알파벳 순으로 정렬하기 : sort

-d : dictionary 옵션으로 사전순 정렬을 의미한다.

cat test.txt | grep "female" | cut -d: -f 2,3 | sort -d
#출력
gaeun:28
jisu:29

문자열 치환하기 : tr

cat test.txt | grep "female" | cut -d: -f 2,3 | sort -d | tr [:] [\-]
# 출력
gaeun\28
jisu\29

삭제, 치환, 부분 출력 등 다양하게 조작하기 : sed

sed -n -e '2,$p' test.txt # 2번째 줄부터 끝까지 출력
sed -n -e '/male/p' test.txt # male 이라는 문자열이 포함되는 라인만 출력
sed -n -e '1d' -e '1,$p' test.txt # 첫줄 지우고 나머지 모두 출력
sed -n -e 's/sungsoo/susu/g' -e '1,$p' test.txt # sungsoo를 susu 치환
sed -n -e '/gaeun/s/dev/alien/' -e '1,$p' test.txt # gaeun을 검색하고  일치하는 문자열 중 'dev'를 alien으로 치환
# 출력
dev:jun:29:male
dev:jisu:29:female
alien:gaeun:28:female
dev:sungsoo:33:male
sed -n -e '/sungsoo/i\newtwo' -e '1,$p' test.txt # sungsoo 있는 문자열 윗줄에 newone을 추가
sed -n -e '/sungsoo/a\newone' -e '1,$p' test.txt # sungsoo 있는 문자열 아래에 newone을 추가
sed -n -e '/sungsoo/c\newtwo' -e '1,$p' test.txt # sungsoo가 있는 라인을 newbie로 대체
#
dev:jun:29:male
dev:jisu:29:female
dev:gaeun:28:female
newtwo

Quoting

아래와 같이 *' { , }같이 특정한 의미가 있을 수 있는 문자열이 있는 경우

echo Hatter's tea party <3
find / -name lib*.{so,a}

\(backslash) 를 사용하여 의미하는 바 그대로임을 구분해 줄 필요가 있다. 첫문장에서는 apapostrophe와 < 가 문자 그대로 출력되어야 하는데 특정한 연산이나 파일 Redirection을 의미할 수도 있으므로 \를 붙여 구분해야 하고 find 역시 * 와 대괄호가 wildcard인지 문자열인지 구분해야하기 때문에 \를 붙여준다.

echo Hatter\'s tea party \<3
find / -name lib\*.\{so,a\}

백그라운드 작업과 우선 순위

nice 명령어로 우선 순위 제어하기

nice -n<nice 값> <command>

nice 19(나이스)와 nice 20(안 나이스) 프로세스 속도 비교

nice 명령어는 프로세스 nice(우선순위)값을 변경하는 명령어로 sudo 권한이 없으면 지정해줄 수가 없다. 왜냐면 특정 프로세스들의 우선순위를 지켜야하기 때문이다. renice 명령어는 이미 돌고 있는 프로세스의 nice 값을 재 지정해줄 수 있는 명령어다.
프로세스 실행 우선순위는 Userland에서 적용되는 nice값과 OS 커널이 반영하는 priority value 두가지로 나뉘어진다.

아래 스크립트는 nice값이 다른 프로세스 여러가지를 동시에 백그라운드에서 실행시켜서 누가 먼저 끝나는지 확인해보려고 만든 스크립트인데 극단적으로 항상 P1 프로세스가 제일 늦게 끝나지는 않았다..(뭐징... 이유를 아는 분이 계시다면 가르침을 주시면 좋겠다.)

# run.sh

#!/bin/bash
nice -n 19 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "Nice P1 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P2 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P3 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P4 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P5 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P6 done"' &
nice -n -20 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P7 done"' &

위 스크립트를 돌리고 ps -al 명령어를 쳐보면 PRI와 NI값이 각각 priority값과 nice값을 보여준다. PRI값은 NI값에 20을 더해서 -19~20 가 0~39로 매핑된다고 한다. 그런데 터미널에서 출력해봤을 때는 매핑값이 달랐다.

F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R     0   670     8  0  99  19 -  2155 -      pts/0    00:00:00 bash
4 R     0   671     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
4 R     0   672     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
4 R     0   673     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
4 R     0   674     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
4 R     0   675     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
4 R     0   676     8  0  60 -20 -  2155 -      pts/0    00:00:00 bash
0 R  1000   677     9  0  80   0 -  2634 -      pts/0    00:00:00 ps

chrt : Real time prority 지정 명령어 사용하기

nice가 유저 프로세스의 우선순위를 결정한다면 chrt 명령어는 OS의 스케줄링 정책에 따라 Realtime Process의 PRI를 지정해줄 수 있다.

chrt -rr <priority-level> <command>

스케줄링 정책에 따른 priority range는 아래와 같은 명령어로 확인 가능하다.

$ chrt --max
SCHED_OTHER min/max priority    : 0/0
SCHED_FIFO min/max priority     : 1/99
SCHED_RR min/max priority       : 1/99
SCHED_BATCH min/max priority    : 0/0
SCHED_IDLE min/max priority     : 0/0
SCHED_DEADLINE min/max priority : 0/0

위 스크립트에 chrt 명령어를 추가하여 누가 먼저 끝나는지 PR값은 어떻게 되는지 확인을 해보면

#!/bin/bash
nice -n 19 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "Nice P1 done"' &
nice -n 10 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "P2 done"' &
... 생략

echo "With chrt"
chrt -rr 90 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "CHRT Nice P1 done"' &
chrt -rr 50 bash -c 'i=0;while [ $i -le 500000 ]; do ((i++)); done; echo "CHRT P2 done"' &
... 생략

아래와 같이 nice값은 보이지 않고 90은 -31로, 50은 9값으로 매핑되었다.

4 R     0   955     8 94 -31   - -  2155 -      pts/0    00:00:02 bash
4 R     0   956     8 95   9   - -  2155 -      pts/0    00:00:02 bash
... 생략

Control Key

stty

터미널 설정 명령어로 stdin에 들어오는 입력에 관한 설정을 할 수 있다. 아래 명령어를 통해 Control키들이 어떻게 동작하는지 확인가능하다.

stty --all
# 출력
speed 38400 baud; rows 50; columns 198; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

아래 코드처럼 터미널에 보낼 시그널들을 특정 컨트롤 키에 매핑할 수 있다.

# CTRL^C 키가 보내던 인터럽트 시그널을 CTRL^K가 보내게 함
stty intr ^K

키 테이블

key stty name description
CTRL-C intr 현재 명령 중단
CTRL-\|quit CTRL-C보다 더 강하게 중단시켜서 마무리 되지 못한 리소스가 존재할 수 있다
CTRL-D eof input이 끝났음을 보낸다
CTRL-Z susp 현재 명령어를 중지 시킨다

참고문헌

Which real-time priority is the highest priority in Linux

Related Posts

답글 남기기

이메일 주소는 공개되지 않습니다.