/* 테스트 1 버전 - 성능 최적화 적용 */ 마무: 리눅스

블로그 소개


*여러분들의 따듯한 댓글은 5%, 팔로우는 10% 블로그 포스팅 속도와 퀄리티를 높여줍니다.*

프로필

팔로우 해주시면 포스트할 때 큰 힘이 됩니다!!! 사실 저도 이 팔로우가 무슨 기능이 있는지는 모르겠습니다만, 팔로우 수가 늘면 '날 응원해주는 사람들이 있구나' 생각이 들어서 큰 힘이 됩니다.

팔로어

다른 페이지로 이동


리눅스 독학 페이지 운영체제 독학 페이지 네트워크 독학 페이지 시스템 해킹 하드웨어 독학 페이지 프로그래밍 독학 페이지 보안 페이지

오스 페이지 다이어트 정보 페이지 게임 정보 페이지 인생 꿀팁


****사진을 클릭하시면 페이지로 이동할 수 있습니다!****

<===***===↓↓↓You can use translate using chrome ↓↓↓===***===>

레이블이 리눅스인 게시물을 표시합니다. 모든 게시물 표시
레이블이 리눅스인 게시물을 표시합니다. 모든 게시물 표시

2021년 7월 30일 금요일

리눅스 /etc/rc.d/ 매우 자세히!

안녕하세요~ 마무입니다. 오늘은 'init 런레벨 파일', '리눅스 init 부팅 과정', 'init 런레벨 디렉토리', '리눅스 /etc/rc.d/' 등등에 대해서 매우 자세히 포스트해보겠습니다.

오늘 이 포스트를 다 읽으시면, 레드햇 6.9이하의 'sysV init을 사용하는 시스템'에 대한 자연스러운 이해를 하게 되실 것이며, 모든 의문이 풀리실 겁니다!


/***알고 있어야 하는 사전 지식***/

최초의 프로세스란, 부모, 자식 프로세스란, sysVinit(init)과 systemd 차이와 상세한 비교

런레벨이란?(0, 1, 2, 3, 4, 5, 6)

/***********************************/


-----목차-----

1. Centos init시스템 부팅과정

2. /etc/rc.d/rc.sysinit

3. /etc/inittab

4. /etc/rc.d/init.d/functions

5. /etc/rc.d/init.d와 /etc/rc.d/rc0~6

6. /etc/rc.d/rc.local

7. /etc/rc.d/rc란

8. 총 정리
---------------

여기서 못 찾은 정보는 

리눅스 독학 포스트 : https://mamu2830.blogspot.com/p/blog-page_13.html

운영체제 독학 포스트 : https://mamu2830.blogspot.com/p/blog-page_14.html

에 있을 수 있습니다!




1. Centos init시스템 부팅과정


'init 프로세스'를 사용하는 6.9이하의 레드햇(CentOS)에서의 'init 프로세스의 총 과정'을 쭈욱 먼저 나열해 전체적인 흐름을 보인 다음에, 이후 하나하나 자세하게 설명을 해드리는 방식을 취하겠습니다!

그러니 여기서 모르는 단어가 나와도, 그런가보다 하고 일단 살짝 읽고 넘어가주세요~

1. 'init'이 "/etc/rc.d/rc.sysinit(run commands.system initialization)"파일을 실행하여 파일 이름대로(system initialization) 시스템 초기화를 합니다.

2. 이후 'init'이 "/etc/inittab" 파일에 써져있는 '런레벨(runlevel)'을 읽어들입니다.

3. 'init'이 다른 데몬들이 공통적으로 사용하는 라이브러리 소스코드인 '/etc/rc.d/init.d/functions'라는 파일을 설정합니다. 이 과정을 통해 '/etc/rc.d/init.d/내부의 데몬'들이 이 'functions'파일을 불러들여, PID를 어떻게 결정하고, 시작하고, 종료할지를 설정합니다.

4. 아까 '/etc/inittab'에서 읽어온 '런레벨'에 따라 "/etc/rc.d/rc[runlevel].d" 디렉토리에 있는 S가 붙은 링크 파일들을 실행하고 K가 붙은 링크 파일들은 종료합니다. 

5. 만약 런레벨을 바꿀시 'init'은 "/etc/rc.d/rc"파일을 실행합니다.

6. 모든 'init'과정이 끝나고 'init'은 "/etc/rc.d/rc.local"파일을 실행해 추가적으로 실행하고 싶은 코드를 마지막에 수행합니다.

7. 런레벨 과정이 끝나고, 런레벨이 2~5중 하나면, '/sbin/mingetty'프로세스를 만들어 가상콘솔을 6개 엽니다.(터미널 포스트에서 다루겠습니다)

8. 런레벨이 5(GUI)라면 '/etc/X11/prefdm' 스크립트를 실행하고, 'prefdm'스크립트는 그래픽 화면인 즉 X 디스플레이어 매니저를 실행합니다.(X 윈도 포스트에서 다루겠습니다)




2. /etc/rc.d/rc.sysinit 


제일 먼저 'init'이 실행하는 이 "/etc/rc.d/rc.sysinit"이란 "run commands system initialization"의 줄임말로, system initialization(시스템 초기화)에 사용하는 run commands(실행 명령어들)이 들어있는 파일입니다.




이렇게 /etc/rc.d/로 이동하신 다음  "ll(ls -l)"로 보시면, 이 'rc.sysinit'파일'x'권한이 있는 쉘 스크립트 파일인 걸 알 수 있는데요, vi(vim)을 이용해 열어보시면



이렇게 '/bin/bash'를 이용한 쉘 스크립트가 써져 있는 것을 볼 수 있습니다. 

내용은, /bin/hostname에서 호스트 이름을 가져오고, 호스트이름에 값이 없을 경우 'localhost'를 넣고, /etc/sysconfig/network 파일을 실행하고, /proc/mounts가 없을 경우 proc와 sysfs를 마운트 하는 등, 말 그대로 시스템 초기화 코드가 적혀있는 것을 볼 수 있습니다.

사실 이 부분은 쉘 스크립트를 배우신 분들이라면 읽는게 그리 어렵진 않겠지만, 모를 경우 이해가 안되는건 당연합니다. 그러니 나중에 이 부분은 쉘 스크립트를 가르치는 포스트에서 다시 다루도록 하겠습니다.

그 외에도 내리다 보시면



SELinux 상태 체크,



하드웨어 초기화 등등 말 그대로 설정 파일들 체크 및 시스템 초기화를 위한 스크립트들이 적혀있는 것을 볼 수 있습니다.

응용프로그램(애플리케이션)을 실행하기에 앞서 당연히 시스템(환경)부터 초기화 하는 건 당연한 것이기 때문에, 이처럼 'init'은 데몬들을 실행하기전에, "/etc/rc.d/rc.sysinit"제일 먼저 실행하는 것입니다.

'init'이 "/etc/rc.d/rc.sysinit"을 실행해 시스템을 초기화(안정화)시켰다면, 본격적으로 프로세스들을 실행하면 됩니다만, 그 전에 "/etc/inittab"이란 파일을 통해 '런레벨(run level)'을 확인합니다.




3.  /etc/inittab 


'inittab(initialization table)'이란, 말 그대로 초기화를 할 때(initialization) 참고하는 테이블(table)입니다.

바로 이 파일에 위에서 배웠던, 원하는 런레벨을 쓰면, 시스템이 켜질 때 설정해놓은 런레벨대로 자동으로 부팅이 됩니다.

사실 이 '/etc/inittab'파일은 유닉스나 다른 리눅스 종류에선  부팅 때 실행하는 초기화 테이블이라는 이름대로, 원래 런레벨 외에도 특정 터미널에 실행되길 원하는 프로세스와 행위를 적는 파일이기도 했습니다만!

지금 제가 사용중인 레드햇 리눅스 6버전에선 맨 위 주석에 써져있는 것처럼, 디폴트 런레벨 설정으로만 쓰입니다. (디폴트 런레벨 설정외 다른 용도로 사용하는 버전도 있을 수 있습니다.)

백문이 불여일견, 한번 직접 파일을 보면서 말해보겠습니다.



맨 위에서부터 친절하게 주석을 통해 이 파일이 무엇인지, 무엇을 해도 되지만, 무엇을 하면 안되는지 적혀있습니다. 한번쯤은 읽어보고 넘어가도록 할게요!

# inittab은 오직 시스템 시작 때 디폴트 런레벨을 위해서만 사용이 됩니다.

# 이 파일에 다른 시스템 설정을 추가해도, 당신의 시스템에는 영향이 가지 않습니다.

# 시스템 초기화는 /etc/init/rcS.conf에 의해서 시작이 되며

# 개인 런레벨들은 /etc/init/rc.conf에 의해 시작이 됩니다.

# Ctrl-Alt-Delete 는 /etc/init/control-alt-delete.conf 에 의해서 다뤄집니다.(ctrl + alt + delete를 누르면 60초 내 자동으로 시스템을 종료하겠다는 창이 뜸)

# 터미널 gettys(터미널을 관리하는 유닉스 프로그램)들은 /etc/init/tty.conf,  /etc/init/serial.conf 그리고 /etc/sysconfig/init와 함께 다뤄집니다.

# 어떻게 시스템 시작 이벤트 핸들러들을 적는지나 어떻게 시스템 시작이 작동하는지의 정보는 man page init(5), init(8), initctl(8)을 보세요.

# 디폴트 런레벨. 이 런레벨들은 이렇게 사용됩니다:
#    0 - 정지(이걸 디폴트 런레벨로 사용하지 마시오)
#    1 - 싱글 유저 모드
#    2 - NFS 없이 사용하는 멀티유저(만약 당신이 네트워크를 사용하지 않으면 3과 똑같다)
#    3 - 풀 멀티유저 모드
#    4 - 사용하지 않음
#    5 - X11(유닉스의 GUI 환경)
#    6 - 재부팅(이걸 디폴트 런레벨로 사용하지 마시오)
 
이렇게 적혀있습니다~ 영어를 못하셔도 한번쯤은 읽어야 뭔가 안심이 되니까! 한번은 꼭 읽고 넘어갑시다~

자 그리고 이 설명들 밑에 



이렇게 적혀있는데요. 

그냥 런레벨만 적는게 아니라, 'id''initdefault'니 등 콜론(:)으로 구분이 돼 있는걸 볼 수 있는데요. 

