서론

 컴퓨터를 접하고 이쪽에 흥미를 느끼게 되는사람들이 이쪽으로 파고들어가다보면 필연적으로 몇가지 큰 벽에 만나게 되어 그 다음을 어떻게 파고들어가야할지 막막해지고 힘들어 하게되는데 그 큰벽중 하나가 아마 리눅스일 겁니다..

 개인적으로 이놈의 리눅스란놈은 워낙 방대한 규모의 프로젝트다 보니 이걸 전체적으로 대강 설명하기도 힘들고, 이놈을 써보자고 인터넷 강의나 책을 보자니 너무 단편적인 지식만 보여줘서 이게 뭔지 감도 안잡히는 경우도 많다 생각되네요.

 가장 효과적으로 이 리눅스란놈을 알아가는 방법은 아마 직접 써보고 몸에 채득하는 방법밖에 없겠지만 이 과정을 좀더 수월하게 해보자 하는 생각에서 리눅스에 대한 글을 적어보려고 합니다..

 참고로 제목을 "뒤에서부터 알아보는 리눅스"라 써놓은 이유는 보통 일반적으로 터미널(까만색 도스박스)에 명령어를 처보고 이 명령어를 쳤을때 이런걸 할수 있다같은 즉각적인 결과물을 볼수있는 방법을 알려줬으니 이걸 이라 해보고 이와는 반대되는 커널 깊숙히 뭐가있어서 이런경로로 어찌어찌 된다 같이 즉각적인 결과물을 볼수 없는 방법을 뒤라 생각하고 썼기 때문이니 참고해주세요.

리눅스의 시작

 리눅스란 놈은 다들 알다싶이 "리누스 토발즈"가 심심해서 만들었고 그게 오픈소스로서 인기를 얻어서 지금과같이 커졌다고들 하지만 좀더 뒷사정을 들여다보면 이게 리눅스가 인기를 얻게된 전부는 아닙니다.

 리눅스의 인기는 여러가지 원인이 있겠지만 나 자신의 시각으로서는 (당시 지금의 리눅스 위치에 있던 유닉스의 여러 분파중 하나인) "BSD"라는 운영체제의 라이센스문제가 결정적인 역할을 했습니다.

 이 BSD라는 놈은 당시 엄청나게 많이 쓰이며 여러 상업분야에도 활발하게 쓰이던 놈인데 갑자기 AT&T가 라이센스 문제로 소송을거는 바람에 BSD자체가 무료로 마음대로 쓸수 없게 되버렸고 그 대체품으로 주목된게 바로 리눅스라는것이죠. (리누스 토발즈 본인도 386BSD만 쓸수 있었으면 리눅스를 만들 생각을 안했을거라고 인터뷰에서 밝혔습니다.)

 당연히 BSD의 대체품으로 사용되는 운영체제로서 리눅스는 BSD와 유사한 구조로 설계되고, 유사한 작동구조를 가지며, BSD에서 이용가능한 프로그램도 약간의 수정만 거치면 리눅스에서도 활용 가능하게 설계됬습니다.

 그리고 결정적으로 리눅스가 인기를 얻게된 사건은 GNU재단이 주도하는 GNU프로젝트가 사용할 운영체제로서 리눅스가 지목됬다는 것일겁니다. (GNU프로젝트는 대충 소프트웨어를 오픈소스로 사용하게 하자! 라는 느낌의 것으로 오픈소스 프로젝트의 시초쯤 됩니다)(사실 다른운영체제 쓸려고 했는데 개발이 늦어서 리눅스 사용하게 됬다는건 안비밀)

 사실 GNU재단의 지원을 받기 전까지 리눅스는 그렇게 훌륭하다고 할만할 물건까지는 아니였지만 GNU재단의 지원을 받아가며 안정성이나 성능같은부분이 많이 좋아졌고 BSD를 대체할 물건을 찾던 (HP나 SUN같은)대기업들이 GNU재단의 리눅스를 발견하게 되자 여기에 엄청난 지원금을 퍼부어주고 더 견고해지고 안정적이고 여러기능이 추가되다가 결국 나온것이 현재의 리눅스 라는것이죠.
