Linux 필수 개념
i18n
internationalization
i~n사이의 알파뱃 개수
절대 경로 , 상대 경로
절대 경로(absolute path = abs-path)
- root directory를 시작으로 하는 경로
e.g. /usr/local/bin
상대 경로(relative path)
- 현재 디렉토리 . 를 시작으로 하는 경로 (.은 생략가능하다)
e.g. ../../tmp == ./../../tmp
e.g. work/day1 == ./work/day1
unix file mode
file mode bit는 3+9 bit 체계
- 숨겨진 3bit를 포함하여 12
표기 방법
- symbolic mode
- octal mode: bit를 8진수법으로 표기 → 이방법을 많이 사용
디렉토리의 경우 기본 mode값은 umask값을 뺀 나머지가 된다.
umask가 022라면 디렉토리가 777 - 022 = 755가 생성시 기본 mode가 된다. 파일은 666 - 022 = 644가 생성시 기본 mode가 된다.
linux 필수 명령어
Tab
완성 기능이라는 것이 있다. <tab>키를 누르면 자동 완성이 나온다. 그 단어로 시작하는 것이 여러 개일 경우에는 tab-tab을 쳐야 나온다.
e.g. ls /s 만 치고 tab하면 ls /usr/로 자동완성된다. 하지만 ls/usr/s 하고 tab을 누르면 안나온다. 더블탭을 누르게 되면 s로 시작하는 여러 개를 보여준다.
LANG은 대체로 영여로 해놓는 것이 좋다.
1
$ export LANG=en_US.utf8
ls
ls [option]
- a : all
- l : long
- t : sort by mtime (newest first)
- r : reverse
1
2
3
4
5
6
7
$ ls -al
drwx------ 3 jaehoyoon jaehoyoon 4096 2월 21 15:37 .gnupg
drwx------ 3 jaehoyoon jaehoyoon 4096 2월 21 15:37 .local
drwx------ 3 jaehoyoon jaehoyoon 4096 2월 21 15:41 .mozilla
-rw-r--r-- 1 jaehoyoon jaehoyoon 807 2월 21 15:18 .profile
-rw-r--r-- 1 jaehoyoon jaehoyoon 0 2월 21 15:46 .sudo_as_admin_successful
drwx------ 6 jaehoyoon jaehoyoon 4096 2월 21 15:41 .thunderbird
ls
는 파일정보를 나타내는 명령어다.
맨 앞에 d,-는 파일 타입을 나타내는데, -는 일반 파일, d는 디렉토리, l은 symbolic link에 해당하고, 그 다음 숫자는 링크의 갯수를 나타낸다. r의 권한은 dir의 목록을 읽을 수 있고, x의 권한은 있어야만 목록에 있는 링크에 access할 수 있다. x를 가지면 파일의 명만 알면 access할 수 있지만, r의 권한이 없으면 파일의 명을 외부에서 볼 수는 없다.
ls -lt는 길게 정렬하여 보여주는데, 최신파일이 맨 위에 있기에 뒤집어서 보는 것이 편하다. reverse를 시켜주기 위해 -ltr를 옵션으로 둔다.
direction
1
echo 'hello world' > testdir/hello.txt
라고 작성하면 hello world라는 것을 hello.txt에 저장하겠다는 것이다.
chmod
mode값을 변경하기 위해서는 chmod
1
2
$ chmod 664 testdir
$ ls testdir
chmod 664 대신 -x, +x, =rx 등으로 할 수도 있다.
mkdir, rm
디렉토리를 만드는 건 mkdir, 삭제할 때는 rm -rf로 사용한다. 여기서 여러 개의 디렉토리를 만들려면 mkdir -p, -p를 꼭 두어야 한다.
1
$ mkdir -p mka/asms
rm: remove
cp, mv
cp: copy <원래 디렉토리> <복사할 디렉토리>
mv: move <원래 디렉토리> <이동할 디렉토리>
mv에서 이동될 디렉토리에서 디렉토리인데, ~/까지만 적으면 원래의 디렉토리 이름 그대로, 이름까지 적어주면 새로운 이름으로 이동됨
1
2
$ mv ~/bashrc_example ~/old_bashrc
$ ls -l !$
!$는 그 전의 명령어를 다시 불러오는 것이다.
chown, chgrp
소유자, 그룹을 변경하는 명령어다.
1
2
3
# chown root helloworld
# ls -l helloworld
-rwxrwx-wx 1 root jaehoyoon ...
이 때 root 유저으로 해야 가능하다.
file
file명령어는 파일의 타입 확인하는 명령어다. 고유의 표식을 근거로 파일의 종류를 분류하는데 이 근거를 magic 데이터라 한다. 이 magic데이터의 위치는 대부분 /usr/share/file/magic에 있다.
stat
stat은 status of file로, meta data 즉, 수식하는 정보, 파일 이름, 생성시간, 권한 등을 출력한다.
!$와 비슷하게 <ALT + .> 을 눌러도 맨 마지막 인수 단어를 카피해온다.
이 출력 중 중요한 것은
- access: 마지막으로 접근한 시간
- modify: data가 변경된 시간 (==mtime)
- change: meta data가 변경된 시간 (==ctime)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ stat ~/.bashrc
File: /home/jaehoyoon/.bashrc
Size: 3771 Blocks: 8 IO Block: 4096 일반 파일
Device: 801h/2049d Inode: 2228228 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-21 15:37:32.595367589 +0900
Modify: 2022-02-21 15:18:16.532580138 +0900
Change: 2022-02-21 15:18:16.532580138 +0900
$ cp ~/.bashrc ~/old_bashrc
$ stat <ALT+.> -> stat ~/old_bashrc
File: /home/jaehoyoon/old_bashrc
Size: 3771 Blocks: 8 IO Block: 4096 일반 파일
Device: 801h/2049d Inode: 2228798 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-22 14:14:22.880796911 +0900
Modify: 2022-02-22 14:14:22.880796911 +0900
Change: 2022-02-22 14:14:22.880796911 +0900
$ mv ~/old_bashrc ~/old_bashrc2
$ stat ~/old_bashrc2
File: /home/jaehoyoon/old_bashrc2
Size: 3771 Blocks: 8 IO Block: 4096 일반 파일
Device: 801h/2049d Inode: 2228798 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-22 14:14:22.880796911 +0900
Modify: 2022-02-22 14:14:22.880796911 +0900
Change: 2022-02-22 14:15:36.803985016 +0900
이렇게 했을 때
cp를 하게 되면 전체가 바뀌고, mv는 ctime만 변경되는 것을 볼 수 있다.
touch
파일이 존재할 경우 메타 정보를 업데이트하고, 없을 경우 빈 파일을 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ touch emptyfile
$ stat emptyfile
File: emptyfile
Size: 0 Blocks: 0 IO Block: 4096 일반 빈 파일
Device: 801h/2049d Inode: 2228800 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-22 14:20:45.939490334 +0900
Modify: 2022-02-22 14:20:45.939490334 +0900
Change: 2022-02-22 14:20:45.939490334 +0900
Birth: -
$ touch emptyfile
$ stat emptyfile
File: emptyfile
Size: 0 Blocks: 0 IO Block: 4096 일반 빈 파일
Device: 801h/2049d Inode: 2228800 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-22 14:20:56.535844324 +0900
Modify: 2022-02-22 14:20:56.535844324 +0900
Change: 2022-02-22 14:20:56.535844324 +0900
Birth: -
find
파일을 조건에 맞게 검색하고, 검색 후 작업을 할 수도 있다. size에 정확한 n을 찾는 경우 n, n보다 큰 것은 +n, 작은 것은 -n으로 실행한다. name에는 *와 같은 와일드카드를 사용할 수 있다. maxdepth를 사용하려면 모든 조건 맨 앞에 와야 한다.
find 검색 조건으로는
- -name filename : filename의 이름과 같은 파일을 검색
- -size n : 크기가 n인 파일을 검색
- -mtime n : 변경된 시간이 n인 파일을 검색 (단위는 day)
- -mmin n : 변경된 시간이 n인 파일을 검색 (단위는 minute)
- -inum n : inode number가 n인 파일을 검색
- -samefile file : file과 같은 inode를 가진 파일을 검색 (= 같은 하드링크를 검색)
- -maxdepth level : 탐색할 위치의 하위디렉토리 최대 깊이가 level인 파일을 검색
- -mindepth level : 탐색할 위치의 하위디렉토리 최소 깊이가 level인 파일을 검색
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ mkdir ~/tmpp; cd !$
$ for i in {8..21}; do dd bs=100000 count = $i if=/dev/zero of =./${i}00k.dat; done
1.
$ find . -name '[89]*k.dat
2.
$ find . -name ‘*k.dat’ -a -size 1M
3.
$ find . -name ‘*k.dat’ -a -size +1500k -size -1800k
./1600k.dat
./1700k.dat
./1800k.dat
‘[89]*k.dat’: .은 기준 디렉토리, -name은 조건에서 [89]는 8또는 9가 들어가는 마지막이 k인 .dat들을 검색한다.
-a는 AND(생략 가능), -o는 OR 이다. 사이즈는 단위가 M단위이므로 0~1M에 걸쳐지는 것들을 검색한다.
여기서 주의해야 할 것들은 와일드카드를 사용하면 꼭 ‘’나 “”를 사용해줘야 한다.
작업 지시 (-exec 명령어)
- find … -exec 명령어 \; = 매번 찾을때마다 실행
- find … -exec 명령어 + = 다 구한 다음 실행
파일이 a.tmp,b.tmp,c.tmp가 있다고 가정할 때
- find … rm {} \;를 하면 rm a.tmp rm b.tmp rm c.tmp
- +를 하면 rm a.tmp b.tmp c.tmp
파일 크기가 많으면 +가 더 빠르고 효율적이다. 그러나 수십만 개라 하면 +가 에러가 난다.
실습
- 현재 디렉토리 아래에서 최근 24시간 이내의 일반 파일을 찾아 mtime_b24.txt로 저장
- 현재 디렉토리에서 3단계 아래를 넘어가는 경우는 검색하지 않고, 조건에 만족하는 것들을 ~/backup 디렉토리에 복사
1
2
3
4
5
6
7
8
9
10
11
$ find ./ -mtime -1 -type f > mtime_b24.txt
$ find ./ -maxdepth 3 -mtime -1 -type f -exec cp {} ~/backup \\;
$ stat ~/backup
File: /home/jaehoyoon/backup
Size: 1500000 Blocks: 2936 IO Block: 4096 일반 파일
Device: 801h/2049d Inode: 2228820 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/jaehoyoon) Gid: ( 1000/jaehoyoon)
Access: 2022-02-22 14:49:32.418745318 +0900
Modify: 2022-02-22 14:49:19.940008219 +0900
Change: 2022-02-22 14:49:19.940008219 +0900
Birth: -
stdio
표준 입출력에 대한 명령어이다.
file channel: file에 입출력하기 위한 통로
- file channel에 입출력하기 위해 하드웨어를 직접 접근하지 않고, 표준화된 입출력 방식을 통하도록 하는 가상화 레이어의 일종
파일채널은 파일에 입출력하기 위한 메타 정보를 가지는 객체이므로 프로세스 종료시 정보 증발한다. 파일 채널을 지칭할 때 파일 서술자(file descriptor = fd)라는 유일한 식별자가 존재한다. 0번부터 시작하고, 0은 stdin(표준 입력), 1은 stdout(표준출력), stderr(표준에러) -> 0은 입력방향, 1,2는 출력방향에 해당한다.
find 명령의 출력 (stdout)이 wc 명령의 입력(stdin)과 연결하는 것으로 find ~의 출력이 wc -l의 입력으로 들어간다.
1
2
3
4
$ find ~ | wc -l
174
-> 이를 | 안쓰고 하게 되면
$ find ~ > tmp.txt;wc -l < tmp.txt; rm tmp.txt
find ~ 는 홈 디렉토리, 즉 홈 디렉토리를 다 찾아서 wc(word count) -l는 line 수를 카운트한다.
pipe
PIPE: 프로세스 사이에 통신으로 사용, IPC(inter process communication)의 일종
파이프의 종류
- annoymous pipe(익명) - temporary 프로세스 종료하면 사라짐
- named pipe - persistency 프로세스 종료해도 남아있음
- annoymous pipe
- 임시로 생성되었다가 소멸되는 파이프
- 프로세스들의 직렬 연결
명령행에서 로 사용 e.g. A B C A,B,C를 직렬로 연결해서 A의 출력이 B의 입력으로 연결,, - 줄여서 파이프라고도 많이 함
- named pipe
- 유닉스에서는 FIFO pipe라고 부른다.
- path를 가지는 것을 명명되었다고 표현
- mkfifo 명령을 사용해서 생성
redirection
방향 다른 곳으로 연결한다는 것으로 출력을 입력으로 넣거나 할 때 사용한다.
- A > B: A의 stdout을 파일 B로 연결
e.g. ls > filelist1.txt
e.g. strace ls 2> strace.txt
-> 2>는 2번 파일서술자(stderr)를 파일로 연결
- A < B: A의 stdin을 파일 B로 연결
e.g. sort < names.txt
- A >> B: 방향은 >과 같고, 추가하는 모드
cat
stdout와 파일을 자유롭게 연결해주는 기본 필터이다.
가장 자주 쓰이는 쓰임새는
- 파일의 내용을 stdout으로 출력
- stdin의 입력을 redirection해서 파일로 출력 → 타이핑 치고 ctrl + D 치면 저장
1
2
$ cat ~/.bashrc
$ cat $? > hello.txt
archive
아카이브는 보관용 묶음, compress는 압축이다.
UNIX계열은 여러 파일을 묶는 작업과 압축이 분리이 존재한다.
- 아카이브 유틸: tar, cpio
- 압축 유틸: gzip, bzip2, zstd(속도), xz(압축율)
tar
tar [ctxv] [f archive-file] files...
- c: create
- t: test
- x: extract
- v: verbose ( 거의 안씀 )
- f archive-file: 입출력할 아카이브 파일명
- —exclude file: 대상 중 file을 제외 (특정 파일을 제외할 때 사용)
1
$ tar cf arc_c.tar *.c
f옵션을 주어 *.c의 출력이 arc_c.tar에 저장한다는 것이다.
compress
xz, zstd를 많이 쓴다.
xz
xz [-cdflrv] <file ...>
- d: 압축해제
- c: stdout 표준 출력으로 결과물 보냄
- 1,-9: fast, better 등의 압축 레벨
실습
e.g. 압축 → 해제
1
2
$ tar c /etc/*.conf | xz -c > etc.tar.gz
$ xz -cd etc.tar.gz | tar x
zstd
zstd [options] [-|input-file] [-o output-file]
options - #: 압축 레벨 설정 1-19 [ default:3]
- tar, gzip 사용 예제 (정통파 방법)
1
2
3
4
5
$ mkdir ~/tmp
$ cd !$
$ cp -rf /etc .
$ tar c . | gzip -c > bak_etc.tar.gz
tar → . 디렉토리 즉, 현재 디렉토리에 전부를 묶어서 생성(c)
한 결과를 gzip → 표준출력으로 결과물을 보냄
보낸 결과를 bak_etc.tar.gz로 압축
이 정통파 방법이 중요한 이유는 요즘 방법을 사용할 때는 멀티쓰레드를 쓰지 못하여 정통파 방법을 통해 멀티쓰레드를 사용해야 하기 때문이다.
- 최근 방법
GNU tar 방법이라 해서 tar cfa 에서 a를 붙이게 되면 알아서 뒤의 확장자를 보고 판단한다. 대신 멀티 쓰레드를 못쓴다.
1
2
3
4
5
$ tar cfa bak_data.tar.xz ./data ./exp
$ tar cfa bak_data.tar.zst ./data ./exp
멀티 쓰레드 사용
$ tar c ./data ./exp | zstd -T0 > bak_data.tar.zst
위는 ./exp의 결과를 ./data의 폴더에 bak_data이름으로 압축하는 코드다.
압축을 풀 때는
1
2
3
4
5
$ tar xfa bak_data.tar.xz
$ tar xfa bak_data.tar.zst
멀티 쓰레드 사용
$ zstd -dcT0 bak_data.tar.zst | tar x
실습
1
2
3
4
5
$ git clone [https://github.com/htop-dev/htop](https://github.com/htop-dev/htop)
htop 디렉토리를
$ htop.tar.gz , htop.tar.xz, htop.tar.zst로 3회씩 압축 ( tar cfa htop.tar.zst htop)
$ 압축에 걸린 시간과 압축률 계산 ( 맨 앞에 time)
link
file 관련 명령어이다.
ln 명령어를 사용하고, 하드 링크와 심볼릭 링크로 나뉜다
- 하드 링크
- 심볼릭 링크: 축약시 symlink라고도 함 ( -s 옵션)
i-node
i-node: 파일의 메타정보 및 관리용 객체
- 파일은 고유의 i-node를 1개 가진다.
- i-node는 disk partition내에서 유일한 식별자
- i-num이라고도 함
- 같은 파티션내에서의 식별자
hard link
- 동일 파티션내에서만 생성 가능
- 일반 파일만 가능 → 일반 파일이 아닌 디렉토리 등은 하드링크를 생성할 수 없다.
- 실체를 가진 파일
symlink
- 위치만 가리키므로 다른 파티션, 모든 종류의 file에 만들 수 있다.
- 가르키는 대상의 UNIX file mode를 따라가므로 symlink의 권한은 777이며 의미는 없다.
하드 링크 생성 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ mkdir -p ~/work/testdir
$ chmod 775 ~/work/testdir
$ cd !$
$ touch hello.txt
$ ls -li
2228823 -rw-rw-r-- 1 jaehoyoon jaehoyoon 12 2월 22 15:59 hello.txt
1개 상위의 디렉토리에 하드링크 생성
$ ln hello.txt ../hardlink.txt
$ ls -li
2228823 -rw-rw-r-- 2 jaehoyoon jaehoyoon 12 2월 22 15:59 hello.txt
$ ls -li ..
2228823 -rw-rw-r-- 2 jaehoyoon jaehoyoon 12 2월 22 15:59 hardlink.txt
2228822 drwxrwxr-x 2 jaehoyoon jaehoyoon 4096 2월 22 15:59 testdir
$ ln -s ../hardlink.txt symlink.txt
$ ls -l
-rw-rw-r-- 2 jaehoyoon jaehoyoon 12 2월 22 15:59 hello.txt
lrwxrwxrwx 1 jaehoyoon jaehoyoon 15 2월 22 16:04 symlink.txt -> ../hardlink.txt
$ ls -li
2228824 lrwxrwxrwx 1 jaehoyoon jaehoyoon 15 2월 22 16:04 symlink.txt -> ../hardlink.txt
여기서 중요한 것은
- 링크의 수가 증가했다는 것. 왜냐하면 같은 파일즉, 2228823이라는 i-node를 가르키는 링크가 2개가 되었기 때문이다.
- symlink를 생성할 경우 링크의 개수는 증가하지 않지만, 경로를 나타내어 줌, symlink이므로 l로 시작
symlink는 만들 디렉토리로 가서 생성을 해야 한다. 그렇지 않다면 옵션을 추가해야 하지만, 그냥 단순하게 해당 디렉토리로 가서 생성하는 것이 좋다.
which
파일의 path를 검색
1
2
$ which find
/usr/bin/find
readlink
symlink가 여러 단계를 가리키는 파일이 있을 수 있다. 즉 A → B → C라고 하면 누가 마지막인지 애매해진다.
그래서 symlink의 canonical path를 따라가는 기능이 있다.
- f 옵션은 마지막 링크를 제외한 모든 링크가 존재할 때 성공
- e 옵션은 모든 링크가 존재할 때 성공
실습
- sym3 → sym2 → sym1 → hardlink형태를 만들자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ dir
hello.txt
$ ln -s hello.txt sym1
$ ln -s sym1 sym2
$ ln -s sym{2,3}
$ ls -l sym* hello.txt
-rw-rw-r-- 2 jaehoyoon jaehoyoon 12 2월 22 15:59 hello.txt
lrwxrwxrwx 1 jaehoyoon jaehoyoon 9 2월 22 16:23 sym1 -> hello.txt
lrwxrwxrwx 1 jaehoyoon jaehoyoon 4 2월 22 16:23 sym2 -> sym1
lrwxrwxrwx 1 jaehoyoon jaehoyoon 4 2월 22 16:23 sym3 -> sym2
$ readlink -e sym2
/home/jaehoyoon/work/testdir/hello.txt
$ readlink -f sym2
/home/jaehoyoon/work/testdir/hello.txt
$ rm -rf hello.txt
$ readlink -f sym3
/home/jaehoyoon/work/testdir/hello.txt
$ readlink -e sym3
-e는 마지막까지 포함, -f는 전까지
- readlink사용해보기
1
2
3
4
5
6
7
8
9
10
11
$ which locate
/usr/bin/locate
$ ls -l /usr/bin/locate
lrwxrwxrwx 1 root root 24 2월 21 15:12 /usr/bin/locate -> /etc/alternatives/locate
$ ls -l /etc/alternatives/locate
lrwxrwxrwx 1 root root 16 2월 21 15:11 /etc/alternatives/locate -> /usr/bin/mlocate
$ ls -l /usr/bin/mlocate
-rwxr-sr-x 1 root mlocate 43088 3월 2 2018 /usr/bin/mlocate
$ readlink -e /usr/bin/locate
/usr/bin/mlocate
ls -l 로 계속 symlink를 따라가기는 힘들다. 이를 readlink하나로 해결가능
symlink를 사용하는 예
- 음악 스트리밍
- 음악 파일은 음반별로 저장된다.
- 추천 100 음악을 /exp/malon/rec100/에 1.mp3 ~ 100.mp3로 만들어야 하는데 매일 복사하는 것은 너무 비효율적이다.
- hot 100에 해당하는 symlink를 생성하게 되면 원래 파일의 경로를 symlink를 통해 rec100에 담는다.
1
$ ln -s /exp/disc/chet_atkins_1/02.sails.mp3 /exp/malon/rec100/2.mp3
- 음악 파일은 음반별로 저장된다.
- library 버전 관리
- 기존 라이브러리의 실제 파일은 libflamegraph.so.0.4.5가 있다.
- 라이브러리 업그레이드로 0.5.0이 설치된다면 최신 버전을 가르키기 위해 기존 라이브러리를 제거하는 것보다 symlink가 가르키는 canonical path만 변경하면 된다.
1
$ ln -s /usr/lib/libflamegraph.so.0.5.0 /usr/lib/libflamegraph.so
- 실제로 ls -/usr/lib을 보면 관찰할 수 있다.
1 2
$ ls -l /usr/lib/python3.6 lrwxrwxrwx 1 root root 31 2월 21 15:12 [sitecustomize.py](<http://sitecustomize.py/>) -> /etc/python3.6/sitecustomize.py
process 관련 명령어
ps
현재 세션의 프로세스를 보여준다.
- PID: 프로세스 ID
- TTY: 터미널 ID
- TIME: CPU 시간(누적 시간) = CPU를 점유했던 시간의 누적값, 즉 CPU를 사용한 시간
현실 시간에 대한 건 ETIME이란 다른 항목이 있다.
- CMD: command = 프로세스 이름 (argv[0]를 의미
옵션
- -e: 전체를 다 보여줌
- -a: 터미널과 연결되어 있는 프로세스 및 세션 리더
- -f: full format → UID, PID, PPID, C, STIME, TTY, TIME
- UID: 해당 프로세스의 소유권자, 숫자인 경우 UID, 심볼인 경우 Isername
- PPID: 부모 프로세스 ID(parent PID)
- C: CPU 사용량
- STIME: 프로세스 시작한 시간 (시 : 분) - 현실 시간
- -l: long format → F,S,PRI,NI,SZ,C
- F: 프로세스 플래그
- S: 상태 코드 (State code)
- PRI: 실시간 우선 순위
- NI: 나이스 우선 순위
- SZ: 사용되는 프로세스 코어 이미지의 메모리 크기
- C
여기서 가장 많이 사용되는 방법은 -ef, -el, -ej 즉, 전체(e)를 full format, 전체(e)를 long format…
1
2
3
$ ps -ef | grep bash
jaehoyo+ 1984 1974 0 13:30 pts/0 00:00:00 bash
jaehoyo+ 2830 1984 0 17:14 pts/0 00:00:00 grep --color=auto bash
bash 단어가 들어간 행만 뽑아준다.
process control
kill
kill이라는 명령어가 있다. 이는 프로세스에 시그널을 보내는 기능
$ kill -l
을 하면 시그널 리스트 확인 가능하다.
대표적이어서 외워야 하는 것들 (sig는 시그널, 뒤의 단어가 의미)
- SIGHUP: hang up - 연결이 끊겼을 때(로그아웃 등)
- SIGINT: interrupt, <ctrl +c> - 프로그램을 죽이는 것, 일반적으로 프로그램을 죽일 때
- 작동: SIGINT를 받는 프로세스가 프로세스 그룹 리더라면 프로세스 그룹에 속한 모든 프로세스에게 시그널이 전파되고, 자식 프로세스도 전부 종료
- SIGQUIT: QUIT, <ctrl + \> - 프로그램을 죽이는 것, 일반적이지 않은 프로그램이 이상할 때, 메모리를 덮을 때 사용
- 작동: SIGINT와 같으나 core가 생성됨 → 프로그래머를 위한 기능
- 동일하게 프로세스 그룹 리더에게 전달되면 다 전파됨
- SIGKILL: kill, 강제로 죽이는 기능, 강제이기에 파일이 깨질 수 있음, 거의 최후의 수단으로 사용
- SIGSEGV: segment violation, 이상 작동해서 메모리 침범으로 죽었을 때
- SIGTERM: terminate, 죽이기 요청, 상태가 이상하면 요청을 거부하기에 kill로 함
- SIGTSTP: terporary stop, <ctrl+z>, 잠깐 정지
명령어 | 설명 |
---|---|
kill 13011 | PID 13011 프로세스에 SIGTERM(default) 시그널 보냄 |
kill -QUIT 13013 | PID 13013 프로세스에 SIGQUIT 시그널 보냄 |
kill -9 13012 | PID 13012 프로세스에 9번 시그널인 SIGKILL 보냄 |
실습
터미널 2개로 1번에는 less ~/.bashrc
, 2번에는 ps -e | grep less
하여 PID확인 후 kill <PID number>
job control
foreground / background process
- foreground process: 현재 session에서 제어 터미널을 가진 프로세스
- background process: 현재 session에서 제어 터미널을 잃어버린(소유하지 않은) 프로세스
- CTRL+Z
- foreground프로세스가 sigtstp 시그널을 전달받음
- 작동 → 잠시 정지시킴 = 결과적으로 background에 stop상태로 내려가게 됨
session
세션은 멀티유저 시스템에서 통신 객체를 구별하기 위해 사용된다. 세션은 제어 터미널을 가질 수 있다. 세션에도 ID를 받는데, SID == PID인 프로세스를 Session Leader라고 부른다.
특징
- 세션안에서도 여러 그룹을 만들 수 있다.
- GID == PID인 프로세스를 프로세스 그룹 리더라고 한다.
- 세션 리더로부터 파생된 자식 프로세스는 모두 같은 세션을 가진다.
- logout시 세션이 파괴되면서 세션에 속한 프로세스들은 모두 종료된다.
controlling terminal
제어터미널은 사용자의 제어를 받는 터미널 장치 e.g. 키보드 입력을 받아 작동
- CUI에서 멀티 태스킹을 위한 제어 방법
- 제어터미널을 소유한 프로세스는 키보드 입력을 가진다.
- 이런 프로세스를 foreground process라고 부른다.
- 하나의 세션에서 foregorund process는 최대 1개까지 가질 수 있다.
- 제어 터미널 규격
- ps 명령어 출력에서 TTY 필드 부분에 2가지 방식으로 출력이 된다.
- pts/# : UNIX98
- tty# : control terminal
- ps 명령어 출력에서 TTY 필드 부분에 2가지 방식으로 출력이 된다.
- 세션에서 제어 터미널을 가지지 않는 경우(서버 시스템, 즉 키보드 입력이 안되는 경우)에는 ps의 tty필드에 ?로 나타난다.
process group
프로세스 그룹 리더: ProcessGroup ID == PID
프로세스 그룹에 시그널을 보낼 수도 있는데, PID가 음수면 그룹 ID라고 보면 된다.
daemon 프로세스란?
- orphan process and session leader
- stdio를 모두 /dev/null로 리다이렉션을 걸고
- 제어 터미널을 가지지 않는 프로세스 ⇒ tty필드에 ? 즉, background에 시스템 관련 작업을 하는 프로세스를 가르킴
실습
jobs : stoped, background process의 리스트 출력
- fg %#
- #에는 jobs의 작업 번호
- %는 생략 가능
- 지정한 프로세스를 foreground로 가져옴
- bg %#
- 정지된 백그라운드 프로세스를 running 상태로 변경
실행 - job control
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
$ vi
^Z
[1]+ 정지됨 vi
$ vi hello.c
^Z
[2]+ 정지됨 vi hello.c
$ cat > printdate.sh
#!/bin/bash
while : ;
do
date && sleep 1
done
^D
$ bash printdate.sh
2022. 02. 22. (화) 18:05:26 KST
2022. 02. 22. (화) 18:05:27 KST
2022. 02. 22. (화) 18:05:28 KST
2022. 02. 22. (화) 18:05:29 KST
2022. 02. 22. (화) 18:05:30 KST
2022. 02. 22. (화) 18:05:31 KST
2022. 02. 22. (화) 18:05:32 KST
2022. 02. 22. (화) 18:05:33 KST
2022. 02. 22. (화) 18:05:34 KST
2022. 02. 22. (화) 18:05:35 KST
2022. 02. 22. (화) 18:05:36 KST
2022. 02. 22. (화) 18:05:37 KST
^Z
[3]+ 정지됨 bash printdate.sh
$ jobs
[1] 정지됨 vi
[2]- 정지됨 vi hello.c
[3]+ 정지됨 bash printdate.sh
이 때 +는 foreground, -는 background
$ fg %2
2번 작업을 포그라운드로 불러옴
^Z
vi hello.c
[2]+ 정지됨 vi hello.c
$ jobs
[1] 정지됨 vi
[2]+ 정지됨 vi hello.c
[3]- 정지됨 bash printdate.sh
$ bg %3
3번 작업을 background에서 running 상태로 변경시키는 것이므로 ctrl+c를 눌러도 명령이 멈추지 않음
이는 background에서 작동하면 제어터미널을 잃기 때문에, 현재 제어터미널은 셀이 가지고 있어서 ctrl+c는 셸로 전달된다. 즉 현재 foreground process는 셸
이를 죽이는 방법은 fg%3을 통해 불러와서 ctrl+c를 누르든 시그널을 보내서 직접 죽이던 해야 함