이건 과거 여러 갈래 유닉스에서(솔라리니, BSD 등등)나 다른 리눅스 버전에서 사용되오던 기능과 그 때 사용하는 필드로, 이제는 굳이 알 필요가 없을 것 같습니다.(현재 저처럼 6.9이하 에선 디폴트 런레벨용으로만 사용하며, systemd에선 사용을 안하기에)

그래도 저와 같이 궁금한거 못참는 분들이 있을까봐! 살짝 언급을 하자면

/***굳이 알 필요 없는 TMI ***/

'첫 번째' 필드인 'id' 위치엔 원래 터미널번호를 쓰며 ex) tty1인 경우 '1' 
이렇게 씁니다.

그 다음 '두 번째' 필드는 저희가 알 듯이 런레벨 숫자를 적으며

다음 '세 번째' 필드는 미리 정의된 행동을 적는 곳으로, 위에선 'initdefault'는 이름 그대로 '디폴트 런레벨'을 말하며, 그 외에도 뭐 'respawn, wait, once, boot...'등등 많습니다.

마지막 '네 번째' 필드는 세 번째 필드에서 정의한 행위를 적용할 파일(프로세스)를 적는 곳입니다. 

그래서 이러한 설정을 통해 가상터미널(ctrl + alt 2~6)을 만드는 버전도 있습니다.

/***굳이 알 필요 없는 TMI ***/

그냥 사실 위에 적은 정보는 무시해도 되고, 저희는 그냥 '두 번째' 필드인 런레벨만 알면 됩니다.

예를 들어, 두 번째 필드에 '5'대신 '3'을 적으면 다음부터 시스템이 켜질 때 CLI 환경으로 켜지는 겁니다.

좀 TMI를 적어서 복잡했던거지, 그리 어렵진 않죠?





4. /etc/rc.d/init.d/functions



'/etc/inittab'을 통해 '런레벨'을 인식을 한 뒤에, 이제 'init'은 런레벨에 맞는 프로세스들을 만들어내야합니다만, 당연히 프로세스를 어떻게 만들지를 정해야할지 않습니까?

바로 그 때! 즉, 'init'이 데몬을 만들 때, 어떻게 PID를 결정할지, 프로세스를 시작할지, 종료할지정할 때 사용하는 공통 스크립트가 있으니.. 그것이 바로! 

'/etc/rc.d/init.d/functions'라는 파일입니다!



바로 위 'functions'라는 일반파일을 'vim'을 통해 열어보시면


맨 위 주석으로 

# functnions  이 파일은 /etc/init.d/ 디렉토리에 들어있는 모든 혹은 대부분의 쉘 스크립트가 사용하는 함수들을 포함하고 있습니다.

라고 적혀있죠? 말 그대로 거의 모든 '/etc/init.d/내부에 들어있는 데몬이 될 스크립트'를 보
functions 내부에 적혀있는 함수들을 불러와, 기본적인 데몬 생성 및 관리에 필요한 코드를(umask, PATH, PID, 프로세스 종료 등등) 사용하는 것을 볼 수 있습니다.

아직 서버프로그램을 많이 알지 못하실 것이라, 대부분 아실 'sshd(ssh)' 스크립트를 예를 들어 보겠습니다.



이렇게 /etc/rc.d/init.d/에 들어있는 sshd 스크립트를 읽어보시면, '/etc/rc.d/init.d/functions'현재 스크립트 "sshd"로 불러오는 것을 볼 수 있습니다.

이렇듯 대부분의 데몬이 공통적인 PID관리에 필요한 코드를'functions'라는 파일을 불러와 처리한다는 것이죠.

'/etc/rc.d/init.d/functions'라는 파일에 적혀있는 쉘 스크립트를 모두 다 해석하는건... 여러분들이 쉘 스크립트도 모르고, 너무나 방대하기에... 나중에 쉘 스크립트를 가르키는 포스트나 PID관련 포스트에서 집중적으로 다루도록 하겠습니다.

그래도 궁금하실 분들이 있을까봐 '/etc/rc.d/init.d/functions'코드를 살짝 보여드리자면



이렇게 /proc/내부에 실행되고 있는 pid가 있는지 체크하는 코드나



kill_list라는 로컬변수에 담긴 체크된 PID들을 "kill -TERM"으로 종료하듯, pid를 종료하는 코드나



이렇게 데몬을 실행하기 위한 함수등등이 담겨있습니다.

이렇듯, '/etc/rc.d/init.d/functions'파일은 데몬들이 자신들의 개인 코드를 실행하기전 공통적으로 실행하는 코드이기 때문에, 데몬들이 실행되기 전 먼저 세팅이 되야 한다는겁니다.





5. /etc/rc.d/init.d와 /etc/rc.d/rc0~6 

 

'/etc/inittab'적혀있는 런레벨을 확인하고, '/etc/rc.d/init.d/functions'파일을 세팅 후

이제 본격적으로 'init'은 그 런레벨에 맞춰서, /etc/rc.d/rc[0~6]에서 런레벨에 맞는 숫자의 디렉토리 내부에 있는 데몬들을 실행합니다.

예를 들어, 저희는 현재 GUI 환경인 '런레벨 5'를 쓰고 있으니, 부팅 때 'init'프로세스는



/etc/rc.d/rc5.d 디렉토리 내부의



이렇게 'S02lvm2-monitor', 'S05rmda'와 같은 'S(Start)'로 시작하는 데몬들을 숫자 순서에 따라 실행합니다.

지난번 '최초의 프로세스 포스트' 에서 다뤘던 것처럼, 'init'시스템은 직렬적으로 프로세스들을 시작하기에 이렇게 숫자로 순서가 나타나 있는겁니다!

어? 그럼 K는 뭔가요? 

'K'는 'Kill'의 약자로, K뒤에 적힌 데몬들을 숫자 순서에 따라 종료하라는 말입니다.

??? 종료를 하지 말고 첨부터 데몬을 안 키면 되는거 아닌가요??

맞습니다. 그럼 왜 여기서 K로 시작하는 데몬들을 넣어놨느냐? 그것은 바로 다른 런레벨로 바꿀 때를 위해서 정의를 해놓은겁니다.

예를 들어, CLI환경의 런레벨 3인 경우 GUI환경에서 쓰이는 데몬들이 필요가 없습니다.
그래서 만약 (GUI 환경 런레벨 5 --> CLI 환경 런레벨 3)으로 변경할 시, 런레벨 3에서 필요 없는 데몬들을 종료하라는 의미로 이때 'K로 시작하는 데몬'들을 종료하라는겁니다.

그럼 이런 심화 의문이 생길 수 있습니다.

런레벨에 맞춰서 '/etc/rc.d/rc[0~6].d'가 실행이 된다면, '/etc/rc.d/init.d'는 왜 존재하는건가요??? 보니까 /etc/rc.d/init.d'도 여러가지로 데몬들이 있던데요?

아하~ 그건 '/etc/rc.d/init.d'가 바로 실제로 데몬 파일들을 두는 곳이기 때문입니다.

무슨소리냐! 

데몬 파일들은 '/etc/rc.d/init.d'에 넣은 다음, 이 /etc/rc.d/init.d에 있는 데몬들을 링크로 만들어서 /etc/rc.d/rc[0~6]에서 쓴다는 것입니다.

실제로 확인을 해보시면, '/etc/rc.d/init.d'는



이렇게 'x'권한이 있는 실제 데몬 파일들이 있는 것을 확인할 수 있고

다른 '/etc/rc.d/rc[0~6].d' 디렉토리들은 내부를 보시면



모두 /etc/rc.d/init.d/ 내부의 실제 데몬 파일들의 링크파일로 이루어진 것을 확인할 수 있습니다.

그래서 말 그대로 /etc/rc.d/rcX.d의 숫자 X는 런레벨에 맞춰 스크립트를 실행하기 위해서다~

또한 앞서 시스템 종료용 '런레벨 0'재부팅용 '런레벨 6'같은 경우에는 
각각 '/etc/rc.d/rc0.d''/etc/rc.d/rc6.d'를 보시면



이렇게 rc0이나



rc6나 
앞서 K01~99까지 데몬들을 종료하고, 완전한 종료를 위한 쉘 스크립트 "S00killall, S01halt"
를 실행하거나, 완전한 재부팅을 위한 "S00killall, S01reboot'를 실행하라는 것을 볼 수 있습니다.

각각의 killall, halt, reboot 코드를 보시면



이렇게 건전한 체크를 위해, 현재 여전히 실행중인 필요하지 않은 서비스를 종료하는 'killall'스크립트나



런레벨 0이나 6에 쓰이는, 모든 프로세스 종료후, 파일시스템 마운트 해제까지, 완전한 시스템 종료를 위한 'halt'스크립트인걸 볼 수 있습니다.

참고로 rc6에 들어있는 'reboot스크립트'는 구분하기 쉽게 이 'halt 스크립트'를 이름만 바꾼겁니다.

TMI로 이 스크립트는 'Miquel van Smoorenburg'라는 분이 만드셨다네요. 와우






6. /etc/rc.d/rc.local 


/etc/rc.d/ 내부를 보시면, 특이한 쉘스크립트가 하나 더 있습니다. 바로



'/etc/rc.d/rc.local'이라는 쉘 스크립트죠.

이 파일은 무엇이냐? 바로 런레벨 관련 작업중 가장 마지막에 실행되는 스크립트 입니다.

왜 마지막에 실행되는 이 rc.local이란 스크립트를 뒀느냐?  바로 런레벨과 상관없이, 자기가 부팅때 실행하고 싶은 행위를 적기 위해서죠.

무슨 말이냐... 저희는 기존에 런레벨에 맞춰서, 쉘 스크립트를 런레벨에 맞는 디렉토리에 권한을 부여해 넣어두면 부팅 때 자동으로 실행이 됩니다만! 

이건 말 그대로 '런레벨'에서만 실행되는 것으로, 만약 런레벨 3 디렉토리인 rc3.d에 넣어뒀다면, 다른 런레벨 5로 부팅했을 때에는 제가 원하는 쉘스크립트가 당연히 실행 되지 않는다는 것이죠.

물론 런레벨 5 디렉토리인 rc5.d에도 똑같은 쉘 스크립트를 넣으면 됩니다만.. 그렇게 할바엔~~ 그냥 모든 런레벨 부팅 과정이 끝나면 실행하는 "rc.local"코드를 써서 사용하라는 것이죠~