(쉽게 정리하면 아무리 오픈소스라도 돈은 중요하고 기업의 이해관계가 일치해 기업으로부터 돈을 얻게되자 급성장한 프로젝트)

리눅스 커널이란 무엇인가?

 정확히말하면 리눅스라는 표현은 두가지 부분에서 조금 잘못됬습니다. 한가지는 리눅스가 아닌 GNU재단에서 제공하는 "GNU/리눅스"라 불러야 하는것이며 나머지 한가지는 리눅스란 리눅스 커널을 이용한 우분투나 페도라같은 모든 운영체제를 지칭하는 용어임으로 사실상 리눅스라는 개체는 존재하지 않기 때문입니다.

 그럼 리눅스 커널이란 무엇일까? 일단 운영체제는 대체로 다음도표와 같이 3가지 영역이 존재합니다.

유저단인터넷, 오피스, 아파치&nginx서버, BashShell, 터미널 같은 유저가 직접적으로 관여하고 사용하는곳
커널단유저단으로부터 들어온 요청을 해석해서 하드웨어를 조작한뒤 그에 걸맞는 응답을 다시 유저단으로 돌려주는곳
하드웨어단CPU, 그래픽카드, 랜카드, 사운드카드 같이 하드웨어부분

여기서 리눅스 커널은 이름에 나와있다 싶이 "커널"단의 소프트웨어를 의미합니다. 좀더 파고들어가보면

  1. 스케줄러와 같은 기능으로 여러분이 멀티프로세스 작업을 할때 각 프로세서에 CPU자원을 적절히 공급해줌
  2. 하드디스크를 읽어서 하드디스크의 정보를 파티션 형식에 맞게 해석해서 유저단에 제공해줌
  3. 랜카드의 정보를 읽어서 소켓형태의 통신수단을 제공해서 유저단에서 인터넷과의 통신을 수월하게 해주기도와줌
  4. IPC와같은 프로세서간 통신수단을 제공해줌
  5. 각 프로세서에 적당량의 메모리공간을 할당했다 회수해가기도 하고 SWAP영역을 적절이 활용함
  6. SELinux와 같은 기능으로 보안수단을 제공해줌
  7. ETC.....

 등등과 같은 대부분의 유저는 신경쓸일도 거의 없고 이런기능이 있는지도 모르고 쓰는사람이 더 많을정도의 역할을 해주는 놈이죠. 이 부분에 대한 내용은 워낙 방대해서 여기선 다루지 않고 이부분을 자세히 알지 못해도 리눅스를 사용하는데는 큰 지장없으므로 넘어가도록 하겠습니다.(사실 저도 대충 알뿐 자세히 아는건 아니라서...)

 참고로 리눅스 커널은 Kernel.org에서 다운받을수 있습니다. 이 리눅스 커널을 이용해 유저단만 새롭게 추가한 운영체제를 바로 리눅스 배포판이라 합니다.

배포판에대해 잠깐 말해보자면 리눅스를 커널로 삼고 유저단에 여러가지를 심어넣을것만으로도 이렇게 불릴 자격이 생기다보니 수없이 많은 종류의 배포판이 존재합니다. 그래도 이 수없이 많은 종류도 패키지 관리자의 종류에 따라 크게 두가지 흐름을 따르고 있는데 하나는 레드헷이고 나머지 하나는 데비안이죠. 이에 관한 설명은 조금 있다가......
리눅스는 어떻게 작동하는가?

 리눅스에대한 정의는 대충 알았다 치고 중요한건 이걸 어떻게 쓸수 있는가? 일겁니다. 리눅스 커널 혼자만 존재한다면 컴퓨터는 부팅이 되면서 리눅스커널이 자기자신을 메모리상에 올려놓기만 할뿐 그 이상의 역할은 아무것도 못할겁니다.

 이러한 커널과 소통하기위해 나온것이 바로 Shell(쉘)이란 놈입니다. 쉘이 무엇이냐고요? 바로 이런놈입니다.