그래서 부팅 런레벨 과정중 마지막에 실행이 되는 이 'rc.local'이란 파일이 존재하는겁니다.

실제로 vim을 통해 내부를 보시면



#이 스크립트는 모든 init 스크립트가 실행된 다음 실행됩니다. 

#만약 당신이 기존 sysV스타일의 init 과정을 원하지 않으면, 당신만의 초기화 과정이나 기타등등을 이곳에 쓸 수 있습니다.

이렇게 쓰여있는 것을 볼 수 있습니다~




7. /etc/rc.d/rc란


똑같이 /etc/rc.d/내부를 보시면 'rc'라는 특이한 스크립트가 있습니다. 

이것이 무엇이냐~? 바로 저희가 런레벨을 바꿀 때 실행되는 스크립트입니다.



런레벨을 바꿀 때 실행된다는 말대로, 내부를 보시면 런레벨 체크와, 현재 런레벨을 저장하고

그 밑에를 또 보시다보면



이렇게 다음 런레벨에 맞는 디렉토리 내 스크립트를 실행하는 등 말 그대로 '런레벨 변경'때 실행되는 스크립트 파일이 바로 'etc/rc.d/rc'였습니다.




8. 총 정리




부팅 때 'sysV init'의 런레벨 과정은 위 사진처럼

1. 'init'이 "/etc/rc.d/rc.sysinit(run commands.system initialization)"파일을 실행하여 파일 이름대로(system initialization) 시스템 초기화를 합니다.

2. 이후 'init'이 "/etc/inittab" 파일에 써져있는 '런레벨(runlevel)'을 읽어들인다, 그러니 /etc/inittab에 원하는 런레벨을 적으면 매번 그 런레벨로 부팅이 된다.

3. 'init'이 다른 데몬들이 공통적으로 사용하는 라이브러리 소스코드인 '/etc/rc.d/init.d/functions'라는 파일을 설정합니다. 이 과정을 통해 '/etc/rc.d/init.d/내부의 데몬'들이 이 'functions'파일을 불러들여, PID를 어떻게 결정하고, 시작하고, 종료할지를 설정합니다. 

4. 아까 '/etc/inittab'에서 읽어온 '런레벨'에 따라 "/etc/rc.d/rc[runlevel].d" 디렉토리에 있는 S가 붙은 링크 파일들을 실행하고 K가 붙은 링크 파일들은 종료합니다. 

5. 모든 'init'과정이 끝나고 'init'은 "/etc/rc.d/rc.local"파일을 실행해 추가적으로 실행하고 싶은 코드를 마지막에 수행합니다. 그러니 런레벨과 상관 없이 항상 부팅 때 실행하고자 하는 코드가 있으면 이곳에 쓰자.

6. 만약 런레벨을 바꿀시 'init'은 "/etc/rc.d/rc"파일을 실행합니다.

7. 런레벨 과정이 끝나고, 런레벨이 2~5중 하나면, '/sbin/mingetty'프로세스를 만들어 가상콘솔을 6개 엽니다.(터미널 포스트에서 다루겠습니다)

8. 런레벨이 5(GUI)라면 '/etc/X11/prefdm' 스크립트를 실행하고, 'prefdm'스크립트는 그래픽 화면인 즉 X 디스플레이어 매니저를 실행합니다.(X 윈도 포스트에서 다루겠습니다)




하 이번 포스트도 생각보다 시간이 꽤 많이 걸렸네요... 하루 5시간씩 5일이 걸렸습니다..

저의 노력이 꼭 리눅스 공부하시는 분들에게 도움이 됐으면 좋겠으며! 도움이 되셨다면, 따뜻한 댓글 및 팔로우를 클릭해주시면 저에게 아주 큰 힘이 돼! 포스트 퀄리티 향상에 큰 도움이 됩니다!

그럼 다음에는 systmed 부팅과정, PID와 리눅스 프로세스 생성과정, 터미널이란, X 윈도란 포스트 중 하나로 찾아뵙겠습니다!


2021년 7월 16일 금요일

init systemd 차이 매우 자세히!

안녕하세요 마무입니다. 오늘은 '리눅스 최초의 프로세스', 'init systemd',  "centos 6.9이하와 7이상 차이"와 "init systemd 비교"에 대해서 알아보겠습니다.


/***이 포스트를 이해하기 위해 반드시 알고 있어야하는 사전 지식***/
데몬과 서비스, 프로세스란: https://mamu2830.blogspot.com/2020/04/blog-post_18.html
/****************************************************************************/


-----목차-----

1. 리눅스 최초의 프로세스와 부모 프로세스, 자식 프로세스란

2.  init과 systemd이란
i) 프로그래밍에서 init이란

3. 리눅스 최초의 프로세스를 공부해야하는 이유
i) init과 systemd 둘다 공부해야하는 이유

4. init systemd 차이
i) systemd init 비교

---------------



여기서 못 찾은 정보는
리눅스 독학 페이지 : https://mamu2830.blogspot.com/p/blog-page_13.html
운영체제 독학 페이지 : https://mamu2830.blogspot.com/p/blog-page_14.html
에서 찾아보시면 있을 수 있습니다!



1. 리눅스 최초의 프로세스와 부모 프로세스, 자식 프로세스란


https://mamu2830.blogspot.com/2020/08/swapper.html 포스트의 'i)리눅스의 부팅과정' 에 써 있는대로 정상적으로 부팅이 진행되면, 결과적으로 커널(운영체제)는 'init(systemd)'이란 이름의 '최초의 프로세스'를 실행합니다. 

그리고 '최초의 프로세스'라는 이름대로 'PID(Process ID)''1번'을 배정받습니다.
'PID'다른 포스트에서 프로세스 명령어들과 함께 자세하게 다룰 예정이므로, 여기선 그냥 말 그대로 'Process(프로세스)들을 구분하기 위한 ID(겹치지 않는 식별자)'라고 생각해주세요. 

그리고 '리눅스'에서는 '최초의 프로세스'를 fork()라는 시스템콜을 이용해 복사해, 리눅스 부팅 때 필요한 모든 프로세스들을 만듭니다.




위 사진은 Centos 6.9이하 버전에서 'pstree(process tree)'란 명령어를 쳤을 때 나오는 결과로, 주황색 동그라미를 보시면 정말 6.9 이하에선 'init'이란 프로세스로 시작해서 다른 모든 프로세스가 시작되는 것을 볼 수 있습니다.

정말 '나무(tree)'란 이름이 들어가는 'pstree' 명령어대로 프로세스 족보를 나무처럼 보여주는 것이죠.

네? 이게 어디봐서 나무라고요? 

흐음~ 그럼 이러면 어떨까요?





이렇게 말이죠!

네? 이게 어딜봐서 나무냐고요? 어... 그럼 한번 더 이해하기 쉽게 그림으로
바꿔보겠습니다.


위 90도 회전시킨 사진을 좀 더 이해하기 쉽게 만들어 봤습니다.

맨 처음 시작되는 'init(최초의 프로세스)'은 마치 나무의 시작인 줄기와 같고'다른 프로세스들'은 그 줄기로부터 시작되는 가지들인 것이죠. 
                                        
이제는  확실히 나무같죠? 



자 'pstree'가 나무처럼 구조를 보여주는 명령어라는 것을 알았으니, 다시 돌아와 이 사진을 왼쪽에 있는 프로세스오른쪽에 있는 프로세스의 차이에 대해서 말해보겠습니다.

여기선 'init'이 맨 왼쪽에 있죠? 이 때 오른쪽에 'init'과 바로 연결돼 있는 프로세스 (NetworkManager, abrtd, acpid, anacron, atd........)들은 모두 fork()라는 시스템콜을 이용해 최초의 프로세스 'init'을 복사해서 만들어졌다는 뜻입니다. 

말 그대로 이 때 왼쪽에 있는 'init'으로부터 새로운 생명(프로세스)이 만들어진 것이니, 'init'은 오른쪽 프로세스들의 '부모' 라고 해서, 부모 프로세스라 이름을 붙인 것이죠. 

참고로 우리나라에서만 이렇게 부르는 것이 아니라, 실제로 영어로도 parent(부모) process라고 합니다.

그리고 같은 맥락으로 왼쪽에 있는 부모 프로세스를 복사해서 만들어진 오른쪽에 있는 프로세스를 부모로부터 만들어졌다 해서 '자식 프로세스'라고 하는 겁니다.

또한 'pstree' 명령어를 볼 때, 부모와 자식 프로세스의 관계를 나무에 비유했었잖습니까?

비유뿐만 아니라, 실제로 프로세스들의 구성과 메커니즘도 나무와 똑같기 때문에 줄기(init)로부터 이어진 가지(부모프로세스)가 끊어지면(종료되면) 그 가지에 이어진 다른 가지들(자식로세스들)도 죽습니다.(물론 정확히 따지자면 최초의 프로세스인 'init'이 부모 역할을 하기도 합니다)

어! 그러면 같은 원리로 당연히 모든 프로세스의 부모이자 줄기인 최초 프로세스(init 또는 systemd)를 종료하면모든 프로세스가 종료되니 즉 시스템이 꺼지나요!?

음... 이론은 그렇지만 당연히 그런식으로 시스템을 종료하면 심각한 문제(커널 패닉)가 생기므로 당연히 리눅스를 설계할 때 못하게 막아놨습니다. 

그래서 나중에 배울 'kill -9'와 같은 '프로세스 강제종료 명령어(시그널)'를 사용해도 'init(systemd)'프로세스는 강제 종료할 수 없습니다.(물론 특정 시그널을 통해서는 가능하다는 말이 있지만 심각한 문제가 초래될 수 있으니 안 알려줄겁니다ㅎㅎ..)

아 물론 지금까지 말한 부모 프로세스를 복사해 자식 프로세스를 만드는 'fork()' 방식'최초의 프로세스', '부모, 자식 프로세스' 등의 개념'init'만 해당되는게 아니라'systemd'에서도 똑같습니다. 

CentOS 7버전 이상(systemd 사용하는)에서 똑같이 'pstree'라는 명령어를 통해서 확인해보시면




이렇게 나옵니다. 위 사진의 주황색 부분을 보시면 'init 프로세스'를 쓰는 시스템과 똑같이 'systemd'란 녀석이 맨 처음 실행되는 최초의 프로세스이자, 다른 프로세스들의 부모 프로세스가 되는 것을 볼 수 있습니다~

이렇듯 대부분의 유명한 리눅스 계열들을 '최초의 프로세스'를  'init' 프로세스를 쓰느냐 'systemd' 프로세스를 쓰느냐 크게 나뉩니다.

여기까지 최초의 프로세스라는 'init', 'systemd'라는 것의 존재와, 그 역할, 부모, 자식 프로세스에 대해서 알아봤습니다. 

그럼 이번에는 'init', systemd'란 녀석들이 도대체 뭔지, 이름이 왜 저따구인지 등등 좀 더 자세한 정보와 차이에 대해서 알아보도록 하겠습니다!



2.  init과 systemd란



'init'은 "initialization(초기화, 시작하기 위한 세팅)"의 약자로, 6.9이하 버전에서 "리눅스의 정상적인 부팅을 위해 초기화를 해주는 프로세스"라는 역할을 하는 최초의 프로세스이기에 이렇게 이름을 지었고

'systemd'은 "system management daemon"의 약자로 말 그대로 "기존 init 기능 + 시스템을 총 관리해주는 데몬"이라서 그렇게 이름을 지어주었다 생각하시면 됩니다.

그리고 당연히 'init, systemd' 둘 다 최초의 프로세스로서 핵심적으로 하는 역할(모든 프로세스의 부모, 프로세스 관리, 부팅에 관여 등등)은 비슷하기에 대부분의 리눅스 계열은 'init' 또는 'systemd' 중 하나만을 씁니다. 

그럼 'init'과 'systemd'는 취향차이인가? 라고 생각이 드실 수 있는데.. 

음... 취향 차이라고도 볼 수는 있지만... 그것보단 'init' '과거부터 사용해오던 시스템'이고, 'systemd'는 '최신 시스템'이라고 보시는게 더 좋을 것 같습니다.

왜냐면 위에서 말했다시피, 'systemd'기존 'init' 프로세스의 역할뿐만 아니라 시스템 전체를 총 관리할 수 있는 다른 기능들도 추가된 데몬이기 때문이죠.

물론 여러가지 기능을 다 할 수 있는 'systemd'는 기존 유닉스계열 시스템의 철학 '한 가지만 잘하자' 라는 취지를 벗어났기에, 싫어하는 사람들도 있어서 취향을 타긴합니다만~~ 역시 'systemd'기존 'init' 프로세스보다 압도적으로 성능이 향상, 기능이 추가 됐고, 최신 리눅스 버전들도 다 도입하고 있기에 이제는 'systemd'가 최신 시스템이라고 보셔도 될 것 같습니다.

그리고 앞에서 살짝 언급을 하긴 했지만 저희가 사용하는 'RedHat 계열(RedHat Enterprise, CentOS)' 리눅스는 6.9이하 버전에선 최초의 프로세스를 'init'란 것을 사용하고, 7이상 버전부터는 'systemd'이란 것을 사용한다고 아시면 됩니다.

물론 기존 init시스템을 사용하던 사람들을 위해, 'systemd'에서 'init'을 사용할 수도 있습니다.

사실 2020년도 까지만 해도, 리눅스마스터 시험은 'init'프로세스를 사용하는 centos 6.9이하를 시험으로 봤는데, 올해부터 'systemd'를 사용하는 7이상 버전을 시험으로 보게 됐죠.


i) 프로그래밍에서 init이란



좀 TMI(Too Much Information)일 수 있지만, 사실 원래 'init'이란 이름은 리눅스 최초의 프로세스뿐만 아니라, 다른 모든 프로그래밍에서 'init(initialization, 초기화)'라는 이름대로 초기화 과정에 자주 쓰이는 이름입니다.

그래서 그냥 프로그래밍에서 'init'이란 용어가 보이면, 프로그램을 정상적으로 실행하기 위해, 처음에 실행되는 과정(초기화 과정)이나 그런 역할의 함수라고 생각하시면 됩니다.

같은 맥락으로 리눅스에서의 'init'이란 단어는 '최초의 프로세스'인 동시에 리눅스 운영체제를 정상적으로 실행하기 위한 '초기화 과정'을 나타내는 단어이기 때문에 사실 'systemd'쓰는 리눅스 시스템이라고 해도, 초기화 과정을 나타낼 때 'init'이란 단어를 사용합니다.

그러니 나중에 man 페이지나 다른 커뮤니티에서, 'systemd'를 사용하는 시스템인데 'init'이란 단어를 사용한다고 해서 당황하지 않으셔도 됩니다! 

또한 만약 리눅스의 프로세스 'init'에 대해서 궁금한 것이 있으면, 위에서 말했듯이 그냥 'init'이란 용어는 다른 프로그래밍에서 자주 쓰이기에, 리눅스 외 다른 정보들도 다 나옵니다. 

그럴 때 'sysVinit'이라 치면 우리가 원하는 '리눅스 init'에 대한 정보만 나옵니다. 왜냐면 지금까지 말한 'init'프로세스는유닉스 'sysV'에서 지금까지 사용해오던 프로그램이기 때문입니다~(sysV 등등 리눅스 역사가 궁금하시면, 리눅스 역사 총 정리 포스트를 보고 오세요!)

쉽게 "linux init process == sysVinit"이라 생각하시면 됩니다.




3. 리눅스 최초의 프로세스를 공부해야하는 이유



자 여기까지 읽으셨으면, "init은 구기술, systemd가 신기술, systemd가 더 좋음" 까진 이해가 되셨을 겁니다만 이런 의문이 들 수 있습니다.

왜 굳이  '최초의 프로세스'라는 것을 상세히 알아야하지? 그냥 그런게 있다 정도로만 알고 넘어가면 안되나?

라고 말이죠..

음... 맞습니다. 사실 리눅스를 잘 사용할 줄 아느냐의 수준'리눅스마스터 2급'까지만 공부하실 생각이라면, 더 자세하게 안 배우고, 그냥 "최신 리눅스는 systemd를 씀, systemd는 init + 시스템 전체를 관리할 수 있는 기능"까지만 알고 넘어가도 상관은 없습니다(물론 프로세스 관련 명령어는 알아야하겠죠?)

하지만 여러분이 서버를 관리할 수 있느냐라는 '리눅스마스터 1급'까지 공부하실 생각이라면, '최초의 프로세스'의 원리와 관련 디렉토리에 대해서 잘 알아야합니다.

왜냐면 실시간으로 서버 프로세스를 관리할 수 있어야 하고, 프로세스의 특징과 생성 원리, 또 데몬(서비스)를 만들고 관리할 줄 알아야하는데 이 때 당연히 '최초의 프로세스 init(systemd)'가 관련되기 때문입니다.

그리고 이런 프로세스 관련 기술, 지식들은 서버 관리에 필수적이며 원래 '총'아군이 들고 있으면 보안용이지만, 적군이 들면 무기가 되듯이서버 관리, 보안 기술은 살짝 뒤집으면 바로 해킹 기술이 되기 때문에 보안 공부를 하시는 분들도 당연히 잘 알아야하죠.


i) init과 systemd 둘 다 공부해야하는 이유 


그럼 'systemd'가 더 좋고, 최신버전에 'systemd'가 쓰이는 추세니, 'systemd'만 공부하면 되는거 아닌가요?" 란 의문이 드실겁니다. 

물론 시험을 목적으로 하신다면 그렇게만 하셔도 됩니다만, 실용성을 목적으로 하신다면 결국 둘 다 공부를 하셔야 할겁니다...

그 이유는 리눅스 독학 포스트 첫 번째인 "리눅스 설치편"에서 제가 "리눅스는 서버에서 많이 쓰이는 운영체제다"라고 말을 했었는데 기억이 나시나요? 그리고 그 이유중 하나는 바로 "안전성"에 있다고 말이죠.

같은 맥락으로 서버의 입장에선 무엇보다도 가장 중요한건 바로 "안전성"입니다. 그렇기 때문에 보통 서버들은 게임마냥 새로운 버전이 나왔다고 운영체제 업데이트를 확확 하지 않습니다.  상당히 보수적이죠...

그런데 그럴 수 밖에 없는게, 개인 PC에 비교해서 서버들은 정~~말 많은 컴퓨터와 장비들이 서로 연결이 돼 있고 요즘 서버는 대부분 서버 가상화 기술(수~~~~많은 컴퓨터들을 가상화 기술들을 이용해 하나로 합치는 것)과  클라우드 환경(인터넷을 통해 서버를 이용하는 것)을 이용해 만들기 때문에, "가상 서버를 이루고 있는 컴퓨터들끼리의 상호관계"와 또 "클라우드 프로그램과의 호환성""지금까지 사용해오던 다른 모든 서버 프로그램들과의 호환성", 그리고 "운영체제 버그 문제" 등등을 고려해봤을 때, 정말 서버입장에선 운영체제를 업그레이드할 경우 감수해야할 위험 부담이 너~~무나 크기 때문이죠.

이렇듯 서버에선 안전성이 제일 중요하기 때문에, 기존에 "6.9이하 시스템(init)"을 써오던 서버들은 "7이상 버전(systemd)"으로 업그레이드 하지 않고 계속 사용하는 경우가 많습니다.

그렇기 때문에 아직까지도 서버에서 버전은 '6.9버전 이하'가 약 절반 정도 사용며 요즘들어 겨우 7.0이상은 절반도 안되게 사용되기 시작했다고 합니다.

그래서 지금까지 리눅스마스터 시험을 6.9이하 버전으로 했던 것이죠. 하지만 systemd를 사용하는 시스템의 장점이 앞서 설명한 부팅 속도 뿐만 아니라 훨씬 많으며, 앞으로 나오는 7.0이상 버전은 모두 systemd를 사용하고 점점 그 수도 증가할 것으로 보이니 결국 저희는 저흰 {init, systemd}시스템 공부를 둘 다 해둬야하는 겁니다. 



4. init systemd 차이



자 그럼 한번 본격적으로 자세하게 'init'과 'systemd'의 차이에 대해서 비교해보겠습니다.

일단 가장 체감이 되는 큰 차이는 바로 부팅 때 다른 프로세스들을 병렬적으로 키는가 아닌가라 볼 수 있습니다.

"갑자기 병렬적이라니... 무슨 소리인가요?"

무슨 소리냐면, 'init 프로세스' 부팅 때 '모든 서비스(데몬)'을 순서대로 차례차례킵니다. 