전자의 경우 "그래픽 쉘" 후자의 경우 "명령줄 쉘"이라 불리며 유저랑 소통을하며 kernel에게 명령을 내리는 놈입니다..

참고로 후자의 "명령줄 쉘"은 저렇게 검은 화면을 의미하는게 아니라 저 문자열을 의미한다. 이 "명령줄 쉘"은 문자열만 처리하며 ssh, tty, terminal 과 같은 외부 프로그램을 통해 우리에게 보여주죠. 위 사진은 ssh를 통해 윈도상에서 putty로 본 명령줄 쉘의 모습

쉘의 정의는 "유저와 소통해가며 커널에 명령을 내리는 존재"정도 되는데 커널을 감싼다는 의미로 Shell(껍데기)이라 이름을 지었다고 하네요.

참고로 후자의 경우 리눅스 커널에 기본탑제되어있는 쉘인데 이 쉘을 바로 "베쉬 쉘"(Bash Shell)이라 부릅니다.(당연히 제작자 이름에서 따온겁니다)(GNU프로젝트의 프로그램중 하나)

우리가 리눅스 명령어를 배운다는건 보통 "베쉬 쉘"의 사용법을 배운다는 의미이며 은근히들 궁금해하는 "쉘스크립트"란 우리가 직접 쉘에 입력해줘야할 명령어들을 미리 텍스트파일에 써놓고 저장시켜놓은걸 말합니다. 물론 여기에 덤으로 쉘에서 지원하는 몇가지 함수들을 활용해 단순한 반복작업을 많이 간소화시킬수도 있습니다. (이에대해 궁금하면 "쉘 문법"정도의 단어를 검색해보세요. 튜토리얼 많이 나옵니다.)

베쉬 쉘은 어떻게 작동되는가?

리눅스를 다룰려 한다면 몇몇 예외는 존재하겠지만 보통 거의 필수적으로 "베쉬 쉘"이란놈을 다뤄야 할겁니다.

자세한 명령어는 인터넷 여기저기 널려있으니 알아서 상황에 맞게 공부해 주세요.

일단 베쉬쉘의 명령어는 2가지정도의 형태로 존재합니다.

  • 베쉬쉘자체의 명령어 : 쉘 자체가 지원하는 명령어이다. if,fi같은 연산자는 베쉬쉘자체가 지원하는 명령어이다. 그 외에 사용자가 allias를 통해 임의로 등록한 명령어도 지원된다.
  • 외부 프로그램의 이름 : 리눅스 명령어를 배우다보면 흔히 chmod, ls같은거부터 aptgcc같이 다양한명령어를 사용해볼것이다. 이는 베쉬쉘자체가 지원하는게 아니라 실행파일(윈도우에서 exe파일)들이며 대부분 /usr/bin /bin /usr/local/bin등에 존재한다. 베쉬쉘이 탐색하는 폴더를 알고싶다면 echo $PATH를 입력해보자.

일반적으로 여러분이 명령어를 입력하면 베쉬 쉘은 자신이 자체적으로 가지고 있는 명령어인지 확인해보고 해당되는 내용이 없으면 위에 언급한 /usr/bin /bin /usr/local/bin등의 경로에 존재하는 파일 이름과 매칭되는것이 있는지 확인해봅니다. 만약 있으면 해당 파일을 실행하고 없으면

bash: XXX: 명령어를 찾을 수 없음

같은 문구를 출력하게 되는겁니다.

여기서 리눅스 조금 해보신분들중 의문이 있으실분이 조금 있을텐데 예를들어 service apache start같은 명령어를 입력했을때는 어떻게 작동하는걸까요? (참고로 http서버중 하나인 apache 데몬을 실행하는 명령어입니다.)

이때 베쉬 쉘/usr/bin/service라는 프로그램을 실행하게 됩니다. 단 실행과 동시에 /usr/bin/service 에게 어떤 명령어를 통해 자신이 실행됬는지에대한 정보를 같이 넘겨줍니다.