차례차례라는 건 앞에 프로세스가 완전히 실행돼야, 그 다음 순서 프로세스를 실행시키는 방식이라는거죠. 그냥 쉽게 프로세스들이 실행되기 위해 한 줄로 서 있다고 보시면 됩니다

한 줄로 서 있다... 그것은 즉 '직렬'이라는 것을 의미하죠!

그래서 이런 'init'프로세스의 방식을 한 단어로 표현하자면 '직렬'방식이라고 하는 것입니다. 

그리고 '직렬 방식'단점은 바로 앞 순서의 시스템에 필수적인 특정 프로세스가 켜지는게 오래걸리면, 뒷 순서의 나머지 프로세스들은 대기해야하기 때문에 부팅이 오래걸릴 수 있다는 것입니다.

예를 들자면 사람들(프로세스들)이 버스를 타려고(시작되려고) 줄을 서 있는데, 버스 입구에서 누군가(특정 프로세스)가 결제가 오래걸리면, 그만큼 뒤에 기다리는 사람들은 버스에 못 들어가는(시작 못하는) 것과 마찬가지인 겁니다. 

그리고 당연히 모든 손님이 버스에 탑승하지 못했기에 버스(시스템)는 출발하지(부팅 되지) 않습니다.

 



나중에 'init'을 전문적으로 다룬 포스트에서 나올 내용이지만, 위 사진처럼 6.9이하 버전에서 "/etc/rc.d/rc3.d/"란 디렉토리를 보시면 K01, K02, S10 등등 파일 이름 앞에 숫자가 써 있는 파일들이 보이실텐데요, 이 숫자들의 의미는 'init'이 이 숫자 순서대로 프로세스를 시작한다는 의미입니다.(더 자세한건 'init'포스트에서 다루겠습니다)

그렇기에 만약 'S10network'란 프로세스가 완전히 켜지는데 오래 걸리면, 그만큼 뒷 순서의 S11, S12, ....들은 켜지는데 오래 걸리는 겁니다.

이처럼 'init'직렬적인 방식이라 부팅이 오래걸릴 수 있다는 단점이 있습니다.

그래서 이런 '직렬'방식의 단점과 기존 'init' 프로세스 시스템의 아쉬움 점들을 보완하기 위해 '레드햇 7이상' 버전부터 새로 도입한 시스템이 바로 'systemd'를 사용하는 시스템인 것입니다.

나중에 'systemd'만 다룬 포스트에서 설명할 것이지만, 'systemd'는 사실 'init'프로세스와는 다르게 시스템 초기화에만 관여하는 프로그램 뿐만 아니라, 시스템 전반적 관리에 쓰이는 다른 데몬들을 포함한(journald, logind, networkd 등등..) 종합세트의 이름입니다.   

어쨌든, 직렬 방식의 단점을 보완했다는 말에서 알 수 있듯이, 'systemd' 'init'과 다르게 부팅에 필요한 프로세스들만 먼저 '병렬적'으로 시작합니다. 그렇기에 부팅할 때 특정 프로세스가 오래걸릴 경우, 기다릴 필요가 없으니 부팅시간이 init과 비교해서 훨씬 빠릅니다.

직렬 방식(init) 시스템은, 버스 앞문을 이용해서만 모든 손님이 버스에 탄 뒤 출발하는 방식이라고 치면 

병렬 방식(systemd)은 버스 앞문 뿐만 아니라 뒷문도 열어서 일단 손님들이 우르르 버스에 올라탄 다음, 각자 결제를 하되, 특정 인원 수 이상(부팅에 꼭 필요한 서비스들)이 결제(시작)를 완료하면 그냥 출발(부팅)하는 것입니다.

손님이 앞, 뒷문을 이용해 일단 버스에 탄 뒤에 각자 결제를 하고, 특정 수만 결제를 완료하면 출발하니,  좁은 앞문만 이용하며, 모든 인원이 결제를 마쳐야 출발 하는 직렬 방식보단 훨씬 빠르겠죠?




위 사진은 7이상 버전에서 6.9이하에서 init이 사용하던 "/etc/rc.d/rc3.d/" 디렉토리 내부를 찍은 사진인데요, 숫자들이 적힌 파일들이 있던 init시스템(6.9이하)와는 다르게 아무것도 없이 텅~ 비어있는 걸 볼 수 있습니다.

당연히 'init'에서 'systemd'으로 바뀌며, 사용하는 디렉토리가 완전히 바뀐 것도 있고, 서비스를 키는 방식이 완전히 달라진 것도 있습니다.

지금은 이해가 안 되실 수 있지만 미리 살짝 말하자면, 기존 'init'은 런레벨에 맞는 특정 디렉토리에 실행할 데몬들을 집어넣어 넣어놓고, 'init'이 특정 디렉토리를 선택 후 그 내부의 프로그램들을 순서대로 실행하는 방식이였다면

'systemd'는 어떤 데몬을 실행할지, 또 그 데몬은 다른 어떤 프로그램과 의존성을 갖는지 등등을 적은 ".target"이란 확장자가 붙은 설정파일들을 이용하여 런레벨과 데몬들을 실행하듯이 방식이 완전히 달라졌다는 것이죠.

그 외에 다른 세부적인 차이점들을 모두 이 포스트에 설명하자면 끝이 없으므로... 일단 'init'에서 'systemd'로 변하면서 생긴 큰 'systemd'의 특징들 적어보겠습니다.


i) systemd init 비교



1) 프로세스의 관리에 있어서 더욱 효율적이고, 깔끔하며, 상태 지향적으로 바뀌었다.
 ex)데몬이 active 인지,  inactive인지 등등 상태를 잘 나타냄

상태 지향적으로 바뀌었다는 말은 글로만 이해가 잘 안되니 사진으로 보여드리자면

기존 init에서 실행중인 데몬의 상태를 보는 명령어를 치면




이렇게 되게 담백하게 그저 실행중이라고만 뜹니다

하지만! 'systemd'에서는?




이렇게 프로그램의 상세한 정보들과, 위 주황색 밑줄을 보시면 "active(활성 상태)"라고 써 있죠? 이런 활성 상태 이외에도 "active, inactive, failed"등등, 데몬의 '상태'를 나타내주기 때문에 더욱 효율적이고, 깔끔하며, 상태 지향적으로 바뀌었다고 하는 겁니다.


2) 부팅 때 프로세스 병렬처리를 통한 빠른 부팅

이건 위에서 설명했듯이, 병렬처리를 통해 더욱 빠르게 부팅한다는 것인데요, 그래도 그냥 넘어가면 찝찝하실테니.. 부팅 때의 systemd의 병렬처리 과정 사진을 보여드리겠습니다.

 더 자세한 정보들은 'systemd' 포스트에서 집중적으로 다루도록 하겠습니다.


3) 더 좋아진 API


4) 다양해진 단위(unit)(여기서 단위란, init이나 systemd가 인식하고 사용하는 파일을 말합니다.)

사실 단위가 다양해졌다? 말로만 들으면 이해가 안됩니다. 그래서 sshd 데몬을 예시를 들어 설명해보겠습니다. 

'init'시스템에서는 서비스(데몬)는 모두 다 그냥 서비스일뿐이고, 이름도 그냥 서비스 자체의 이름 그대로 'sshd'입니다. 



이렇게 주황색으로 표시한 것처럼 말이죠.(아직 'init'에 대해서 배우지 않으셨으면 이해가 안되는게 정상입니다. 그런가보다~ 넘어가주세여)

그리고 설정파일들은 확장자가 ".conf"로 끝나고, 뭐 요정도 정도밖에 기존 'init' 시스템에선 딱히 용도에 맞게 파일들을 구분하는게 많지 않았고, 그렇기에 '유닛(unit)'라고 부를만한 세분화가 없었습니다.

하지만 'systemd' 시스템부터 '기존 init 기능 이외'에도 시스템 전반적인 것들을 관리하는 기능이 더 있기에, 그만큼 사용해야할 파일들도 많아졌고, 그래서 효율적으로 사용하기 위해, 'systemd'가 사용하는 파일들을 그 용도에 따라 명확히 구분(세분화)했습니다.  

그리고 세분화된 'systemd'가 사용하는 파일들을 '단위(unit)'이라고 부르기로 했죠.

여기서 세분화 했다는 것은, 용도에 따라 파일 이름 끝에 붙이는 확장자가 더욱 다양해졌다는 겁니다.

예를 들어, 우리가 알고 있는 데몬(서비스)은 파일이름 끝에 확장자 ".service" 붙여 구분하고,  데몬 프로그램에서 사용하는 소켓 파일은 확장자 ".socket" 붙이듯이 말이죠.



이건 아까 'init' 시스템처럼 똑같이, 'systemd'를 사용하는 시스템에서 ''sshd" 검색을 한 결과입니다.

주황색을 보시면, 그냥 'sshd'만 있던 'init'시스템과는 다르게, 'sshd.service', 'sshd.socket'이렇게 용도에 따라 나뉘어져 있는 것을 볼 수 있습니다.

그리고 이렇게 확장자가 붙어있는 sshd.service, sshd.socket을, 우린  systemd가 사용하는 파일이라 해서 단위(unit)라 부르기로 했다는 것이죠. 

이 외에도  systemd가 사용하는 파일들의 확장자 종류에는 service, socket, device, target, path, device, mount 등등 다양하게 있습니다. 

이렇듯 단위가 다양하기에 말 그대로 '단위가 다양해졌다'고 한 것입니다. 

5) 더 낮아진 실행중 필요한 메모리양(footprint)

6) 초기화 명령어들이 이젠 쉘 스크립트가 아닌 단위(unit)파일들에 적혀있음

음 이것도 사진을 보여드리자면

init을 사용하는 시스템인 경우



이렇게 초기화 명령어들이 쉘 스크립트 형식으로 적혀 있습니다.
이런 경우 쉘 스크립트를 모르는 분들은 당연히 이해할 수 없고, 무엇을 해야하는지 이해하기 위해서는 일일이 코드를 해석해야하기 때문에 조금 더 번거러운 부분이 있습니다.

하지만 systemd 시스템에서는 이런 초기화 명령어 부분들을 'systemd'에서 정의해놓은 특정한 구문을 통해서 실행합니다.(자세한건 'systemd' 포스트에서 다루겠습니다.)