int main(int argc,char* argv[])

흔히 C언어에서 많이 나오는 저 argcargv의 존재를 통해서 말이죠. (각각 argument count, argument vector의 의미를 가지며 굳이 저 이름을 쓸필요없이 변수 종류만 맞으면됨)

이경우 프로그램내부에서는 자신이 실행되면서 argc에는 3이 대입되있고 argv{"service", "apache", "start"}와 같은 내용이 대입되어 있습니다. 나머지는 각 프로그램에서 어떻게 구동될지 정해지는 것이죠.

참고로 이는 윈도우에도 사용되는 방식입니다. 흔히 연결프로그램이라는 방식으로 말이죠.

리눅스는 어떤 디렉토리 구조를 가지는가?
  1. 경로
    리눅스는 윈도우와 같이 C:\D:\로 시작하는 디렉토리구조를 가지지 않고 루트 디렉토리라 불리는 /로 시작하는 구조의 디렉토리구조를 가집니다. 리눅스는 윈도우처럼 각 파티션공간이 독립되있지 않고 여러 파티션을 특별한 경로 안에 마운트하는 방식으로 각 파티션공간에 접근할수 있습니다. 무슨소리인지 모르시겠지만 잠시후 설명해 드리겠습니다.

  2. 각 폴더의 역할
    배포판에따라 다르긴 하지만 보통 루트디렉토리속을 보면 몇몇개의 폴더를 볼수 있습니다.

    /bin리눅스 커널에서 사용하는 프로그램들이 있습니다. 기본적인 리눅스 명령어들(bash rm ls등등)에 해당되는 프로그램들이 여기 존재합니다.
    /devdevice의 약자로 커널과 연결된 하드웨어적인것들이 표시되는 "가상폴더"입니다. 외장하드부터 웹캠까지 여기 표시됩니다.
    /home리눅스 사용자들의 홈디렉토리가 존재하는곳입니다. 보통 유저가 로그인하면 이곳폴더가 현재폴더로 표시됩니다.
    /mntmount의 약자로 보통 자동으로 마운트되는 장소로 많이쓰입니다.
    /rootroot사용자를 위한 홈디렉토리입니다. /home에서 분리됬을뿐 역할은 같습니다.
    /sbin리눅스의 필수 바이너리파일(실행파일)이 존재하는곳입니다. 보통 부팅시 커널과 함께로딩되는경우가 많습니다. rebootshutdown같은 명령어도 이곳에 존재합니다.
    /sys시스템과 관련된 가상파일들이 많습니다. 실제 그 공간에 파일이 존재하지않고 램위에 올려져있는 가짜파일인경우가 많습니다. 컴퓨터의 fan속도부터 LED점멸패턴까지 이곳에서 정할수 있습니다.
    /usr리눅스 배포판을 제작할때 추가되는 프로그램은 보통 이장소에 저장되있습니다. 추가적으로 프로그램을 설치하는경우에도 보통 이장소에 설치됩니다.
    /boot부팅관련 파일들
    /etc보통 프로그램들의 설정파일이 이 장소에 저장되있는경우가 많습니다.
    /lib라이브러리들이 존재하는곳입니다. 윈도우로 따지만 Win32같은 공간입니다.
    /proc프로세서나 시스템정보등이 여기에 표시됩니다. 실제 이장소에 파일이 존재하지않고 램상에 존재합니다.
    /var보통 로그파일이나 mail등이 이곳에 저장됩니다.
    대충 이런역할들을 합니다.

  3. 마운트란 무엇인가?
    영어적으로 따지면 여기서는 올라타다정도의 의미로서 사용됩니다. 즉 특정 경로에 마운트될 파티션공간을 Mount(올려태우다)하는거죠. 위에서 말했다싶이 리눅스는 윈도우처럼 각 파티션공간이 (경로상으로) 독립적으로 존재하지 않습니다. 할려고만 한다면 /home/iwan이라는 디렉토리에 hdd란 이름으로 외장하드를 마운트시키고 그 속에다가 D드라이브를(리눅스에선 D드라이브란 개념이 없지만..) Data란 이름으로 마운트시켜 /home/iwan/hdd는 외장하드인데 /home/iwan/hdd/Data는 D드라이브가 되는 진풍경을 볼수도 있습니다.

    구체적으로 이걸 어떻게 실현하나 물으시면 일단 리눅스 커널은 자신이 인식 가능한 모든 하드웨어을 /dev란 공간에 표시해둡니다. 여기에는 하드디스크나 USB메모리등도 모두 포함되며 이렇게 인식된 저장공간들은 sda sdb mmcblk1같은 이름을 부여받고 실제로는 존재하지않고 RAM상으로만 존재하는 파일로서 /dev에 표시됩니다. 여러분이 하실것은 mount -t [포맷방식] [인식된 저장공간] [마운트할 경로]라는 명령어를 입력하면 되는거죠. 위의경우 mount -t ext4 /dev/sda /home/iwan/hdd이런식으로 입력하면 되는거죠.

    일반적으로 마운트할 경로는 /mnt상에 존재하게 합니다. (복잡해지지말라고)(저처럼 /home/iwan/hdd에다간 잘 안해요)

  4. 마운트는 왜하는가?
    저는 이부분에대해 상세한 내용은 모르지만 아마 처음에 유닉스가 개발될때 저장공간이 여러개 있을것을 생각안하고 개발해서 그렇지 않을까? 추측합니다.(마운트는 훗날 떔질로 생긴 개념) 리눅스는 그런 유닉스를 따라한것이고요.

    하지만 마운트란 개념은 제대로 사용하면 무척이나 편리한 도구입니다. 저의경우 서로 연동이 지원되지않는 외부프로그램들은 연동시킬때 이 마운트라는 개념을 자주 사용하는데 위의경우 특정 파티션을 특정 경로에 마운트 시키는 법만 보여드렸지만 Mount가 원래 올라타다란 의미를 가지다보니 특정경로를 특정경로에 마운트시키는법도 존재합니다. (mount --bind 검색해보세요)

    또 저장만 담당하는 서버가 따로 존재해 NFS를 사용해 정보를 읽어와 실직적인 저장공간은 없어도 연산작업을 해내게하는 구조의 컴퓨터를 만들때도 마운트라는개념이 꽤 유용하게쓰입니다.

권한이란?

리눅스를 사용하면 피할수없는것이 권한이란것입니다. 리눅스는 윈도우와는 다르게 다수의 유저가 동시에접속해 작업을 할수가 있는데 이렇게되다보니 문제가 생긴게 한 유저가 다른유저파일을 멋대로 수정하거나 엿본다라는 것이죠. 개인적인 용도로서는 이것은 큰 문제가 되진않지만 컴퓨터는 일부 대기업에 한대정도 있던시대에 개발된 유닉스에게 다른유저가 기업에게 민감한 내용은 수정하거나 엿볼수있다는것은 꽤 골치아픈일이었죠. 그래서 생긴것이 권한이란 개념이고 이는 BSD의 대체품으로 나온 리눅스에게도 그대로 이식됬습니다.

권한이란 소유자소유그룹이 정해저있는 한 파일에대해 소유자 본인, 소유그룹, 그외 각각에게 Read(읽기), Write(쓰기), eXecute(실행)를 각각 설정할수 있는걸 말합니다.(폴더의경우 Execute가 없음)

보통 755이나 600같은 숫자로 어떤 설정인지를 표시하는데 각 숫자가 의미를 가지는 방법은 다음과 같습니다.

  1. 백의자리 숫자는 소유자 십의자리숫자는 그룹 일의자리숫자는 그 외에대한 권한을 의미한다
    .
  2. 각 숫자는 2진법으로 4의자리숫자는 Read 2의자리숫자는 Write 1의자리숫자는 eXecute로 생각해 그 숫자를 십의자리숫자로 바꾼숫자이다.

    예를들면 RWX모든권한이 있으면 이진법으로 111이되고 이걸 십진법으로바꾸면 7이된다. 쓰기권한만 생략하면 이진법으로 101이되고 이걸 십진법으로 바꾸면 5가 된다.