미리 살짝 설명하자면, 'Description(설명)'을 통해서 이 유닛이 무슨 역할인지를 알 수 있고,
'documentation(문서)'를 통해서 이 유닛에 대한 설명이 써져있는 man 페이지를 알 수 있고,
'Requires(필요하다)'를 통해서 이 유닛(basic.target)이 실행될 때 반드시 실행되야할 다른 유닛이 'sysinit.target'이라는 '의존성'을 알 수 있고,  'after(어떤 것 다음에 실행해라)'를 통해, 현재 유닛(basic.target)은 'sysinit.target' 다음에 실행되야함을 알 수 있고... 등등

말 그대로 직관적으로 어떤 순서로 실행되며, 어떤 파일을 실행하고 등등알 수 있고, 설정할 수 있다는 것이죠.

7) systemd의 'calendar timer란 유닛 파일'을 이용해 job 스케줄링을 할 수 있다. 

원래 리눅스 시스템에선 'cron'이라는 유닉스 시스템 스케줄러를 이용해서 특정 시간대에 어떤 작업을 하라고, 예약을 할 수 있거든요, 'systemd'에선 '.timer'라고 끝나는 유닛을 새로 도입했고 이 '.timer'로 끝나는 유닛을 이용해서 'cron'작업을 할 수 있습니다.

8) 이벤트 기록을 'journald'라는 데몬이 한다.(sysVinit에선 syslogd가 했음)

여기서 말하는 "리눅스 시스템 이벤트란" 뭘까요? init시스템의 "man 5 init"에 적혀있는 "이벤트의 정의"
"언제든 관리자가 initctl(init 데몬을 컨트롤할 수 있는 프로그램)의 start, stop 명령어를 사용해 시작하거나 정지할 수 있는 작업들" 라고 적혀있습니다.

그리고 원래 이 이벤트는 'init' 프로세스가 필요할 때마다 자동으로 발생하며, 이러한 이벤트 기록을 'syslogd'라는 데몬이 했습니다.

왜 'syslogd'를 안 쓰고, 'jounald'로 바꿨을까는 다른 포스트에서 다루도록 하겠습니다. 

9) 현재 시스템 상태를 그대로 저장했다가 다시 사용할 수 있는 snapshot 기능 지원(systemctl snapshot 명령어를 사용)

이것도 자세한건 나중에 따로 포스트를 해보겠습니다.(포스트 하나에 너무 많은 정보를 적으면 여러분도 읽느라 고생, 저도 고생, 블로그 측면에서도 안 좋아요 ㅠㅠ)
 
10) 프로세스들의 추적을(얼마나 자원을 사용하는지, 잘 종료 됐는지 등등) "cgroup(control group)"이란 그룹들을 이용해 한다.

이것도 다른 포스트에 정리하겠습니다.. (죄송합니다..)

11) 유저들의 로그인을 다양하게 관리할 수 있게 해주는 'systemd-logind'란 데몬을 사용


이 정도로 큼직하게 달라진 점을 말할 수 있을 것 같습니다.




후... 이 포스트도 생각보다 시간이 엄청 오래걸렸네요(하루 6시간, 3일 걸렸네요) 하핫... 

그리고 추가로 막상 포스트 하다보니 개인적으로 궁금한게 계속 생겨서 많이 공부하다보니, 블로그 포스트를 오랜만에 하게된 것 같습니다.

저의 노력을 갈아넣은 포스트가 꼭 도움이 되셨으면 좋겠습니다!!! 그리고 도움이 되셨다면 따뜻한 댓글 및 팔로우를 해주시면 저에게 큰 힘이 돼, 포스트 퀄리티 향상에 큰 도움을 줍니다!

그럼 다음에 'sysvinit(init 프로세스) 총 정리 포스트', 'systemd 총 정리 포스트', '리눅스 PID, 프로세스 명령어'들 중 하나로 찾아뵙겠습니다!!


2021년 5월 10일 월요일

리눅스 tar 매우 쉽고 자세히

 안녕하세요! 마무입니다. 오늘은 앞으로 리눅스를 사용하면서 계~속 사용하게 될 파일 압축 및 해제때 쓰이는 "리눅스 tar, gzip, bzip2, xz"에 대해서 자세히 알아보겠습니다.

굳이 "yum", "rpm"이 있는데, 'tar와 압축기술'을 알아야하나?

라는 의문이 드실 수 있겠지만, 보안이 정말 중요한 '서버 프로그램'인 경우 직접 소스코드를 다운받고 원하는 디렉토리에 컴파일하는데, 이때 무조건 사용하며, 이 외에도 압축이 필요한 모든 곳에 사용되니 꼭 알아둬야 하는 명령어입니다!

제 블로그 글이 특성상 매우 길어서, 다 읽기가 싫으실 수 있습니다! 그럴 경우 3번 총정리만 보셔도 됩니다만... 결국 원리를 배우지 못했기에 계속 스스로 의문이 들면서, 제대로 공부가 안 되실겁니다 ㅎㅎ 

그러니 딱! 한번만 마음 편~히 첨부터 끝까지 읽어주시고, 이후에 까먹을 때마다 '3. 총 정리'만 보시길 바랍니당!


-----목차-----

1. 리눅스 tar란

i) tar 사용법과 옵션

2. 리눅스 gzip, bzip2, xz란

i) gzip 사용법과 옵션

ii) bzip2 사용법과 옵션

iii) xz 사용법과 옵션

3. 총 정리

--------------

입니다.


여기서 못 찾은 정보는 

리눅스 독학 페이지 : https://mamu2830.blogspot.com/p/blog-page_13.html

에서 찾아보세요!




1. 리눅스 tar란


리눅스를 사용한다면 정~말 정~말 자주 쓰는 'tar(tape archive)'란 명령어가 있습니다. 바로 여러 파일들을 하나의 파일로 묶는 명령어인데요, 여기서 'Tape'란 아시는 분들은 다 아시는 


(사진 출처 : https://ko.wikipedia.org/wiki/%EC%9E%90%EA%B8%B0_%ED%85%8C%EC%9D%B4%ED%94%84)

바로 이 '자기테이프'가 맞습니다. 

네? 모르겠다고요?(예끼! 라뗀말야..) 흠.. 그럼 '비디오테이프'는 아시죠? 그 비디오테이프가 바로 자기테이프로, 자기테이프에 영상과 소리를 기록한 것이죠!

이러한 '자기테이프'용량대비 가격이 제일 싸고(현대 사용중인 저장장치중), 또한 물리적으로도 손상에 강하며, 수명도 보통 15년~30년 사이로 매우 길기 때문에 아직까지도 정말 중요한 문서들이나 데이터들은 이런 자기테이프에 백업을 한다고 합니다. 

하지만, 장점이 있다면 단점도 있는법.. 이런 대규모 자기테이프의 정보를 읽고 쓰는 '자기테이프 드라이브'매우 비싸기에 정말 큰 규모의 회사나 기관이 아니면 그냥 하드디스크를 쓴다고 합니다.

얘기가 길어졌는데, 어쨌든 "tar(tape archive)"'tape'는 이 자기테이프를 말한다는 거였습니다.

그럼 "archive(아카이브)"는 뭘까요? archive(아카이브)란 원래 "역사적인 기록들의 모음"을 의미합니다. 그리고 이 의미는 컴퓨터쪽에선 "만일을 대비해 데이터를 백업해두는 것"을 말합니다.

그래서 결국 "tape archive"의 뜻이란? 말 그대로 "자기테이프를 이용한 백업'입니다 ㅋㅋㅋ

어? 그러면 리눅스에서 저희가 배우는 이 'tar'란 명령어는 자기테이프에 백업을 하는 명령어인가요?

네!

네.. 과거엔 그랬습니다... 과거에는 지금처럼 좋은 저장장치가 없었기에, 굳이 거창하게 "만일을 대비한 백업"이라기 보단 애초 쓰는 저장장치가 바로 자기테이프였습니다. 

그런데 당시 '자기테이프' 지금의 하드디스크에서 쓰이는 수준의 파일시스템이 없어서 테이프에 저장하는 데이터 블록 단위가 고정돼 있었고, 그래서 데이터를 저장했다 끊었다를 하기가 힘들기에, 데이터를 하나로 묶고 한방에 저장하는 방식이 필요하게 됩니다.

그래서 'tar'명령어를 써서 여러 파일들을 하나로 묶은 것이죠.

그러나... 현대에 와서는 기술의 발전으로 하드디스크, 플래시 메모리등 여러 저장장치가 많이 등장해서 자기테이프에 저장하기 위해 쓸 일이 거의 없어졌습니다.

그런데 이 "tar"명령어가 위에서 말했다시피, 여러 파일을 하나로 묶어주는 기능을 갖고 있기에 그냥 지금까지도 여러 파일들을 하나의 파일로 묶는용도로 사용하기 시작했습니다.

당연히 자가테이프가 사용되던 시절은 '유닉스(Unix)'가 막 개발돼 시장을 점령하던 시절으로, 이후 당연히 유닉스 계열(리눅스 포함)의 대부분은 지금까지도 이 "tar" 명령어를 애용합니다.

그리고 이젠 다들 아시겠지만, 리눅스는 확장자에 특별한 기능이 없기에 대신 무엇에 쓰이는 것이다라고 확장자를 직접 붙이거든요? ex) .rpm, .swp 등등...

'tar'도 마찬가지로, 'tar'로 묶은 파일임을 나타내기 위해 파일 이름 뒤에 ".tar"를 붙인 형태로 이름을 짓습니다.


i) tar 사용법과 옵션 


"tar"명령어가 아직까지도 계속 애용되는 이유가 있습니다. 바로 "tar"로 묶는 파일들의 속성, 링크, 접근시간등 원래 파일 상태 그~대로 묶어주는 것이죠.

그리고 말 그대로 archive(백업용)이기 때문에, 묶은 파일들이 .tar파일 안으로 들어가는게 아니라, 완전히 똑같은 파일들이 복사된 후 '.tar'로 묶이는 겁니다.

또한 당연하다고 느낄 수도 있지만, 하위 디렉토리와 하위 파일까지 당연히 싹다 같이 묶어줍니다.

뭐 그냥 "tar"로 파일을 묶을 땐, 변할 걱정은 안해도 된다~ 이렇게 생각하시면 되겠습니다.