예를들면 이사단그룹에 속해있고 회장님이란 유저가 소유자로 지정된 비자금.xlsx라는 파일이 있다 쳐봅시다. 회장님은 이 파일 권한을 770으로 설정했습니다. 그럼 회장님이사단그룹에 속한 모든 멤버들은 이 파일을 자유롭게 읽고 수정할수 있습니다. 반면 일반사원그룹에 속한 홍길동이는 이 파일을 읽지도 못하겠죠.

권한이란 위 예시와같은 경우에도 쓰이지만 바이러스감염을 방지할때도 쓰입니다. 예를들어 요즘 유행하는 랜섬웨어의 경우에도 랜섬웨어를 실행시킨 유저의 권한이 특정파일을 쓸수있는 권한이 되지못하면 랜섬웨어는 제대로 작동하지않게되고 파일은 암호화되지않을체 안전하게 있을수 있습니다.

참고로 이런 권한구조속에서 유일하게 ROOT유저만이 권한과 상관없이 어떤파일도 읽고 쓸수 있습니다. 그 파일이 SYSTEM과 관련된 파일이 아니라면요.

리눅스 배포판

리눅스에게는 수많은 배포판이 존재하지만 크게 두가지 부류로 구분할수 있습니다. 바로 데비안레드헷이죠. 이 분류의 기준은 패키지 관리자라는 놈입니다. 기존 리눅스는 어떤 프로그램을 설치하기 위해서는 컴파일이라는 과정이 거의 필수적으로 필요했습니다. 그 이유는 리눅스가 윈도우처럼 모두 통일된 아키텍쳐(x86)에서 작동된다는 보장이 있지 않기때문에 (리눅스는 arm, sparc, power에서도 구동됩니다.) 미리 컴파일된 프로그램을 배포한다는건 특정 플랫폼에서는 실행이 안된다는것을 의미합니다.

그런 경우를 방지하기위해 리눅스에서는 소스(Source)를 배포하는게 기본이 됬었으나...... 너무나도 많은 의존성 문제들이 이 수단이 그닥 좋지 않다는것을 증명해주었습니다.

의존성이란 특정프로그램이 다른프로그램에 의존해 실행되는것을 의미합니다. 대충 예로들자면 동영상 플레이어의경우 거의 대부분 "x264"라는 프로그램을 동해 "h.264"동영상을 디코딩합니다. 그 이유로는 x264의 소스가 공개되있지않고, 라이센스문제도있고, 새로개발하면 완성도가 떨어지는 등등의 이유가 있죠.

그런 문제를 해결하기위해 패키지 관리자라는 존재가 탄생했습니다. 대충 이걸로 프로그램을 설치하면 알아서 모든 의존성 프로그램들도 같이 검색해 의존성 프로그램들도 같이 자동으로 설치해줘 프로그램이 완벽하게 실행되도록 해주는 프로그램이죠.

데비안의 패키지 관리자apt이고 레드헷의 패키지 관리자RPM입니다. 이 두종류의 패키지 관리자가 가장 규모가 크고 안정성, 신뢰성이 높으며 커뮤니티도 꽤 활발해서 왠만한 리눅스는 이 두종류의 패키지 관리자중 하나를 택합니다.

참고로 데비안계열의 리눅스는 대표적으로 UBUNTU, Kali Linux등이 있고 레드헷계열의 경우 대표적으로 CentOS, Fedora등이 있습니다.

결론

리눅스에대해 이런부분 누가 알려줬으면 정말 쉽게 넘어갔을텐데......할만한 부분들은 다 적어봤습니다.

추가적으로 궁금한부분이 있으시면 댓글로 달아주세요.

(이 글은 나중에 새로운꺼리를 발견하면 수시로 추가 or 수정됩니다.)