그래서 현재 윈도우에서도 사람들이 많은 프로그램이나 여러 파일들을 배포할 때 '묶어서' 배포하듯이, 리눅스(유닉스)에서도 현재 대부분의 파일들이 배포될 때 "tar"로 묶어서 배포합니다.

그럼 이 "tar"의 사용법을 알아봐야죠! tar의 명령어 형식은


tar [필수옵션+부가옵션] [묶을 파일들...] 

입니다만, '필수옵션'이 보이시죠? 'rpm'때도 그랬지만, 이 "tar"를 사용할 때도 용도에 맞게 꼭 써야하는 필수 옵션(정식 x, 제가 이름 붙인겁니다)이 있습니다. 

'부가 옵션'은 말 그대로 필요에 따라 부가적으로 쓸 수 있는 옵션입니다.


-tar 필수옵션 종류-


-f(file name) [tar 파일이름] : 'tar' 파일 이름을 짓거나, 파일들을 뺄 'tar'파일을 지정하는 옵션으로, 무조건 붙여줘야함

+

-c(create) : create, 맨 뒤에 적은 여러 파일들을 이용해서 'tar'파일을 만들겠다.

-x(extract) : extract, 즉 'tar'파일에 들어있는 여러 파일들을 빼내겠다.

-r(renew) [추가할 파일들..] : renew(제가 끼워맞춘 영어), 즉 기존 'tar'파일에 새로운 파일들을 추가해서 갱신하겠다.

-t(list) : list, 즉 'tar'파일속 파일들을 펼쳐서 list형태로 보여줘라 


-------------------------


주의할게 있습니다! 반드시 써야하는 '필수'옵션이지만, 'tar'파일 이름을 지정하는 '-f'제외한 나머지 옵션들은 무조건 한 명령어에 내에서 하나만 써야합니다.

무슨 소리냐, '-c', '-x', '-r', '-t' 옵션들은 동시에 같이 쓰일 수 없다는 것이죠.

뭔가 외워야 할 것 같은 느낌이 들면서  머리가 아파오시죠? 에이~ 그럴 필요 없습니다.

그냥 우리는 논리적으로만 생각하면 됩니다. 

일단 'tar'파일을 (c)만들든, (x)빼든, (r)갱신하든, (t)내용물을 보든 당연히 'tar'파일을 지정해야하니, '-f' 옵션은 무조건 써야하는을 우린 알 수 있고

그리고 다른 옵션들인 경우 예를 들어, '-c(create)' 옵션을 써서 'tar'파일로 만드는 동시에 '-x(extract)'로 파일을 빼는게 말이 안되죠? 

마찬가지로 '-c'로 'tar'파일을 만들면서,  '-t'를 써서 'tar'파일에 속한 파일들을 보여주는 것도말이 안되고, '-c'로 만들면서 '-r'로 다른 파일을 추가하는 것도 말이 안되기에 같이 쓸 수 없습니다.

굳이 외운다기 보단, 이렇게 논리적으로 생각하시면 자연스럽게 '-f'외엔 필수옵션중 하나만 써야한다는 것이 체화되실겁니다!

 

그리고 'tar'는 특이하게도 옵션을 쓰실 때, 한번에 여러 옵션을 붙여 쓰는 경우 

"ex) tar -cvf [파일.tar] [넣을 파일들...]"  

이렇게 다른 기존 리눅스 명령어들과 같이 옵션을 이렇게 '-'하나에 여러 옵션을 붙인 형태로 줘도 되지만

"ex) tar cvf [파일.tar] [넣을 파일들...]" 

이렇게 '-'를 생략해도 됩니다.

취향의 차이라고 볼 수 있습니다만 저는 그냥 개인적으로 원래 다른 리눅스 명령어처럼 '-'를 붙인 옵션을 쓰길 추천합니다.

왜냐? 

이게 부가적인 옵션을 같이 사용하는 경우(밑에서 배우겠지만 '-C'란 옵션을 이용한 예시를 든다면)

부가적인 옵션은 바로 뒤에 옵션값을 줘야하기에 "-옵션1 [옵션 값1] -옵션2 [옵션 값2]"이런 형식을 결국에는 취해야해서

"ex) tar xvfC /tmp/ [파일.tar]" 이렇게 쓸 수 없거든요!(-f옵션 바로 뒤에 -C옵션값 '/tmp/'가 아닌, "파일.tar"값을 줘야하기 때문에)

그래서 쓰려면 결국

"ex) tar xvf [파일.tar] -C /tmp/" 이렇게 써야하는데, 이렇게 어떤건 '-'붙이고, 어떤건 안 붙이일바엔 그냥 헷갈리지 않게 처음부터

"ex) tar -xvf [파일.tar] -C /tmp/" 다른 리눅스 명령어 옵션들처럼 이렇게 쓰자는 것이죠~

그래서 저는 그냥 첨부터 헷갈리지 않게 '-'를 붙여서 쓰길 추천한겁니다.

 

-tar 부가옵션 종류-


-v(verbose) : verbose(자세하게), 라는 뜻대로 진행정도를 보여줌



위 사진이 '-v'를 안 썻을 때 사진이고



이게 '-v'를 썻을 때 사진입니다.

확실히 '자세히'라 볼 수 있을 정도로, 재료가 되는 파일들을 나열해주듯, 차이가 있죠?


-C(Change{대문자} directory) [경로]: Change directory, 뜻 그대로 디렉토리를 이동하는 것으로, 옵션값으로 적은 위치로 디렉토리를 이동합니다. 

예를 들어서, 만약에 '/root/'에서 "tar -cf test.tar 1 2 3 -C /var log"라고 칠 경우 이건

애초 '-C'옵션 앞의 "tar -cf test.tar 1 2 3"란 명령어가








이런 뜻이기 때문에
이후 "-C /var"한 세트로서 디렉토리를 이동하고, 이후 나오는 'log'는 앞서 tar파일의 재료인 "1 2 3"과 같은 취급이 되는 것이죠.




이렇게 말이죠.

그래서 결국 "tar -cf test.tar 1 2 3 -C /var log"라 치면 현 디렉토리에 "test.tar"를 만들지만, 그 재료들은 현 디렉토리 1 2 3/var에 있는 'log'에 있다라는 뜻입니다.

만약 다른 디렉토리에 'test.tar'파일을 만들고 싶었으면
"tar -cf /var/test.tar 1 2 3 -C /var log" 이런식으로 애초 'test.tar'파일 이름을 지정할 때 경로까지 같이 적어줬으면, '/var'에 'test.tar'가 만들어졌을 겁니다. 

이처럼 '-C(Change directory)'는 명령어 순서대로 처리가 되기 때문에 마찬가지로 ".tar"파일의 해제하는 옵션 '-x'인 경우에도

"tar -xf test.tar"그냥 이렇게 치면 당연히 디폴트로, 현재 위치에 풀어서



이렇게 되지만

"tar -xf test.tar -C /var"이렇게 치면, "tar -xf test.tar"란 명령어가 현재 위치에 'test.tar'를 풀어라지만, 명령어가 끝나기전에 '-C'옵션을 이용해 이동한 디렉토리는 "/var"여서
결국 현재위치가 '/var/'이기에, '/var'에 1 2 3 파일들이 풀리는 것이죠. 

사진을 보자면



이런식으로 '/var'에 파일들이 풀리는 것이죠.

그래서 결국 "tar -xf test.tar -C /var"라 친 경우엔, 'test.tar'명령어 진행중 이동한 현재 위치인 '/var'에 푸는 것입니다.
  



2. 리눅스 gzip, bzip2, xz란


자 여러 파일들을 묶고 푸는건 'tar'라는 명령어로 충분히 잘 사용하는데, 문제가 생겼습니다.

무슨 문제냐? 위에서 알려준대로 'tar'명령어를 이용해 '.tar'파일을 만드시고, 용량을 확인한 분들은 분명 뭔가 이상함을 눈치챌 수 있으실 겁니다.

바로 기존에 묶은 파일들을 합친 것보다 훨~씬 더 큰 용량으로 '.tar'파일로 묶이는 것을 말이죠.

다시 말해서 용량이 '0'인 파일 3개를 묶었더니 10240바이트(10K)라는 크기의 .tar파일이 똻!하고 나온다는 것이죠. (tar는 신인가..!?)

이렇게 'tar'를 쓸 경우 무에서 유를 창조하듯이 비약적으로 용량이 커지는 이유는 사실 'tar'의 역사와 연관이 있습니다. 

위에서 언급했듯이, '자기테이프'는 원래 고정된 사이즈의 블록단위만 쓸 수 있기에 자기테이프와의 호환을 위해서 '프로그램(tar를 쓰는)'도 고정된 블록 단위로 데이터를 저장하고 읽습니다

(블록이 뭔지 궁금하신 분들은 운영체제 페이지 ->파일시스템 총 정리포스트 를 읽고 오시길!)

블록 단위라.. 그럼 512Byte나 1KB면 되지 왜 굳이 10KB나 될까요? 그건 사실 'tar'의 장점이 바로 파일들을 묶었을 때, 묶는 파일들의 정보들을 그~대로 유지되는거랬잖습니까? 바로 그 장점에 비밀이 있습니다.

그렇습니다. 

'tar'파일을 묶을 때, 기존 파일들의 고유 정보들(이름, 모드, 권한, 크기, 체크섬, 링크수, 링크이름, 여배 공간 채우기용)등 많은 부가정보들을 같이 저장해야하기 때문에 고정 블록 사이즈를 작게 잡을 수가 없었던겁니다.

그래서 'tar'기본 블록 사이즈는 보통 '10KB(10240byte)'로 정했다고 합니다.(사실 정하는 사람 마음이지...)

그래서 'tar'파일을 만들 때 쓰이는 파일들의 크기 총합이 10KB미만이여도, 무조건 10KB 사이즈가 배정되는 것이죠.

어쨌든, 이렇듯 'tar'를 사용하니 너무나 파일 크기가 커져서, 파일을 인터넷을 통해 배포하거나, 백업하는데 등 매우 불편해지자 결국 당연하게도 압축기술을 같이 사용하게 됐습니다.

그래서 원래는 'tar'로 파일을 묶은 다음, 압축 프로그램을 이용해 압축을 해야하지만, 'tar'를 사용한다면 거의 무조건으로 압축기술을 같이 사용하기에 지금은 유명한 압축 프로그램들을, 'tar'를 사용할 때 '옵션'으로써 사용할 수 있게 만들어놓아, 한번에 묶고 압축 합니다.


i) gzip 사용법과 옵션 


'gzip(GNU zip)'은 이름 그대로 GNU 프로젝트를 통해 만들어진 압축 프로그램으로,

간단하게 

gzip [압축할 파일]

형태로 사용이 가능합니다.

항상 말하지만! 리눅스는 확장자에 특별한 기능은 없지만, 어떤 용도 파일로 사용됨을 나타낸다고 했듯이

'gzip'을 사용해서 파일을 압축하면 자동으로 '.gz(gzip)'라는 확장자가 끝에 붙습니다.



이렇게 말이죠. 그리고 당연하게 '압축'프로그램이니 사이즈도 줄어듭니다.

위에 보시면 잘 티가 안나지만, 자세히 보시면 파일 크기가 무려 '0'단위 줄어든 걸 볼 수 있습니다!

그럼 압축 해제는 어떻게 할까요?

바로 이전의 행위를 나타내는 영어 'un'을 붙여주면 됩니다!

하지만 ungzip이라고 하면 폼이 안나서 그런가? 압축 해제는 'gunzip'라고 치면 됩니다.


gunzip [압축해제할 파일]




이렇게 말이죠.

그리고 위에서 언급했듯이 보통 tar를 쓰면 압축도 같이하기에, gzip을 'tar 옵션'으로 실행하여 보통 한번에 아카이브와 압축, 압축해제와 아카이브해제를 동시에 합니다.

그리고 이때 사용하는 

tar에서의 gzip의 옵션은 바로 '-z(소문자)'입니다.


ex) "tar -zcf test.tar.gz 1 2 3" --> 1 2 3파일을 test.tar.gz란 파일로 묶고, gzip으로 압축해라

여기서 편의성을 위해서, 만들겠다는 '-c'옵션gzip 옵션 '-z'가 같이 쓰이면, 같은 맥락으로 .tar 파일을 만들고 압축을 하며

해제하겠다는 '-x'옵션'-z'를 같이 쓰면, 같은 맥락으로 .tar파일 해제와 압축 해제를 합니다.

또한 '-f'옵션 값인 파일 이름에 직접 '.gz'확장자를 붙여줘야 하는 것을 꼭 기억하셔야 합니다.

물론 사실 '-f' 옵션값으로 확장자 '.gz'를 까먹고, 'test.tar'라고 이름을 지어도 압축된 'test.tar'가 나오긴 합니다만

압축 해제, 즉 'gunzip'이나 'tar -zxf'를 쓸 경우엔 확장자가 '.gz'가 붙어있어야 인식을 하므로! '.gz'확장자를 붙여줍시다.(물론 실수로 안 붙여줬을 경우 이름 변경으로 끝에 .gz를 붙여주면 됩니다!)


ii) bzip2 사용법과 옵션 


"bzip2"란 '줄리안 시워드'란 사람이 만들어낸 압축 프로그램으로, 뒤에 '2'라는 이름이 붙듯이 기존 "bzip"라는 압축 프로그램의 업그레이드 버전이며,  gzip보다 압축률이 좀 더 좋습니다.

압축프로그램들은 모두 사용방법과 파일 이름 지어지는 메커니즘이 같습니다. 그러니 

'gzip'과 똑같이 압축할 때는


bzip2 [압축할 파일] 

이렇게 압축을 하면, 끝에 자동으로 ".bz2"확장자가 붙은 상태로 압축이 되며, 반대로 압축해제할 때는 gunzip과 마찬가지로!


bunzip2 [압축 해제할 파일] 

이렇게 쓰면 됩니다!

그리고~ 항상 압축프로그램은 'tar'와 같이 쓰기에, 당연하게도 'tar'에서 'bzip2 옵션' 있습니다! 바로 '-j'로 


tar -jcvf [파일이름.tar.bz2] [tar만들 파일들...]

이렇게 쓰시면 됩니다.

'gzip'이든, 지금의 'bzip2'든, 뒤에서 나올 'xz''tar'의 옵션으로 쓰일 때는 '-c''-x'맥락에 맞게 자동으로 압축이 되든가 해제가 됩니다.

'bzip2'도 'gzip'과 마찬가지로 직접 tar 파일을 만들 때, 이름 끝에 확장자 ".bz2"를 붙여줘야 하며, 그래야 압축 해제할 때 인식이 됩니다!

압축 해제는 'tar'의 '-x'옵션이미 해제와 같은 의미이므로, 


tar -jxvf [파이리름.tar.bz2] 

이렇게 그대로 'tar'의 기존 옵션에 '-j'만 붙여줘도 바로 tar -> bzip2압축 해제까지 일사천리로 됩니다!



iii) xz 사용법과 옵션 


"xz"는 "The Tukaani Project"라는 'slackware 계통 리눅스 배포판'에서 시작된 프로젝트로 만들어진 매우 효율적인 압축 프로그램입니다.

기존의 압축 프로그램이라 하면 'zip'란 단어가 꼭 들어가야한다는 고정관념이 우리에게 뿌리박혀있는데, 이 'xz'란 이름은 ... 참 당황스럽죠 ㅎㅎ

하지만 이런 이단아 같은 압축 프로그램 'xz'매우 효율적인 압축력 때문에 인기가 폭발적이였고, 결국 정식으로 GNU에서 채택이 됐으며, 현재까지도 대부분의 운영체제에서 애용하고 지원하는 훌륭한 압축 프로그램입니다.

'매우 효율적 압축'이란 말대로 gzip보다 압축률이 좋은 bzip2보다 더 압축률이 좋습니다. 

그래서

압축률은 gzip < bzip2 < xz 인 셈이죠.

이름은 이단같지만, 다행스럽게도 사용법은 다른 압축 프로그램과 같습니다!


xz [압축할 파일]

이렇게 말이죠. 압축이 되면 자동으로 확장자로서 '.xz'가 붙습니다.

압축 해제는 당연히~ 'un'을 붙인 xunz(이건 아니지..)가 아닌 'unxz'입니다. 

아쉽게도 이건 이단이네요 ㅋㅋ


unxz [압축 해제할 파일]

GNU에서 공식으로 인정받은 만큼, 'xz'도 당연히 'tar' 옵션이 있습니다!


그건 'bzip2(-j)'보다 좋다고 해서 대문자 '-J'입니다.

그래서 여타 다른 압축프로그램처럼 맥락에 맞게 tar의 '-c'와 '-x' 옵션과 함께 쓰시면 됩니다.


tar -Jcfv [tar파일.tar.xz] [tar만들 파일들...]

이렇게 만들 때나

tar -Jxfv [tar파일.tar.xz] 

이렇게 압축해제 할 때처럼 말이죠!


3. 총 정리


i) 리눅스 'tar(tape archive)'란 명령어는 여러 파일들을 하나의 파일로 묶어주는 명령어로, 이름에 'tape'가 들어가는 것처럼 원래는 자기테이프에 데이터를 저장하기 위해 사용하는 명령어였다.


ii) 'tar'의 명령어 형식은 tar [필수옵션+부가옵션] [묶을 파일들...] 이며 

---tar 필수옵션 종류---

-f(file name) [tar 파일이름] : 'tar' 파일 이름을 짓거나, 파일들을 뺄 'tar'파일을 지정하는 옵션으로, 무조건 붙여줘야함

+

-c(create) : create, 맨 뒤에 적은 여러 파일들을 이용해서 'tar'파일을 만들겠다.

-x(extract) : extract, 즉 'tar'파일에 들어있는 여러 파일들을 빼내겠다.

-r(renew) [추가할 파일들..] : renew(제가 끼워맞춘 영어), 즉 기존 'tar'파일에 새로운 파일들을 추가해서 갱신하겠다.

-t(list) : list, 즉 'tar'파일속 파일들을 펼쳐서 list형태로 보여줘라 

-------------------------

---tar 부가옵션 종류---

-v(verbose) : verbose(자세하게), 라는 뜻대로 진행정도를 보여줌

-C(Change{대문자} directory) [위치]: Change directory, 뜻 그대로 디렉토리를 이동하는 것으로, 옵션값으로 적은 위치로 디렉토리를 이동합니다. 

--------------------------


iii) 

-압축- 

gzip [압축할 파일] 형식으로 압축을 하며, 'gzip'을 사용해서 파일을 압축하면 자동으로 '.gz(gzip)'라는 확장자가 끝에 붙습니다.

bzip2 [압축할 파일] 형식으로 압축을 하며, 'bzip2'를 사용해서 압축하면, 자동으로 '.bz2(bzip2)'란 확장자가 끝에 붙습니다.

xz [압축할 파일] 형식으로 압축을 하며, 'xz'를 사용해서 압축하면, 자동으로 '.xz'확장자가 끝에 붙습니다.


-해제-

gunzip [압축해제할 파일], 압축해제를 하며, 확장자가 ".gz"로 끝나야 인식을 합니다.

bunzip2 [압축해제할 파일] 형식으로 압축 해제를 하며, 확장자가 '.bz2'로 끝나야 인식합니다.

xz [압축 해제할 파일] 형식으로 압축 해제하며, 확장자가 '.xz'로 끝나야 인식합니다.


-tar의 옵션값-

gzip == '-z(소문자)'

bzip2 == '-j(소문자)'

xz == '-J' 

로 각각 'tar'에서 맥락에 맞게, '-c'와 같이 쓰이면 압축하고, '-x'같이 쓰이면 압축해제 합니다.




후.. 오늘은 처음에 리눅스를 공부할 때 참 외울게 많아 보이고, 짜증나는 tar와 압축프로그램들에 대해서 알아보았는데요. 생각보다 쓸게 많아서, 저도 이 포스트를 쓰는데 하루에 7시간, 총 2일이나 걸렸네요 하하...

안타깝게도 'tar'리눅스를 사용한다면 무조건 알아야할 수준'vi'와 같은 프로그램이기 때문에 힘들어도 꼭 한번쯤 따라하며 전부다 읽어보셨으면 좋겠습니다.

긴 글 읽어주시느라 고생하셨고! 도움이 됐다면 따뜻한 댓글 달기 및 팔로우 클릭을 해주시면 저에게 큰 힘을 줘, 포스트 퀄리티 향상에 도움이 됩니다!

그럼 다음에 더 좋은 포스트로 찾아뵙겠습니다!