① 설치와 기본 명령어
이제 리눅스는 더 이상 소수 마니아들만을 위한 운영체제가 아니다. 신문 방송을 통해 리눅스의 존재가 많이 알려지면서 이제 리눅스는 일반인들도 들어본 적이 있는 단어가 되었고 그 범용성 또한 계속 확장되는 추세이다. 처음 소규모 서버 분야에서 조금씩 자리를 차지하기 시작한 리눅스는 이제 엔터프라이즈, 데스크탑 그리고 임베디드 분야까지 진출하고 있는 가장 잠재력이 높은 운영체제의 하나로 성장했다.
이에 따라 리눅스를 사용하는 사람들의 모습도 다양해지고 있다. 하지만 유닉스 클론인 리눅스의 근본적인 부분은 그 모습을 그대로 유지하고 있으며 새로운 변화 속에서도 든든한 기초의 역할을 꾸준히 계속해 오고 있다.
최근 들어 리눅스 데스크탑에 대한 관심이 높아지면서 윈도우에서 리눅스로 옮겨보고 싶어 하는 개발자들이 늘고 있는 듯하다. 하지만 이들 중의 상당수가 리눅스 설치 이후 실제 개발자에게 필요한 리눅스 셸 활용법이나 개발툴 활용 그리고 윈도우와는 다른 문화를 제대로 접해보지 못하고 있는 듯하다. 이번 연재에서는 이런 리눅스의 조금은 전통적인 사용 환경과 개발 환경을 하나씩 소개해 나가면서 개발자들에게 좀 더 도움이 되는 부분들을 다뤄보기로 한다.
리눅스를 써 보고 싶다면 리눅스를 설치해 보는 것이 가장 좋은 길이다. 그렇다면 리눅스는 어떻게 설치할 것인가? 이 질문은 간단해 보이면서도 많은 리눅스 사용자들을 혼란스럽게 하는 질문이다. 특히 리눅스와 같은 오픈소스 환경은 다양성이 주요한 장점인 까닭에 자신의 필요에 맞는 배포판을 자유롭게 선택해 마음껏 설정해 쓰는 것이 가장 바람직하겠지만 오픈소스에는 자유가 많은 만큼 선택의 괴로움 또한 증가하는 것이 사실이다.
게다가 최근 들어 네트워크의 지속적인 발전과 하드웨어 가격의 하락은 굳이 리눅스를 '깔아서 쓰지' 않고서도 잘 쓸 수 있는 환경이 나타나는 추세도 보인다. 일례로 Knoppix 배포판의 경우 부팅 가능한 CD-ROM 디스크 한 장에 리눅스 배포판을 담고 있는데 Knoppix 디스크를 만들어 사용하면 Knoppix CD-ROM을 단순히 부팅하는 것만으로도 리눅스 시스템을 쓸 수 있게 해준다. 비록 파일 시스템이 읽기 전용이라는 단점이 따라오기는 하지만 리눅스를 돌리기가 예전에 비해서는 훨씬 간단해진 셈이다.
또한 최근 웹 호스팅 서비스의 가격 하락으로 PHP와 같은 웹 프로그래밍 언어에 관심이 많은 사람이라면 공들여 PHP 프로그래밍 전용 서버를 하나 설치하는 것보다는 오히려 웹 호스팅 업체에서 제공하는 리눅스 계정을 약간의 비용을 들여서 하나 장만하는 것이 직접 자신의 컴퓨터에 리눅스를 설치하는 것보다 편리할 수도 있다.
하지만 전체적인 시스템에 대한 감을 잡기 위해서는 아무래도 스스로 직접 리눅스 서버를 설치해서 사용하는 편이 가장 지름길이다. 우선, 여기서는 개발자를 위한 리눅스 서버를 하나 장만하는 것을 위주로 해서 이야기를 엮어 나가 보도록 하자.
리눅스 시스템의 선택
개발자를 위한 리눅스 하드웨어는 그다지 높은 사양을 요구하지는 않는다. 요즘 일반화되어 있는 GHz대 CPU에 256MB 정도의 메모리만 있어도 리눅스를 쓰는 데는 무리가 없다. 다만 CPU의 속도가 빠르면 아무래도 컴파일할 때 시간이 덜 걸리고, 메모리가 많으면 하드디스크 스왑이 줄어든다는 장점이 있겠다.
리눅스 하드웨어의 호환성은 지금도 꾸준히 개선되고 있으며, 최근에는 리눅스를 처음부터 지원하는 하드웨어도 많이 출시되고 있다. 하지만 리눅스 환경은 하드웨어 호환성의 측면에서 여전히 윈도우 환경에 비해 모자란 면이 없지 않다. 특히, 그래픽카드의 지원은 아직도 상대적으로 많이 부족한데 새로 리눅스용 시스템을 만드는 경우에는 그래픽카드의 지원 상황은 반드시 체크해 보도록 하자.
필자의 경우는 보통 리눅스 문서 프로젝트(The Linux Documentation Project, www.tldp.org) 페이지의 Hardware-HOWTO 문서를 우선 참조한다. 또한, 최신 하드웨어의 호환성 여부 정보는 유즈넷 뉴스그룹을 참고하거나 유즈넷에 직접 질문을 포스팅해 보는 것도 좋다. 아무래도 영문권 사용자들은 지금도 뉴스그룹을 많이 이용하는 까닭에 사용자 수가 많고 원하는 답변을 얻게 될 확률 또한 그만큼 높은 편이다.
comp.os.linux 아래쪽 뉴스그룹을 주로 참고하는 것이 괜찮으며 하드웨어 호환성은 comp.os.linux.hardware에서 많이 다루는 편이다. 혹시, 뉴스그룹이 무엇인지 잘 모르는 사람은 구글에서 제공하는 뉴스 서비스인 구글 그룹 서비스(groups.google.com)를 이용해 보자.
구입하고자 하는 하드웨어의 정확한 호환성 여부에 관한 정보를 얻지 못하는 경우는 직접 리눅스 커널 소스코드를 다운받고(ftp://ftp.kernel.org), 커널 소스코드의 압축을 푼 다음 소스코드를 뒤져 보는 것도 괜찮은 선택이다. 보통 해당 디바이스의 드라이버 소스코드에는 코멘트로 현재 드라이버의 지원 상황이 적혀 있기 마련이며, C 언어를 잘 못하더라도 코멘트 문장을 읽기란 어렵지 않다. 예를 들어 네트워크 카드 드라이버들은 리눅스 커널 소스의 drivers/net 디렉토리에 들어가 있다.
배포판의 선택
이제 시스템을 장만했다면 설치할 배포판을 고를 차례이다. 리눅스 배포판은 소스코드가 공개되어 있는 리눅스의 특성상 수많은 종류가 있다. 그 중 많이 쓰이고 유명한 배포판들이 레드햇, 수세, 데비안, 젠투, 맨드레이크, 한컴 리눅스 등이다.
리눅스 배포판의 응용 프로그램 패키징
바이너리 패키징
이들 배포판의 특성을 전체적으로 분류해 보면 우선 응용 프로그램의 패키징 방식에 따라 배포판들을 나누어 볼 수 있다. 대표적인 패키징 방식은 리눅스 배포판의 양대 산맥 격인 레드햇의 rpm 형식과 데비안의 deb 형식이다. 레드햇의 배포판, 그리고 최근의 레드햇 페도라, 맨드레이크, 수세, 한컴 리눅스와 같은 배포판이 rpm 패키지를 사용하고 있다. 이에 반해 deb 형식은 데비안 배포판에 사용되고 있으며 데비안 이외에도 여러 배포판들에서 deb 형식을 도입하고 있다.
주지하다시피 윈도우 설치 패키지와는 달리 리눅스 배포판들의 설치 패키지는 의존성(dependency) 개념이 처음부터 고려되어 있다. 즉 어떤 응용 프로그램을 설치하려고 할 때 이 패키지가 다른 패키지가 기본으로 설치되어 있어야 실행될 수 있다면 패키지 시스템은 자동적으로 이럴 때 어떤 패키지들이 추가로 필요한 지를 사용자에게 알려준다.
예를 들어 리눅스 시스템에서 사용자가 어떤 자바 기반의 응용 프로그램 패키지 설치 명령을 내리면 그 리눅스 배포판의 패키징 시스템은 현재 시스템에 자바 런타임 패키지가 설치되어 있는지를 우선 체크하고, 자바 런타임이 있지 않은 경우에는 설치 작업을 더 이상 진행하지 않는다. 이 덕분에 리눅스 시스템은 윈도우보다 응용 프로그램의 유지보수 측면에서 시스템 관리가 한결 수월하다.
여기서 조금 더 나아가면 하나의 응용 프로그램 패키지를 설치할 때 자동적으로 필요한 패키지 리스트를 생성해 낼 수 있으면 좋을 것이고 가능하다면 이 리스트를 보고 직접 다운로드 작업까지 패키지 관리 프로그램이 알아서 처리해 주면 더욱 좋을 것이다.
이렇게 패키지 사이의 의존성을 자동으로 처리해 주는 패키지 관리자의 대표적인 것이 데비안의 APT(Advanced Package Manager, www.debian.org/doc/manuals/apt-howto)이다. APT를 사용하면 사용자는 패키지 다운로드나 설치를 수동으로 할 필요가 없이 단순히 설치할 패키지의 이름만 지정해 주면 시스템이 알아서 패키지 다운로드 및 설치, 업그레이드를 해주며, 심지어는 배포판 자체의 업그레이드까지도 가능하게 해준다. 많은 데비안 사용자들이 게시판에서 APT의 편리함을 패키지 설치 명령어 한 줄 짜리 답변으로 대신하는 경우를 여러분들도 간혹 보았을 것이다.
# apt-get install <패키지 이름>
APT의 경우에서 볼 수 있듯이 리눅스 배포판에서 이제 응용 프로그램 설치는 사용자가 원하는 패키지를 선택하면 시스템이 알아서 필요한 다른 패키지까지 알아서 다운받아 설치하는 형태로 변화되어 있다. deb뿐만 아니라 이제는 rpm에서도 마찬가지 경향이 나타나며 rpm에서는 이것이 yum이나 지미안(Ximian)의 Red Carpet과 같은 좀 더 쓰기 쉬운 패키지 관리 매니저로 나타나게 된다. 즉, 과거에는 rpm 방식과 데비안 배포판의 deb 패키징에 대한 비교가 많았지만 이제는 rpm이냐 deb이냐 혹은 소스 패키지이냐의 구분이 커다란 의미가 없는 방향으로 나아가고 있다.
리눅스 사용자의 입장에서는 어느 배포판이든 응용 프로그램을 설치하는 방법이 원하는 프로그램을 마우스로 선택하고 설치 버튼을 누르는 쪽으로 이미 통일됐기 때문이다. 다만, 설정 파일의 유지보수 측면이나 시스템을 내 마음대로 꾸미는(customization) 측면에서는 파일 단위의 의존성을 체크하는 rpm보다는 패키지 단위로 의존성을 체크하는 deb이 좀 더 우위에 있는 편이지만 실제 사용자의 입장에서 큰 차이는 존재하지 않는다.
하지만 전통적으로 rpm 기반의 배포판들은 레드햇, 수세, 맨드레이크와 같이 상용 업체들에서 만들어지는 경우가 많고 따라서 설치 작업이 쉬운 경우가 많으며 기본 데스크탑 설정도 깔끔하게 잘 되어 있다는 장점이 있다. 따라서 리눅스에 익숙하지 않은 사용자들은 아무래도 이런 상용 업체가 만든 배포판이 좀 더 쉽게 다가갈 수밖에 없다.
일단 설치가 쉽고 설정이 많이 필요하지 않는 레드햇과 같은 상용 배포판을 쓰면서 리눅스에 어느 정도 익숙해졌다고 생각하면 좀 더 다양한 가능성을 제공하는 데비안이나 여타 소스코드 패키지 기반의 시스템으로 넘어가는 것도 좋은 방법이다. 컴퓨터의 세계에서는 일반적으로 좀 더 최적화(customization)가 쉽고 동적(dynamic)인 시스템 구성이 가능할수록 사용자 입장에서 배워야 할 것이 많은 경향이 있을 수밖에 없다. 데비안의 경우 배포판 설치 작업을 좀 더 쉽게 하려는 여러 가지 노력이 계속되고 있으나 아무래도 다른 배포판에 비해 배울 것이 많은 편이다.
소스 패키지 기반의 배포판
리눅스와 같은 오픈소스 환경에서는 소스코드가 공개되어 있기에 프로그램을 설치할 때 직접 소스코드를 컴파일해서 설치하는 방식이 예전부터 자연스럽게 정착되었다. 게다가 소스코드 컴파일은 기본적으로 배포용 패키지가 플랫폼에 중립적인 경향이 강하며, 컴파일 된 바이너리가 시스템에 최적화될 수 있다는 장점을 갖고 있다.
하지만 사용자가 소스코드를 직접 손으로 컴파일하면서 수많은 응용 프로그램들을 모두 관리하는 것은 많은 시간과 노력을 들여야 할 뿐만 아니라 설치하는 패키지 숫자가 많아지면 패키지 관리가 무척 힘든 일이 될 것이다. 그러나 리눅스의 소스 패키지 기반 배포판들은 역시 바이너리 패키징과 마찬가지로 의존성 처리 기능을 갖추고 있으며, 그 대표 주자가 젠투 리눅스(gentoo.org, 이하 젠투)이다. 원래 소스코드를 가져와 컴파일을 해서 응용 프로그램을 설치하는 방식은 FreeBSD의 ports 시스템이 원조라고 할 수 있다.
ports는 소스코드를 직접 가져와 컴파일하면서도 패키지간의 의존성 정보를 알아서 처리해 주는데 리눅스에서는 젠투가 널리 쓰이고 있다. 젠투에서는 portage라는 소스 패키지 관리 프로그램을 사용하고 있는데 portage 역시 앞에서 본 데비안의 apt-get 만큼이나 패키지 관리가 편리하다. 다만 portage의 경우 소스코드 패키지를 다루기 때문에 패키지 설치 명령을 내리면 자동적으로 필요한 소스코드 패키지들을 다운받은 다음 소스코드 컴파일이 시작되는 차이점이 있다. 젠투에서 응용 프로그램 패키지를 설치하려면 다음 명령을 사용한다.
# emerge <패키지 이름>
젠투의 portage 시스템은 여기서 한술 더 떠 아예 다음과 같은 명령어도 가능하다. 이 명령은 실제 젠투 설치 과정의 일부인데 최소한도의 리눅스 사용이 가능한 젠투 base system을 구성하는 과정에서 쓰는 명령이다. 이 명령 하나로 가장 최근의 젠투 base system을 구성할 수 있으며, 이미 base system이 설치된 시스템에서는 업데이트까지 해결해 준다.
# emerge system
여담이지만, 최근 들어 얼핏 보기에 마니아층에 좀 더 적합할 것 같은 젠투가 많은 인기를 끌고 있는 주된 이유는 무엇일까? 필자 개인적인 경험에 비추어 볼 때 젠투의 매력은 다른 무엇보다도 실제 리눅스 시스템이 어떻게 구성되는지 그 과정을 하나하나 보여준다는 데 있는 것 같다. 소스코드 컴파일은 사실 오픈소스 운영체제를 쓰지 않으면 거의 접하기 힘든 경험이다. 대부분의 소스코드는 그냥 가져다가 ./configure; make; make install 명령어만 내리면 설치가 되기는 하지만 컴파일이 안 되는 경우도 많으며, 초보 사용자의 입장에서는 컴파일 에러를 만났을 때 에러 해결이 힘든 경우가 허다하다.
하지만 젠투 리눅스는 소스코드 패키지 설치를 거의 make && make install 수준으로 쉽게 만들면서도 실제 컴파일 과정을 모두 볼 수 있다. 또한 젠투의 설치 과정은 다른 배포판과는 달리 하나하나 손으로 명령을 입력해야 한다.
예를 들어, 네트워크 설정을 할 때 다른 배포판은 일반적으로 IP 주소와 게이트웨이, 네임서버 주소 등의 정보를 설치 프로그램의 대화상자에 입력하는 방식을 많이 쓰는데 젠투에서는 다음처럼 route add, ifconfig 명령을 써서 사용자에게 실제로 네트워크 설정을 직접 명령어를 타이핑해서 설정하도록 한다. 설치 메뉴얼을 프린트해 놓고 하나하나 따라하면서 설치를 진행하다 보면 덩달아 배우는 지식도 많아지는 재미가 있는 배포판이 젠투라고 할 수 있겠다.
# ifconfig eth0broadcast <브로드캐스트 주소> netmask <넷마스크> up
# route add default gw <게이트웨이 주소>
다만 젠투는 설치 과정이 직접 리눅스 명령어를 입력하면서 진행되기 때문에 유닉스 셸 프롬프트가 익숙하지 않은 초보자들에게는 적합하지 않으며, 패키지를 설치할 때 소스코드를 컴파일하기 때문에 시간이 많이 걸린다는 단점이 있다(참고로 젠투 최근 버전부터는 소스코드 컴파일 외에 바이너리 패키지 설치 방식도 같이 지원한다).
전체적으로(필자 개인적인 생각으로 볼 때) 젠투는 리눅스 시스템 설치 과정에서 리눅스 시스템 설정에 대해 많은 사항을 자연스럽게 배울 수 있게 해 주기 때문에 개발자들에게 가장 적합한 배포판이 아닐까 싶다. 특히 젠투에서 하드웨어 자동 인식을 갖추고 리눅스 커널 컴파일을 쉽게 해주는 genkernel(www.gentoo.org/doc/en/genkernel.xml)은 아직까지 리눅스 커널 컴파일을 해 보지 않은 사용자들에게 괜찮은 가이드가 될 수 있을 것이다. 시스템 최적화의 측면에서는 데비안도 아주 유연하지만 짧은 시간에 설치 작업만으로 시스템 관리와 설정에 관한 많은 것을 쉽게 배울 수 있게 해주는 젠투의 장점은 젠투만의 독보적인 특징이 아닐까 싶다.
리눅스 라이브 CD, Knoppix
최근 들어 CD 한 장으로 부팅해서 쓰는 리눅스 배포판이 많이 나오고 있다. 그 대표적인 것이 앞에서도 잠깐 언급했던 Knoppix(www.knoppix.net)인데 이러한 CD-ROM 부팅 방식의 배포판은 하드디스크를 비우고 채워 넣는 설치작업이 아예 필요 없다는 간편함이 큰 장점이다. 특히 하드디스크에 리눅스를 설치해 쓰는 경우라도 우선 배포판을 설치하기 전에 이런 리눅스 라이브 CD를 이용해서 쉽게 시스템 테스트를 해볼 수 있다는 점은 많은 도움이 된다.
Knoppix는 CD-ROM 방식이기 때문에 파일 시스템이 읽기 전용이고 기본적으로 시스템 설정을 고칠 수 없다는 단점이 있지만 여느 오픈소스 프로젝트들이 그렇듯이 그저 CD-ROM으로 부팅하는 리눅스 배포판이라는 기본적인 기능 외에 여기서 파생된 여러 가지 재밌는 아이디어들 또한 많이 구현되어 있다. 하드디스크의 조그만 FAT32 파티션에 Knoppix CD 이미지를 넣고 CD-ROM 대신 부팅을 해서 쓴다든가, Knoppix의 데스크탑 환경인 KDE를 빼고 GNOME을 집어넣은 Gnoppix 프로젝트라든가, 내 입맛에 맞는 설정을 플로피나 USB 메모리 드라이브에 저장해 놓고 매번 불러 쓰는 것과 같은 기능들이 이미 구현되어 있으니 관심 있는 독자들은 프로젝트 홈페이지를 한번 들러 보자.
리눅스의 설치
리눅스를 설치하기 전에, 준비한 시스템에 리눅스가 잘 작동하는지 테스트를 해보고 싶다면 방금 이야기한 Knoppix를 하나 준비하자. Knoppix CD 이미지를 다운받아 공 CD 하나에 구운 다음 Knoppix를 CD-ROM 부팅해 보면 대략 내 시스템에서 어떤 부품이 말썽을 피울 것인지 미리 짐작해 볼 수 있다.
구체적인 배포판의 설치 과정은 여기서는 생략하기로 한다. 이미 리눅스 설치의 편의성은 레드햇 구 버전부터 이미 윈도우보다 쉬워진 지 오래고 데비안이나 젠투와 같이 설치가 상대적으로 까다로운 배포판은 직접 프로젝트 홈페이지에서 문서 자료를 구하는 것이 좋기 때문에 굳이 설치까지 다룰 필요는 없을 것 같다. 다만 여기서는 배포판에 상관없이 설치 과정에서 걸리게 되는 파티션에 대한 개념과 리눅스 설치 이후 리눅스용 GUI 응용 프로그램을 원격으로 실행할 때 사용하는 X서버/클라이언트 개념에 대해 잠깐 짚어보고 넘어가도록 하자.
하드디스크 파티션 나누기
하드디스크를 왜 나누어 쓸까? 그 이유야 다양하겠지만 가장 쉽게 생각해 볼 수 있는 파티션 나누기의 이점은 분할해서 쓰기 때문에 필요한 부분만 다른 파티션에 영향을 주지 않고 내 맘대로 바꾸어 쓸 수 있다는 점이다.
예를 들어 윈도우에서 파티션을 하지 않고 하나의 하드디스크를 그냥 사용했다고 가정해보자. 윈도우 새 버전이 출시되었을 때 이 사용자가 새 버전의 윈도우를 깔끔하게 새로 설치하려면 그동안 저장된 사용자 문서나 여러 데이터 파일들을 잠시 백업받은 뒤 나중에 복구하거나, 혹은 임시 디렉토리라도 만들어서 거기에 데이터 파일들을 저장해 놓은 다음, 기존의 윈도우 디렉토리와 응용 프로그램 디렉토리들을 재주껏 지우는 과정을 거쳐야 한다.
하지만 이 사용자가 하드디스크를 이미 파티션해 놓았고, 파티션이 분리된 D: 드라이브에다가 항상 사용자 데이터를 저장하고 있었다면 얘기는 달라진다. 이 경우 새 윈도우를 설치하려면 그냥 C: 드라이브를 속 시원히 밀어버려도 D:의 사용자 데이터에는 전혀 이상이 없기 때문이다.
파티션을 나누는 또 하나의 주된 이유는 하나의 하드디스크에 2개 이상의 운영체제를 설치할 때이다. 이 경우는 운영체제마다 독립된 저장 공간이 필요할 테니 파티션을 이용하는 것이 가장 바람직한 방법이 될 것이다. 그렇다면, 2개의 운영체제가 하나의 하드디스크에 설치되어 있다고 할 때 이 하드디스크로는 어떻게 부팅을 해야 할까? 여기서 기본 파티션(primary partition)과 확장 파티션(extended partition)의 개념이 나오게 된다.
우선, 기본 파티션은 부팅이 가능한 파티션이라고 정의해 볼 수 있다. 그리고 여기서 하나 외워 둘 것은 기본 파티션은 하나의 하드디스크에 4개만 만들 수 있다는 제한 조건이다. 그렇다면 4개 이상의 기본 파티션이 필요한 경우는 어떻게 처리할까? 이 경우는 4개의 기본 파티션 중의 하나를 ‘더 쪼갤 수 있도록’ 설정한다. 이렇게 더 쪼개질 수 있도록 지정된 파티션이 확장 파티션이다.
즉, 기본 파티션은 원래 4개 밖에 만들 수 없도록 되어 있지만 그 중 하나를 맘대로 쪼갤 수 있도록 해서 실제로 4개 이상의 기본 파티션을 만들 수 있는 효과를 내는 것이다. 이 경우 우리가 쪼갤 수 있도록 지정한 파티션을 확장 파티션이라고 하며, 확장 파티션은 그 안의 조그만 파티션들을 담게 되는 큰 그릇 역할을 하게 되는 셈이다.
그런데 요즘은 윈도우 fdisk의 영향으로 기본 파티션을 보통 하나만 만들고 하드 디스크의 남은 부분은 자동으로 확장 파티션으로 지정해 버리는 방법이 많이 사용된다. 즉, 기본 파티션을 4개까지 만들다가 4개 이상의 파티션을 생성해야 할 일이 생기면 그 중 하나를 더 쪼개 쓸 수 있도록 지정하지 않고, 처음부터 만들어진 파티션 중 두 번째 파티션을 바로 확장 파티션으로 지정해 놓고 이 안에서 숫자의 제한 없이 파티션의 개수를 계속 늘려 나가겠다는 얘기이다. 하지만 이 방식이 리눅스를 설치하는 사용자의 입장에서는 약간의 혼동을 일으키게 된다는 문제가 있다.
우선, 기본 파티션만을 이용해서 리눅스를 설치하는 과정을 생각해 보자. 리눅스는 윈도우와는 달리 가상 메모리를 쓰기 위해 스왑 파티션이 필요하니 리눅스 전용 파티션 하나, 스왑 파티션 하나, 이렇게 2개의 파티션이 최소한으로 필요하다. 윈도우 듀얼 부팅을 위해 윈도우에도 파티션을 하나 줘 도합 3개의 파티션을 만들어 본다고 가정하자. 리눅스는 파일 방식으로 모든 하드웨어 장치를 가리키는데 일반적인 IDE 방식 하드디스크가 하나 설치되어 있다고 가정하면 이 하드디스크는 /dev/hda에 해당하며 여기서 한번 /dev/hda에 리눅스 fdisk로 파티션을 나누어 보자.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14000 51014407+ 83 Linux
/dev/hda3 14001 14063 506047+ 82 Linux swap
Command (m for help):
앞에서 볼 수 있듯이 생성되는 파티션은 /dev/hda2, /dev/hda3로 끝남을 알 수 있다. 윈도우용 파티션은 /dev/hda1으로 설정해 주었다. 그런데 여기서 하드디스크를 /dev/hda1, /dev/hda2 둘로 쪼갠 다음, 두 번째 기본 파티션인 /dev/hda2를 확장 파티션으로 지정해 보자.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
Command (m for help): n
Command action
e extended # 여기서 extended 선택
p primary partition (1-4)
.
.
(중간 생략)
.
.
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
Command (m for help):
그 다음, 이 그릇 역할을 하는 /dev/hda2 파티션을 잘게 쪼개어 보자. 쪼개진 파티션 각각을 논리 파티션(logical partition)이라고 한다.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
Command (m for help): n
Command action
l logical (5 or over) # logical을 선택한다.
p primary partition (1-4)
l
First cylinder (7650-14593, default 7650):
Using default value 7650
Last cylinder or +size or +sizeM or +sizeK (7650-14593, default 14593): 14500
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
/dev/hda5 7650 14500 55030626 83 Linux
.
.
(중간 생략)
.
.
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
/dev/hda5 7650 14500 55030626 83 Linux
/dev/hda6 14501 14563 506016 82 Linux swap
Command (m for help):
즉, 확장 파티션 그릇인 /dev/hda2 안에 생성된 자식 파티션들을 가리키는 파일 이름은 /dev/hda5, /dev/hda6, /dev/hda7 등이 됨을 볼 수 있다. 중간의 hda3, hda4가 생략된 조금 got갈리는 숫자 배열 방식이기는 하지만 한번 알아두면 편하니 머릿속에 꼭 넣어 놓도록 하자. <그림 1>에서는 하드디스크 파티션을 만들면서 기본 파티션만 쓴 경우와 확장 파티션을 쓴 경우를 다이어그램으로 간략화시켜 표현해 보았다.
몇 개의 파티션을 만들 것인가?
앞에서 잠깐 얘기했듯이 리눅스를 설치하기 위해서는 리눅스 전용 파티션 하나, 그리고 스왑 파티션 하나, 이렇게 최소 2개의 파티션이 필요하다. 하지만 파티션은 적절히 나누어 놓으면 나중에 업그레이드나 시스템을 변경할 일이 생길 때 무척 쉽게 대응할 수 있다.
유닉스 시스템의 재미있는 특징 중의 하나는 하드디스크를 마운트할 때 윈도우와 같이 C: D: E: 드라이브 이름을 주지 않고 디렉토리에 바로 마운트시켜 버린다는 점이다. 아래 df 명령 출력을 잠깐 보자. df는 남아있는 디스크 용량을 보여주는 명령어이고 -h는 MB, GB 단위로 용량을 출력하라는 옵션이다.
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hda1 3.9G 2.5G 1.3G 66% /
/dev/hdb1 39G 33G 4.3G 89% /home
/dev/hda2 15G 13G 1.4G 91% /home/foobar/backup
/dev/hdb2 18G 16G 1.2G 94% /usr
앞의 리눅스 시스템의 경우 물리적으로 2대의 하드디스크를 리눅스에서 가져다 쓰고 있으며, 첫 번째 하드디스크의 첫 번째 파티션은 리눅스의 루트(root) 파티션, 두 번째 파티션은 백업용인 /home/foobar/backup으로 쓰이고 있음을 알 수 있다. 두 번째 하드디스크의 첫 번째 파티션은 사용자 계정이 들어가는 /home 디렉토리에 그리고 두 번째 파티션은 응용 프로그램들이 주로 들어가는 /usr 디렉토리에 사용되고 있음을 볼 수 있다.
우선, 리눅스 시스템을 만들 때 사용자 계정이 들어가는 /home 디렉토리는 별도의 파티션으로 나누어 주는 것이 차후의 시스템 확장을 대비해 무척 편리하다. 리눅스를 완전히 새로 설치하는 경우가 생기더라도 /home 디렉토리가 별도의 파티션으로 빠져 있으면 리눅스 루트 파티션을 새로 포맷하고 리눅스를 설치한 다음 /home 디렉토리만 그냥 마운팅해 버리는 것으로 사용자 파일은 전혀 손상 없이 유지되기 때문이다.
그 다음으로 생각해 볼 것이 /boot 파티션이다. /boot 파티션은 굳이 안 만들어도 상관은 없지만, 리눅스 커널을 넣어두는 곳이라 하나쯤 분리해 놓는 편이 좋다. /boot 파티션이 분리되어 있으면 루트 파일 시스템에 오류가 생기더라도 커널 차원의 부팅에는 문제가 없기 마련이다.
/boot 파티션의 크기는 커널 이미지가 1MB가 안되는 편이니 수십MB 정도만 잡아도 충분하다. /var 디렉토리를 파티션으로 분리하면 어떤 점이 좋을까? /var 디렉토리 안에는 여러 종류의 로그(log) 파일과 메일 데이터가 저장된다. /var/log와 /var/spool/mail이 대표적인 예이다.
만약 /var 디렉토리가 파티션 분리되어 있지 않다면 특정 서버 프로세스의 로그 파일이 갑자기 넘치거나 덩치 큰 메일이 하드디스크를 채워버리는 경우 시스템의 루트 파티션에 더 이상 쓰기가 불가능하게 될 것이고 이것은 서버 동작의 정지로 이어진다. 하지만 /var 디렉토리가 분리되어 있으면 이 경우 /var 파티션이 가득 차기는 하지만 루트 파티션은 영향을 받지 않기 때문에 서버는 여전히 제 동작할 수 있다.
마찬가지로 응용 프로그램이 많은 경우 /usr 쪽을 분리해 내는 것도 생각해 볼 수 있을 것이다. 하지만 대규모 서버를 운영하기 전에는 지나치게 파티션을 많이 만들 필요 없다. 일반적인 개인 사용자의 입장에서 리눅스 파티션은 스왑 파티션, /, /home, /boot 정도만 해주면 충분하다고 보면 되겠다.
참고로 파일 시스템은 자동 에러 체킹 기능이 있는 저널링 파일 시스템을 사용하도록 하자. 일반적으로 많이 쓰이는 ext3, xfs, Reiserfs 정도를 사용하면 된다. 단, /boot 파티션은 심플한 것이 좋으니 어디서나 지원하는 ext2 파일 시스템으로 포맷해서 쓰는 것이 좋다.
세컨드 PC에서 리눅스
요즘은 세컨드 PC라는 말이 의외로 자주 등장하고 있는 것 같다. 새 PC를 장만하는 데 드는 비용이 지속적으로 하락하고 있고, VGA가 내장된 microATX 크기의 메인보드가 10만원이 채 안되는 가격을 형성하고 있으니 이제는 세컨드 PC도 사치가 아닌 시대가 찾아온 셈이다.
게다가 구형 취급을 당하는 1GHz CPU들의 성능은 사실 리눅스를 돌리기에는 남아도는 사양이다. 이런 이유로 여유가 닿는 대로 간단히 세컨드 PC로 리눅스 서버를 구성해서 개발 전용으로 쓰는 것도 괜찮은 아이디어이다. 그리고 리눅스 데스크탑이 비약적인 발전을 이루고 있긴 하지만 인터넷 익스플로러에 지나치게 최적화되어 버린 국내 인터넷 환경은 이미 윈도우 PC를 어느 정도는 쓰지 않을 수 없을 정도까지 상황이 악화되어 버리고 말았다. 아는 사람의 미니 홈페이지에 접속하기 위해 신용카드로 물건을 하나 주문하는 데도 윈도우와 인터넷 익스플로러가 있어야 하는 상황은 결코 정상은 아니지만, 이것이 짧은 시간 내에 해결될 것 같지는 않다.
리눅스에서는 X윈도우가 클라이언트/서버 구조이기 때문에 윈도우의 터미널 서버보다 쓰기 편한 터미널 서버/클라이언트 환경을 이용할 수 있다. 바로 옆의 리눅스 서버의 GUI 응용 프로그램의 디스플레이를 윈도우 PC로 당겨 쓰는 것은 무척 쉬운 일이며, 리눅스는 윈도우 XP 프로페셔널처럼 윈도우 시스템을 현재 누군가가 쓰고 있는 경우 터미널 클라이언트에서의 로그인 접속을 막아버리는 제한도 없다.
사용자 입장에서는 윈도우와 리눅스 두 환경을 한 데스크탑에서 쓸 수 있으니 상당히 편리하다. <화면 1>은 윈도우 XP에서 X윈도우 서버인 Xmanager를 설치하고 리눅스용 응용 프로그램들의 디스플레이를 윈도우 데스크탑에서 쓰고 있는 모습이다. 인터넷 익스플로러와 나란히 리눅스용 한텀, gnuplot, xlogo가 실행되어 있는 모습을 볼 수 있다.
많은 독자들이 이미 이 방법을 잘 사용하고 있겠지만 이제 어떻게 하면 리눅스용 GUI 애플리케이션들을 윈도우 데스크탑으로 끌어와서 디스플레이할 수 있는지 살펴보도록 하자. 게다가 X윈도우의 클라이언트/서버 구조는 일반적인 클라이언트/서버 구조를 이해하는 데 많은 도움을 준다.
클라이언트/서버 구조는 중간에 서비스라는 매개체를 넣고 생각하면 쉽다. 어떠한 서비스를 제공하는 쪽은 서버가 되는 것이고 그 서비스를 받는 쪽은 클라이언트가 되는 것이다. 어떤 사람들은 그냥 쉽게 메인프레임과 터미널의 확장, 혹은 웹 서버와 클라이언트 정도로 생각을 하는데 여기에 한번 X윈도우 서버와 클라이언트의 작동을 살펴보도록 하자.
우선 리눅스의 모든 X윈도우 응용 프로그램들은(KDE나 Gnome 응용 프로그램들을 모두 포함하여) X클라이언트이다. 그리고 윈도우 PC에서 작동하는 Xmanager나 XFree86과 같은 프로그램은 X서버이다. X서버는 X클라이언트의 디스플레이 서비스를 제공한다.
즉, X서버는 X클라이언트의 요청에 따라 X클라이언트의 모습을 화면에 그려내는 서비스를 제공하는 것이다. 그리고 X클라이언트는 X서버의 이런 디스플레이 서비스를 이용해서 자신의 모습을 화면에 표시할 수 있게 되는 것이다. 이 모든 구조가 클라이언트/서버 방식으로 구현되어 있으니 클라이언트와 서버는 완전히 분리될 수 있는 것이다.
그렇다면 사용자가 리눅스용 GUI 응용 프로그램들을 지금 쓰고 있는 컴퓨터에 디스플레이하려면 어떻게 해야 할까? 답은 X윈도우 서버를 현재 쓰고 있는 컴퓨터에 설치해서 사용한다는 것이다. 클라이언트/서버 환경에서 보통은 웹 브라우저와 같이 사용자는 클라이언트 프로그램을 쓰게 되는 경우가 많기에 이런 경우 왜 X클라이언트가 아니고 X서버를 내 데스크탑에 깔아야 하는지 잘 이해하지 못하는 경우가 많은 것 같다.
하지만 X서버는 X클라이언트에게 디스플레이 서비스를 제공하는 서버가 맞으며, 사용자에게는 데스크탑에 X클라이언트의 모습을 출력시켜 주는 기능을 제공하는 응용 프로그램인 것이다. 따라서 사용자는 X서버만 설치하면 OS에 상관없이 어디서나 리눅스 GUI 응용 프로그램들을 불러 쓸 수 있다는 얘기가 된다. 보통, 윈도우에서 많이 쓰이는 X서버로는 Exceed, Xmanager 그리고 공개인 XFree86이 있다.
Xmanager(www.netsarang.co.kr)의 경우 국산 프로그램으로 속도도 빠르고 평가판 다운로드가 가능하며 한글 폰트까지 내장되어 있어 편리하다. 윈도우용 XFree86은 공개라는 장점이 있지만 속도가 상대적으로 느리다는 단점이 있다. 이제 직접 리눅스용 X클라이언트를 윈도우 데스크탑에 띄워 보자. X클라이언트는 DISPLAY 환경 변수를 참조해서 X서버와의 연결을 시도한다. 즉, DISPLAY 환경 변수는 우리가 알아서 설정해 줘야 한다. 서버와 클라이언트의 구분에 유의하면서 다음 명령어들을 하나하나 실행시켜 보자.
여기서 ssh를 이용한 X11 forwarding 기능에 대해 잠깐 알아보자. 앞의 과정에서 DISPLAY 환경 변수를 세팅하기가 의외로 번거로울 수 있는데 X11 forwarding 기능을 이용하면 ssh로 접속을 시도할 때마다 이 DISPLAY 정보가 알아서 자동으로 세팅된다.
윈도우에서 cygwin에 포함된 ssh와 XFree86을 X서버로 쓰는 경우 /etc/ssh_config나 홈 디렉토리의 .ssh_config에 다음 2줄을 추가한다. Xmanager와 같은 X서버를 쓸 때는 연결 방식을 ssh로 설정하는 것으로 보통 충분하다.
Host <리눅스 서버의 IP 혹은 *>
ForwardX11 yes
이렇게 하면 DISPLAY 환경 변수 설정이 필요 없게 되며 특히 윈도우 데스크탑이 사설 IP를 쓰는 IP 공유기 뒤에 있고, 리눅스 서버가 IP 공유기 바깥에 있는 경우와 같이 DISPLAY 환경 변수 설정이 곤란한 상황에서 아주 유용하게 쓰인다.
리눅스의 사용, 유닉스 셸에서의 파일 관리
KDE와 GNOME과 같은 리눅스 데스크탑 환경의 발전의 영향으로 요즘은 리눅스를 쓰면서 처음부터 유닉스 셸을 접하는 사람들의 비율이 예전처럼 많지는 않은 것 같다. 아마도 터미널 방식의 커맨드 라인 인터페이스 (command line interface)가 불편할 것이라는 선입관이 많이 작용하는 이유도 상당할 것 같은데 개발자 입장에서 기본적인 유닉스 명령어는 필수이며 유닉스 셸은 조금만 익숙해지면 무척이나 쓰기 편한 인터페이스 환경이다. 파일 관리를 중심으로 가장 기본적인 유닉스 명령어들을 한번 더 체크해 보도록 하자.
파일 리스트 보기 - ls
가장 먼저 배우게 되는 유닉스 명령어의 대표격이다. 긴 파일 리스트를 보여주는 ls -l, 숨겨진 파일(리눅스에서 .로 시작하는 파일은 모두 숨겨진 파일이다)까지 보여주는 ls -al에 추가해서 디렉토리 뒤에는 /, 실행 파일 뒤에는 *, 심볼릭 링크(윈도우의 ‘바로가기’에 해당한다)에는 @를 붙여주는 -F 옵션까지를 기억해 두자. GNU ls에서는 한글 파일명이 잘 보이지 않는 경우 간혹 --show-control-chars 옵션을 쓰기도 한다. pwd는 현재 디렉토리를 알려주는 명령어이다.
$ pwd
/home/jwsohn
$ ls
Mail dragon.txt public_html storage www
bin hangul_fonts share swarm_for_fedora_core_1
doc man src temp
$ ls -F
Mail/ dragon.txt public_html@ storage/ www/
bin/ hangul_fonts/ share/ swarm_for_fedora_core_1/
doc/ man/ src/ temp/
$ ls -F bin
ex@ rview@ rvim@ vi@ view@ vim* vimdiff@ vimtutor* xxd*
파일 이름 자동 완성 기능, 디렉토리 옮겨 다니기 - cd
리눅스에서 많이 쓰는 bash와 tcsh에는 파일 이름 자동 완성(filename autocompletion) 기능이 있다. 파일 이름이 상당히 긴 경우 그냥 탭(tab) 키만 눌러 주면 쉘이 알아서 파일 이름을 사람 대신 타이핑해 주는 기능인데 여기에 일단 맛들이고 나면 심지어는 윈도우에도 bash를 깔게 될 정도로 그 마수에서 벗어나기가 쉽지 않다. 혹 아직까지 이 기능을 써 보지 않은 독자들을 위해서 간단한 예를 들어 보자. 앞의 파일 리스트에서 swarm_for_fedora_core_1 디렉토리에 들어가기 위해서는 다음과 같은 명령을 입력해야 한다.
$ cd swarm_for_fedora_core_1
모두 다 타이핑하려면 귀찮으니 이 경우 자동완성 기능을 이용하면,
s로 시작하는 디렉토리가 3개 있는데 만약 s만 타이핑하고 탭 키를 누르면 어떻게 될까?
참고로 윈도우와는 달리 리눅스에서는 디렉토리 이름에도 와일드카드를 쓸 수 있다.
cd 명령과 관련해서 점 1개(.)는 현재 디렉토리, 점 2개(..)는 한 단계 위의 디렉토리(parent directory), 그리고 ~ 는 사용자의 홈 디렉토리(보통은 /home/<사용자 계정>이다)임을 꼭 외워두자.
디렉토리 생성과 삭제 - mkdir, rmdir
말 그대로이다. mkdir, rmdir 뒤에는 복수 개의 디렉토리가 올 수 있다.
파일 복사 - cp
리눅스 명령어 중 복수 파라미터가 필요한 명령어는 반드시 두 번째 파라미터를 생략해서는 안 된다는 원칙이 있다. 파일 복사 cp는 원본 파일 하나, 복사된 파일 하나 해서 두 개의 파라미터를 가지는 대표적인 명령인데 우선 다음 예를 보면서 그 의미를 살펴보자. 다운받은 한글 폰트의 백업본을 만드는 과정이다.
$ cd hangul_fonts/
$ ls
iyagi.pcf.gz johabg16.pcf.gz johabp16.pcf.gz johabsm16.pcf.gz
iyagis16.pcf.gz johabm16.pcf.gz johabsg16.pcf.gz johabsp16.pcf.gz
$ cp iyagi.pcf.gz iyagi.pcf.gz.backup # cp 명령의 일반적인 형식
$ ls iyagi.pcf.gz*
iyagi.pcf.gz iyagi.pcf.gz.backup
$ cp iyagi.pcf.gz iyagis16.pcf.gz .. # 복수 개의 파일 복사. ..에 유의하자
$ cd ..
$ ls
Mail dragon.txt iyagis16.pcf.gz share swarm_for_fedora_core_1
bin hangul_fonts man src temp
doc iyagi.pcf.gz public_html storage www
mv
mv는 move의 약자라고는 하나 여러 가지 기능을 갖고 있다. 유닉스에서 파일 이름을 바꾸는 명령이 무엇이냐는 질문에 mv라고 대답하면 novice에서 user로 승급하게 된다는 농담도 있는데 실로 간단하면서도 여러 응용을 보여주는 참으로 재미있는 명령어이다. 역시 사용 예를 보자.
◆ 파일이나 디렉토리 이름 변경
$ mkdir backup
$ mv backup storage # backup을 storage로 변경
◆ 디렉토리를 통째 이동
$ ls
Mail bin dragon.txt man share storage temp
backup doc hangul_fonts public_html src swarm_for_fedora_core_1 www
$ cd storage
$ mv ../hangul_fonts ../doc . # 상위 디렉토리 두개를 현재 디렉토리로 옮김
$ ls -F
doc/ hangul_fonts/
별로 쓰일 일이 없을 것 같던 현재 디렉토리 기호 (.)가 유용하게 쓰이고 있음을 볼 수 있다. 윈도우 데스크탑에서 마우스 드래그앤드롭으로 폴더를 옮기는 것과 아주 흡사하다.
파일 지우기 - rm
파일을 삭제할 때는 rm 명령을 쓴다. -r 옵션을 쓰면 디렉토리도 지울 수 있다. 리눅스에서 rm 명령으로 한번 삭제한 파일은 복구가 되지 않으니 rm 명령을 쓰기 전에는 항상 여러 번 확인하는 습관을 들이는 것이 좋다.
심볼릭 링크 만들기 - ln -s
ln 명령에는 아예 심볼릭 링크를 의미하는 -s 옵션을 붙여 외워버리자. 심볼릭 링크는 윈도우 파일 매니저의 바로가기에 해당한다. ln -s 명령을 쓸 때는 항상 원본 파일/디렉토리 이름이 앞에, 만들어지는 심볼릭 링크가 뒤에 간다는 점을 잘 외워두자.
$ ln -s storage my_stuff
$ ls -ld storage my_stuff
lrwxrwxrwx 1 jwsohn jwsohn 8 5월 20 08:21 my_stuff -> storage
drwxr-xr-x 2 jwsohn jwsohn 4096 5월 20 08:08 storage
참고로 심볼릭 링크를 지워도 원본에는 영향이 없다.
$ rm my_stuff
$ ls -ld storage
drwxr-xr-x 2 jwsohn jwsohn 4096 5월 20 08:08 storage
개발자 입장에서 계속 살펴볼 리눅스
지금까지 간략히 개발자를 위한 리눅스 시스템과 배포판 선택시 유의할 사항, 기본 유닉스 명령어에 관해 알아보았다. 다음 글부터는 이번 글에 다루지 못한 고급 수준의 중요 유닉스 명령어와 시스템 관리 기초를 다지고 리눅스의 다양한 개발 환경을 어떻게 활용하는 것이 좋은지 개발자의 입장에서 계속 살펴보기로 한다. @
이에 따라 리눅스를 사용하는 사람들의 모습도 다양해지고 있다. 하지만 유닉스 클론인 리눅스의 근본적인 부분은 그 모습을 그대로 유지하고 있으며 새로운 변화 속에서도 든든한 기초의 역할을 꾸준히 계속해 오고 있다.
최근 들어 리눅스 데스크탑에 대한 관심이 높아지면서 윈도우에서 리눅스로 옮겨보고 싶어 하는 개발자들이 늘고 있는 듯하다. 하지만 이들 중의 상당수가 리눅스 설치 이후 실제 개발자에게 필요한 리눅스 셸 활용법이나 개발툴 활용 그리고 윈도우와는 다른 문화를 제대로 접해보지 못하고 있는 듯하다. 이번 연재에서는 이런 리눅스의 조금은 전통적인 사용 환경과 개발 환경을 하나씩 소개해 나가면서 개발자들에게 좀 더 도움이 되는 부분들을 다뤄보기로 한다.
리눅스를 써 보고 싶다면 리눅스를 설치해 보는 것이 가장 좋은 길이다. 그렇다면 리눅스는 어떻게 설치할 것인가? 이 질문은 간단해 보이면서도 많은 리눅스 사용자들을 혼란스럽게 하는 질문이다. 특히 리눅스와 같은 오픈소스 환경은 다양성이 주요한 장점인 까닭에 자신의 필요에 맞는 배포판을 자유롭게 선택해 마음껏 설정해 쓰는 것이 가장 바람직하겠지만 오픈소스에는 자유가 많은 만큼 선택의 괴로움 또한 증가하는 것이 사실이다.
게다가 최근 들어 네트워크의 지속적인 발전과 하드웨어 가격의 하락은 굳이 리눅스를 '깔아서 쓰지' 않고서도 잘 쓸 수 있는 환경이 나타나는 추세도 보인다. 일례로 Knoppix 배포판의 경우 부팅 가능한 CD-ROM 디스크 한 장에 리눅스 배포판을 담고 있는데 Knoppix 디스크를 만들어 사용하면 Knoppix CD-ROM을 단순히 부팅하는 것만으로도 리눅스 시스템을 쓸 수 있게 해준다. 비록 파일 시스템이 읽기 전용이라는 단점이 따라오기는 하지만 리눅스를 돌리기가 예전에 비해서는 훨씬 간단해진 셈이다.
또한 최근 웹 호스팅 서비스의 가격 하락으로 PHP와 같은 웹 프로그래밍 언어에 관심이 많은 사람이라면 공들여 PHP 프로그래밍 전용 서버를 하나 설치하는 것보다는 오히려 웹 호스팅 업체에서 제공하는 리눅스 계정을 약간의 비용을 들여서 하나 장만하는 것이 직접 자신의 컴퓨터에 리눅스를 설치하는 것보다 편리할 수도 있다.
하지만 전체적인 시스템에 대한 감을 잡기 위해서는 아무래도 스스로 직접 리눅스 서버를 설치해서 사용하는 편이 가장 지름길이다. 우선, 여기서는 개발자를 위한 리눅스 서버를 하나 장만하는 것을 위주로 해서 이야기를 엮어 나가 보도록 하자.
리눅스 시스템의 선택
개발자를 위한 리눅스 하드웨어는 그다지 높은 사양을 요구하지는 않는다. 요즘 일반화되어 있는 GHz대 CPU에 256MB 정도의 메모리만 있어도 리눅스를 쓰는 데는 무리가 없다. 다만 CPU의 속도가 빠르면 아무래도 컴파일할 때 시간이 덜 걸리고, 메모리가 많으면 하드디스크 스왑이 줄어든다는 장점이 있겠다.
리눅스 하드웨어의 호환성은 지금도 꾸준히 개선되고 있으며, 최근에는 리눅스를 처음부터 지원하는 하드웨어도 많이 출시되고 있다. 하지만 리눅스 환경은 하드웨어 호환성의 측면에서 여전히 윈도우 환경에 비해 모자란 면이 없지 않다. 특히, 그래픽카드의 지원은 아직도 상대적으로 많이 부족한데 새로 리눅스용 시스템을 만드는 경우에는 그래픽카드의 지원 상황은 반드시 체크해 보도록 하자.
필자의 경우는 보통 리눅스 문서 프로젝트(The Linux Documentation Project, www.tldp.org) 페이지의 Hardware-HOWTO 문서를 우선 참조한다. 또한, 최신 하드웨어의 호환성 여부 정보는 유즈넷 뉴스그룹을 참고하거나 유즈넷에 직접 질문을 포스팅해 보는 것도 좋다. 아무래도 영문권 사용자들은 지금도 뉴스그룹을 많이 이용하는 까닭에 사용자 수가 많고 원하는 답변을 얻게 될 확률 또한 그만큼 높은 편이다.
comp.os.linux 아래쪽 뉴스그룹을 주로 참고하는 것이 괜찮으며 하드웨어 호환성은 comp.os.linux.hardware에서 많이 다루는 편이다. 혹시, 뉴스그룹이 무엇인지 잘 모르는 사람은 구글에서 제공하는 뉴스 서비스인 구글 그룹 서비스(groups.google.com)를 이용해 보자.
구입하고자 하는 하드웨어의 정확한 호환성 여부에 관한 정보를 얻지 못하는 경우는 직접 리눅스 커널 소스코드를 다운받고(ftp://ftp.kernel.org), 커널 소스코드의 압축을 푼 다음 소스코드를 뒤져 보는 것도 괜찮은 선택이다. 보통 해당 디바이스의 드라이버 소스코드에는 코멘트로 현재 드라이버의 지원 상황이 적혀 있기 마련이며, C 언어를 잘 못하더라도 코멘트 문장을 읽기란 어렵지 않다. 예를 들어 네트워크 카드 드라이버들은 리눅스 커널 소스의 drivers/net 디렉토리에 들어가 있다.
배포판의 선택
이제 시스템을 장만했다면 설치할 배포판을 고를 차례이다. 리눅스 배포판은 소스코드가 공개되어 있는 리눅스의 특성상 수많은 종류가 있다. 그 중 많이 쓰이고 유명한 배포판들이 레드햇, 수세, 데비안, 젠투, 맨드레이크, 한컴 리눅스 등이다.
리눅스 배포판의 응용 프로그램 패키징
바이너리 패키징
이들 배포판의 특성을 전체적으로 분류해 보면 우선 응용 프로그램의 패키징 방식에 따라 배포판들을 나누어 볼 수 있다. 대표적인 패키징 방식은 리눅스 배포판의 양대 산맥 격인 레드햇의 rpm 형식과 데비안의 deb 형식이다. 레드햇의 배포판, 그리고 최근의 레드햇 페도라, 맨드레이크, 수세, 한컴 리눅스와 같은 배포판이 rpm 패키지를 사용하고 있다. 이에 반해 deb 형식은 데비안 배포판에 사용되고 있으며 데비안 이외에도 여러 배포판들에서 deb 형식을 도입하고 있다.
주지하다시피 윈도우 설치 패키지와는 달리 리눅스 배포판들의 설치 패키지는 의존성(dependency) 개념이 처음부터 고려되어 있다. 즉 어떤 응용 프로그램을 설치하려고 할 때 이 패키지가 다른 패키지가 기본으로 설치되어 있어야 실행될 수 있다면 패키지 시스템은 자동적으로 이럴 때 어떤 패키지들이 추가로 필요한 지를 사용자에게 알려준다.
예를 들어 리눅스 시스템에서 사용자가 어떤 자바 기반의 응용 프로그램 패키지 설치 명령을 내리면 그 리눅스 배포판의 패키징 시스템은 현재 시스템에 자바 런타임 패키지가 설치되어 있는지를 우선 체크하고, 자바 런타임이 있지 않은 경우에는 설치 작업을 더 이상 진행하지 않는다. 이 덕분에 리눅스 시스템은 윈도우보다 응용 프로그램의 유지보수 측면에서 시스템 관리가 한결 수월하다.
여기서 조금 더 나아가면 하나의 응용 프로그램 패키지를 설치할 때 자동적으로 필요한 패키지 리스트를 생성해 낼 수 있으면 좋을 것이고 가능하다면 이 리스트를 보고 직접 다운로드 작업까지 패키지 관리 프로그램이 알아서 처리해 주면 더욱 좋을 것이다.
이렇게 패키지 사이의 의존성을 자동으로 처리해 주는 패키지 관리자의 대표적인 것이 데비안의 APT(Advanced Package Manager, www.debian.org/doc/manuals/apt-howto)이다. APT를 사용하면 사용자는 패키지 다운로드나 설치를 수동으로 할 필요가 없이 단순히 설치할 패키지의 이름만 지정해 주면 시스템이 알아서 패키지 다운로드 및 설치, 업그레이드를 해주며, 심지어는 배포판 자체의 업그레이드까지도 가능하게 해준다. 많은 데비안 사용자들이 게시판에서 APT의 편리함을 패키지 설치 명령어 한 줄 짜리 답변으로 대신하는 경우를 여러분들도 간혹 보았을 것이다.
# apt-get install <패키지 이름>
APT의 경우에서 볼 수 있듯이 리눅스 배포판에서 이제 응용 프로그램 설치는 사용자가 원하는 패키지를 선택하면 시스템이 알아서 필요한 다른 패키지까지 알아서 다운받아 설치하는 형태로 변화되어 있다. deb뿐만 아니라 이제는 rpm에서도 마찬가지 경향이 나타나며 rpm에서는 이것이 yum이나 지미안(Ximian)의 Red Carpet과 같은 좀 더 쓰기 쉬운 패키지 관리 매니저로 나타나게 된다. 즉, 과거에는 rpm 방식과 데비안 배포판의 deb 패키징에 대한 비교가 많았지만 이제는 rpm이냐 deb이냐 혹은 소스 패키지이냐의 구분이 커다란 의미가 없는 방향으로 나아가고 있다.
리눅스 사용자의 입장에서는 어느 배포판이든 응용 프로그램을 설치하는 방법이 원하는 프로그램을 마우스로 선택하고 설치 버튼을 누르는 쪽으로 이미 통일됐기 때문이다. 다만, 설정 파일의 유지보수 측면이나 시스템을 내 마음대로 꾸미는(customization) 측면에서는 파일 단위의 의존성을 체크하는 rpm보다는 패키지 단위로 의존성을 체크하는 deb이 좀 더 우위에 있는 편이지만 실제 사용자의 입장에서 큰 차이는 존재하지 않는다.
하지만 전통적으로 rpm 기반의 배포판들은 레드햇, 수세, 맨드레이크와 같이 상용 업체들에서 만들어지는 경우가 많고 따라서 설치 작업이 쉬운 경우가 많으며 기본 데스크탑 설정도 깔끔하게 잘 되어 있다는 장점이 있다. 따라서 리눅스에 익숙하지 않은 사용자들은 아무래도 이런 상용 업체가 만든 배포판이 좀 더 쉽게 다가갈 수밖에 없다.
일단 설치가 쉽고 설정이 많이 필요하지 않는 레드햇과 같은 상용 배포판을 쓰면서 리눅스에 어느 정도 익숙해졌다고 생각하면 좀 더 다양한 가능성을 제공하는 데비안이나 여타 소스코드 패키지 기반의 시스템으로 넘어가는 것도 좋은 방법이다. 컴퓨터의 세계에서는 일반적으로 좀 더 최적화(customization)가 쉽고 동적(dynamic)인 시스템 구성이 가능할수록 사용자 입장에서 배워야 할 것이 많은 경향이 있을 수밖에 없다. 데비안의 경우 배포판 설치 작업을 좀 더 쉽게 하려는 여러 가지 노력이 계속되고 있으나 아무래도 다른 배포판에 비해 배울 것이 많은 편이다.
소스 패키지 기반의 배포판
리눅스와 같은 오픈소스 환경에서는 소스코드가 공개되어 있기에 프로그램을 설치할 때 직접 소스코드를 컴파일해서 설치하는 방식이 예전부터 자연스럽게 정착되었다. 게다가 소스코드 컴파일은 기본적으로 배포용 패키지가 플랫폼에 중립적인 경향이 강하며, 컴파일 된 바이너리가 시스템에 최적화될 수 있다는 장점을 갖고 있다.
하지만 사용자가 소스코드를 직접 손으로 컴파일하면서 수많은 응용 프로그램들을 모두 관리하는 것은 많은 시간과 노력을 들여야 할 뿐만 아니라 설치하는 패키지 숫자가 많아지면 패키지 관리가 무척 힘든 일이 될 것이다. 그러나 리눅스의 소스 패키지 기반 배포판들은 역시 바이너리 패키징과 마찬가지로 의존성 처리 기능을 갖추고 있으며, 그 대표 주자가 젠투 리눅스(gentoo.org, 이하 젠투)이다. 원래 소스코드를 가져와 컴파일을 해서 응용 프로그램을 설치하는 방식은 FreeBSD의 ports 시스템이 원조라고 할 수 있다.
ports는 소스코드를 직접 가져와 컴파일하면서도 패키지간의 의존성 정보를 알아서 처리해 주는데 리눅스에서는 젠투가 널리 쓰이고 있다. 젠투에서는 portage라는 소스 패키지 관리 프로그램을 사용하고 있는데 portage 역시 앞에서 본 데비안의 apt-get 만큼이나 패키지 관리가 편리하다. 다만 portage의 경우 소스코드 패키지를 다루기 때문에 패키지 설치 명령을 내리면 자동적으로 필요한 소스코드 패키지들을 다운받은 다음 소스코드 컴파일이 시작되는 차이점이 있다. 젠투에서 응용 프로그램 패키지를 설치하려면 다음 명령을 사용한다.
# emerge <패키지 이름>
젠투의 portage 시스템은 여기서 한술 더 떠 아예 다음과 같은 명령어도 가능하다. 이 명령은 실제 젠투 설치 과정의 일부인데 최소한도의 리눅스 사용이 가능한 젠투 base system을 구성하는 과정에서 쓰는 명령이다. 이 명령 하나로 가장 최근의 젠투 base system을 구성할 수 있으며, 이미 base system이 설치된 시스템에서는 업데이트까지 해결해 준다.
# emerge system
여담이지만, 최근 들어 얼핏 보기에 마니아층에 좀 더 적합할 것 같은 젠투가 많은 인기를 끌고 있는 주된 이유는 무엇일까? 필자 개인적인 경험에 비추어 볼 때 젠투의 매력은 다른 무엇보다도 실제 리눅스 시스템이 어떻게 구성되는지 그 과정을 하나하나 보여준다는 데 있는 것 같다. 소스코드 컴파일은 사실 오픈소스 운영체제를 쓰지 않으면 거의 접하기 힘든 경험이다. 대부분의 소스코드는 그냥 가져다가 ./configure; make; make install 명령어만 내리면 설치가 되기는 하지만 컴파일이 안 되는 경우도 많으며, 초보 사용자의 입장에서는 컴파일 에러를 만났을 때 에러 해결이 힘든 경우가 허다하다.
하지만 젠투 리눅스는 소스코드 패키지 설치를 거의 make && make install 수준으로 쉽게 만들면서도 실제 컴파일 과정을 모두 볼 수 있다. 또한 젠투의 설치 과정은 다른 배포판과는 달리 하나하나 손으로 명령을 입력해야 한다.
예를 들어, 네트워크 설정을 할 때 다른 배포판은 일반적으로 IP 주소와 게이트웨이, 네임서버 주소 등의 정보를 설치 프로그램의 대화상자에 입력하는 방식을 많이 쓰는데 젠투에서는 다음처럼 route add, ifconfig 명령을 써서 사용자에게 실제로 네트워크 설정을 직접 명령어를 타이핑해서 설정하도록 한다. 설치 메뉴얼을 프린트해 놓고 하나하나 따라하면서 설치를 진행하다 보면 덩달아 배우는 지식도 많아지는 재미가 있는 배포판이 젠투라고 할 수 있겠다.
# ifconfig eth0
# route add default gw <게이트웨이 주소>
다만 젠투는 설치 과정이 직접 리눅스 명령어를 입력하면서 진행되기 때문에 유닉스 셸 프롬프트가 익숙하지 않은 초보자들에게는 적합하지 않으며, 패키지를 설치할 때 소스코드를 컴파일하기 때문에 시간이 많이 걸린다는 단점이 있다(참고로 젠투 최근 버전부터는 소스코드 컴파일 외에 바이너리 패키지 설치 방식도 같이 지원한다).
전체적으로(필자 개인적인 생각으로 볼 때) 젠투는 리눅스 시스템 설치 과정에서 리눅스 시스템 설정에 대해 많은 사항을 자연스럽게 배울 수 있게 해 주기 때문에 개발자들에게 가장 적합한 배포판이 아닐까 싶다. 특히 젠투에서 하드웨어 자동 인식을 갖추고 리눅스 커널 컴파일을 쉽게 해주는 genkernel(www.gentoo.org/doc/en/genkernel.xml)은 아직까지 리눅스 커널 컴파일을 해 보지 않은 사용자들에게 괜찮은 가이드가 될 수 있을 것이다. 시스템 최적화의 측면에서는 데비안도 아주 유연하지만 짧은 시간에 설치 작업만으로 시스템 관리와 설정에 관한 많은 것을 쉽게 배울 수 있게 해주는 젠투의 장점은 젠투만의 독보적인 특징이 아닐까 싶다.
리눅스 라이브 CD, Knoppix
최근 들어 CD 한 장으로 부팅해서 쓰는 리눅스 배포판이 많이 나오고 있다. 그 대표적인 것이 앞에서도 잠깐 언급했던 Knoppix(www.knoppix.net)인데 이러한 CD-ROM 부팅 방식의 배포판은 하드디스크를 비우고 채워 넣는 설치작업이 아예 필요 없다는 간편함이 큰 장점이다. 특히 하드디스크에 리눅스를 설치해 쓰는 경우라도 우선 배포판을 설치하기 전에 이런 리눅스 라이브 CD를 이용해서 쉽게 시스템 테스트를 해볼 수 있다는 점은 많은 도움이 된다.
Knoppix는 CD-ROM 방식이기 때문에 파일 시스템이 읽기 전용이고 기본적으로 시스템 설정을 고칠 수 없다는 단점이 있지만 여느 오픈소스 프로젝트들이 그렇듯이 그저 CD-ROM으로 부팅하는 리눅스 배포판이라는 기본적인 기능 외에 여기서 파생된 여러 가지 재밌는 아이디어들 또한 많이 구현되어 있다. 하드디스크의 조그만 FAT32 파티션에 Knoppix CD 이미지를 넣고 CD-ROM 대신 부팅을 해서 쓴다든가, Knoppix의 데스크탑 환경인 KDE를 빼고 GNOME을 집어넣은 Gnoppix 프로젝트라든가, 내 입맛에 맞는 설정을 플로피나 USB 메모리 드라이브에 저장해 놓고 매번 불러 쓰는 것과 같은 기능들이 이미 구현되어 있으니 관심 있는 독자들은 프로젝트 홈페이지를 한번 들러 보자.
리눅스의 설치
리눅스를 설치하기 전에, 준비한 시스템에 리눅스가 잘 작동하는지 테스트를 해보고 싶다면 방금 이야기한 Knoppix를 하나 준비하자. Knoppix CD 이미지를 다운받아 공 CD 하나에 구운 다음 Knoppix를 CD-ROM 부팅해 보면 대략 내 시스템에서 어떤 부품이 말썽을 피울 것인지 미리 짐작해 볼 수 있다.
구체적인 배포판의 설치 과정은 여기서는 생략하기로 한다. 이미 리눅스 설치의 편의성은 레드햇 구 버전부터 이미 윈도우보다 쉬워진 지 오래고 데비안이나 젠투와 같이 설치가 상대적으로 까다로운 배포판은 직접 프로젝트 홈페이지에서 문서 자료를 구하는 것이 좋기 때문에 굳이 설치까지 다룰 필요는 없을 것 같다. 다만 여기서는 배포판에 상관없이 설치 과정에서 걸리게 되는 파티션에 대한 개념과 리눅스 설치 이후 리눅스용 GUI 응용 프로그램을 원격으로 실행할 때 사용하는 X서버/클라이언트 개념에 대해 잠깐 짚어보고 넘어가도록 하자.
하드디스크 파티션 나누기
하드디스크를 왜 나누어 쓸까? 그 이유야 다양하겠지만 가장 쉽게 생각해 볼 수 있는 파티션 나누기의 이점은 분할해서 쓰기 때문에 필요한 부분만 다른 파티션에 영향을 주지 않고 내 맘대로 바꾸어 쓸 수 있다는 점이다.
예를 들어 윈도우에서 파티션을 하지 않고 하나의 하드디스크를 그냥 사용했다고 가정해보자. 윈도우 새 버전이 출시되었을 때 이 사용자가 새 버전의 윈도우를 깔끔하게 새로 설치하려면 그동안 저장된 사용자 문서나 여러 데이터 파일들을 잠시 백업받은 뒤 나중에 복구하거나, 혹은 임시 디렉토리라도 만들어서 거기에 데이터 파일들을 저장해 놓은 다음, 기존의 윈도우 디렉토리와 응용 프로그램 디렉토리들을 재주껏 지우는 과정을 거쳐야 한다.
하지만 이 사용자가 하드디스크를 이미 파티션해 놓았고, 파티션이 분리된 D: 드라이브에다가 항상 사용자 데이터를 저장하고 있었다면 얘기는 달라진다. 이 경우 새 윈도우를 설치하려면 그냥 C: 드라이브를 속 시원히 밀어버려도 D:의 사용자 데이터에는 전혀 이상이 없기 때문이다.
파티션을 나누는 또 하나의 주된 이유는 하나의 하드디스크에 2개 이상의 운영체제를 설치할 때이다. 이 경우는 운영체제마다 독립된 저장 공간이 필요할 테니 파티션을 이용하는 것이 가장 바람직한 방법이 될 것이다. 그렇다면, 2개의 운영체제가 하나의 하드디스크에 설치되어 있다고 할 때 이 하드디스크로는 어떻게 부팅을 해야 할까? 여기서 기본 파티션(primary partition)과 확장 파티션(extended partition)의 개념이 나오게 된다.
우선, 기본 파티션은 부팅이 가능한 파티션이라고 정의해 볼 수 있다. 그리고 여기서 하나 외워 둘 것은 기본 파티션은 하나의 하드디스크에 4개만 만들 수 있다는 제한 조건이다. 그렇다면 4개 이상의 기본 파티션이 필요한 경우는 어떻게 처리할까? 이 경우는 4개의 기본 파티션 중의 하나를 ‘더 쪼갤 수 있도록’ 설정한다. 이렇게 더 쪼개질 수 있도록 지정된 파티션이 확장 파티션이다.
즉, 기본 파티션은 원래 4개 밖에 만들 수 없도록 되어 있지만 그 중 하나를 맘대로 쪼갤 수 있도록 해서 실제로 4개 이상의 기본 파티션을 만들 수 있는 효과를 내는 것이다. 이 경우 우리가 쪼갤 수 있도록 지정한 파티션을 확장 파티션이라고 하며, 확장 파티션은 그 안의 조그만 파티션들을 담게 되는 큰 그릇 역할을 하게 되는 셈이다.
그런데 요즘은 윈도우 fdisk의 영향으로 기본 파티션을 보통 하나만 만들고 하드 디스크의 남은 부분은 자동으로 확장 파티션으로 지정해 버리는 방법이 많이 사용된다. 즉, 기본 파티션을 4개까지 만들다가 4개 이상의 파티션을 생성해야 할 일이 생기면 그 중 하나를 더 쪼개 쓸 수 있도록 지정하지 않고, 처음부터 만들어진 파티션 중 두 번째 파티션을 바로 확장 파티션으로 지정해 놓고 이 안에서 숫자의 제한 없이 파티션의 개수를 계속 늘려 나가겠다는 얘기이다. 하지만 이 방식이 리눅스를 설치하는 사용자의 입장에서는 약간의 혼동을 일으키게 된다는 문제가 있다.
우선, 기본 파티션만을 이용해서 리눅스를 설치하는 과정을 생각해 보자. 리눅스는 윈도우와는 달리 가상 메모리를 쓰기 위해 스왑 파티션이 필요하니 리눅스 전용 파티션 하나, 스왑 파티션 하나, 이렇게 2개의 파티션이 최소한으로 필요하다. 윈도우 듀얼 부팅을 위해 윈도우에도 파티션을 하나 줘 도합 3개의 파티션을 만들어 본다고 가정하자. 리눅스는 파일 방식으로 모든 하드웨어 장치를 가리키는데 일반적인 IDE 방식 하드디스크가 하나 설치되어 있다고 가정하면 이 하드디스크는 /dev/hda에 해당하며 여기서 한번 /dev/hda에 리눅스 fdisk로 파티션을 나누어 보자.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14000 51014407+ 83 Linux
/dev/hda3 14001 14063 506047+ 82 Linux swap
Command (m for help):
앞에서 볼 수 있듯이 생성되는 파티션은 /dev/hda2, /dev/hda3로 끝남을 알 수 있다. 윈도우용 파티션은 /dev/hda1으로 설정해 주었다. 그런데 여기서 하드디스크를 /dev/hda1, /dev/hda2 둘로 쪼갠 다음, 두 번째 기본 파티션인 /dev/hda2를 확장 파티션으로 지정해 보자.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
Command (m for help): n
Command action
e extended # 여기서 extended 선택
p primary partition (1-4)
.
.
(중간 생략)
.
.
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
Command (m for help):
그 다음, 이 그릇 역할을 하는 /dev/hda2 파티션을 잘게 쪼개어 보자. 쪼개진 파티션 각각을 논리 파티션(logical partition)이라고 한다.
# fdisk /dev/hda
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
Command (m for help): n
Command action
l logical (5 or over) # logical을 선택한다.
p primary partition (1-4)
l
First cylinder (7650-14593, default 7650):
Using default value 7650
Last cylinder or +size or +sizeM or +sizeK (7650-14593, default 14593): 14500
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
/dev/hda5 7650 14500 55030626 83 Linux
.
.
(중간 생략)
.
.
Command (m for help): p
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/hda1 * 1 7649 61440561 7 HPFS/NTFS
/dev/hda2 7650 14593 55777680 5 Extended
/dev/hda5 7650 14500 55030626 83 Linux
/dev/hda6 14501 14563 506016 82 Linux swap
Command (m for help):
즉, 확장 파티션 그릇인 /dev/hda2 안에 생성된 자식 파티션들을 가리키는 파일 이름은 /dev/hda5, /dev/hda6, /dev/hda7 등이 됨을 볼 수 있다. 중간의 hda3, hda4가 생략된 조금 got갈리는 숫자 배열 방식이기는 하지만 한번 알아두면 편하니 머릿속에 꼭 넣어 놓도록 하자. <그림 1>에서는 하드디스크 파티션을 만들면서 기본 파티션만 쓴 경우와 확장 파티션을 쓴 경우를 다이어그램으로 간략화시켜 표현해 보았다.
VMWare, 가상 시스템 |
몇 개의 파티션을 만들 것인가?
앞에서 잠깐 얘기했듯이 리눅스를 설치하기 위해서는 리눅스 전용 파티션 하나, 그리고 스왑 파티션 하나, 이렇게 최소 2개의 파티션이 필요하다. 하지만 파티션은 적절히 나누어 놓으면 나중에 업그레이드나 시스템을 변경할 일이 생길 때 무척 쉽게 대응할 수 있다.
유닉스 시스템의 재미있는 특징 중의 하나는 하드디스크를 마운트할 때 윈도우와 같이 C: D: E: 드라이브 이름을 주지 않고 디렉토리에 바로 마운트시켜 버린다는 점이다. 아래 df 명령 출력을 잠깐 보자. df는 남아있는 디스크 용량을 보여주는 명령어이고 -h는 MB, GB 단위로 용량을 출력하라는 옵션이다.
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/hda1 3.9G 2.5G 1.3G 66% /
/dev/hdb1 39G 33G 4.3G 89% /home
/dev/hda2 15G 13G 1.4G 91% /home/foobar/backup
/dev/hdb2 18G 16G 1.2G 94% /usr
앞의 리눅스 시스템의 경우 물리적으로 2대의 하드디스크를 리눅스에서 가져다 쓰고 있으며, 첫 번째 하드디스크의 첫 번째 파티션은 리눅스의 루트(root) 파티션, 두 번째 파티션은 백업용인 /home/foobar/backup으로 쓰이고 있음을 알 수 있다. 두 번째 하드디스크의 첫 번째 파티션은 사용자 계정이 들어가는 /home 디렉토리에 그리고 두 번째 파티션은 응용 프로그램들이 주로 들어가는 /usr 디렉토리에 사용되고 있음을 볼 수 있다.
우선, 리눅스 시스템을 만들 때 사용자 계정이 들어가는 /home 디렉토리는 별도의 파티션으로 나누어 주는 것이 차후의 시스템 확장을 대비해 무척 편리하다. 리눅스를 완전히 새로 설치하는 경우가 생기더라도 /home 디렉토리가 별도의 파티션으로 빠져 있으면 리눅스 루트 파티션을 새로 포맷하고 리눅스를 설치한 다음 /home 디렉토리만 그냥 마운팅해 버리는 것으로 사용자 파일은 전혀 손상 없이 유지되기 때문이다.
그 다음으로 생각해 볼 것이 /boot 파티션이다. /boot 파티션은 굳이 안 만들어도 상관은 없지만, 리눅스 커널을 넣어두는 곳이라 하나쯤 분리해 놓는 편이 좋다. /boot 파티션이 분리되어 있으면 루트 파일 시스템에 오류가 생기더라도 커널 차원의 부팅에는 문제가 없기 마련이다.
/boot 파티션의 크기는 커널 이미지가 1MB가 안되는 편이니 수십MB 정도만 잡아도 충분하다. /var 디렉토리를 파티션으로 분리하면 어떤 점이 좋을까? /var 디렉토리 안에는 여러 종류의 로그(log) 파일과 메일 데이터가 저장된다. /var/log와 /var/spool/mail이 대표적인 예이다.
만약 /var 디렉토리가 파티션 분리되어 있지 않다면 특정 서버 프로세스의 로그 파일이 갑자기 넘치거나 덩치 큰 메일이 하드디스크를 채워버리는 경우 시스템의 루트 파티션에 더 이상 쓰기가 불가능하게 될 것이고 이것은 서버 동작의 정지로 이어진다. 하지만 /var 디렉토리가 분리되어 있으면 이 경우 /var 파티션이 가득 차기는 하지만 루트 파티션은 영향을 받지 않기 때문에 서버는 여전히 제 동작할 수 있다.
마찬가지로 응용 프로그램이 많은 경우 /usr 쪽을 분리해 내는 것도 생각해 볼 수 있을 것이다. 하지만 대규모 서버를 운영하기 전에는 지나치게 파티션을 많이 만들 필요 없다. 일반적인 개인 사용자의 입장에서 리눅스 파티션은 스왑 파티션, /, /home, /boot 정도만 해주면 충분하다고 보면 되겠다.
참고로 파일 시스템은 자동 에러 체킹 기능이 있는 저널링 파일 시스템을 사용하도록 하자. 일반적으로 많이 쓰이는 ext3, xfs, Reiserfs 정도를 사용하면 된다. 단, /boot 파티션은 심플한 것이 좋으니 어디서나 지원하는 ext2 파일 시스템으로 포맷해서 쓰는 것이 좋다.
세컨드 PC에서 리눅스
요즘은 세컨드 PC라는 말이 의외로 자주 등장하고 있는 것 같다. 새 PC를 장만하는 데 드는 비용이 지속적으로 하락하고 있고, VGA가 내장된 microATX 크기의 메인보드가 10만원이 채 안되는 가격을 형성하고 있으니 이제는 세컨드 PC도 사치가 아닌 시대가 찾아온 셈이다.
게다가 구형 취급을 당하는 1GHz CPU들의 성능은 사실 리눅스를 돌리기에는 남아도는 사양이다. 이런 이유로 여유가 닿는 대로 간단히 세컨드 PC로 리눅스 서버를 구성해서 개발 전용으로 쓰는 것도 괜찮은 아이디어이다. 그리고 리눅스 데스크탑이 비약적인 발전을 이루고 있긴 하지만 인터넷 익스플로러에 지나치게 최적화되어 버린 국내 인터넷 환경은 이미 윈도우 PC를 어느 정도는 쓰지 않을 수 없을 정도까지 상황이 악화되어 버리고 말았다. 아는 사람의 미니 홈페이지에 접속하기 위해 신용카드로 물건을 하나 주문하는 데도 윈도우와 인터넷 익스플로러가 있어야 하는 상황은 결코 정상은 아니지만, 이것이 짧은 시간 내에 해결될 것 같지는 않다.
리눅스에서는 X윈도우가 클라이언트/서버 구조이기 때문에 윈도우의 터미널 서버보다 쓰기 편한 터미널 서버/클라이언트 환경을 이용할 수 있다. 바로 옆의 리눅스 서버의 GUI 응용 프로그램의 디스플레이를 윈도우 PC로 당겨 쓰는 것은 무척 쉬운 일이며, 리눅스는 윈도우 XP 프로페셔널처럼 윈도우 시스템을 현재 누군가가 쓰고 있는 경우 터미널 클라이언트에서의 로그인 접속을 막아버리는 제한도 없다.
사용자 입장에서는 윈도우와 리눅스 두 환경을 한 데스크탑에서 쓸 수 있으니 상당히 편리하다. <화면 1>은 윈도우 XP에서 X윈도우 서버인 Xmanager를 설치하고 리눅스용 응용 프로그램들의 디스플레이를 윈도우 데스크탑에서 쓰고 있는 모습이다. 인터넷 익스플로러와 나란히 리눅스용 한텀, gnuplot, xlogo가 실행되어 있는 모습을 볼 수 있다.
많은 독자들이 이미 이 방법을 잘 사용하고 있겠지만 이제 어떻게 하면 리눅스용 GUI 애플리케이션들을 윈도우 데스크탑으로 끌어와서 디스플레이할 수 있는지 살펴보도록 하자. 게다가 X윈도우의 클라이언트/서버 구조는 일반적인 클라이언트/서버 구조를 이해하는 데 많은 도움을 준다.
클라이언트/서버 구조는 중간에 서비스라는 매개체를 넣고 생각하면 쉽다. 어떠한 서비스를 제공하는 쪽은 서버가 되는 것이고 그 서비스를 받는 쪽은 클라이언트가 되는 것이다. 어떤 사람들은 그냥 쉽게 메인프레임과 터미널의 확장, 혹은 웹 서버와 클라이언트 정도로 생각을 하는데 여기에 한번 X윈도우 서버와 클라이언트의 작동을 살펴보도록 하자.
우선 리눅스의 모든 X윈도우 응용 프로그램들은(KDE나 Gnome 응용 프로그램들을 모두 포함하여) X클라이언트이다. 그리고 윈도우 PC에서 작동하는 Xmanager나 XFree86과 같은 프로그램은 X서버이다. X서버는 X클라이언트의 디스플레이 서비스를 제공한다.
즉, X서버는 X클라이언트의 요청에 따라 X클라이언트의 모습을 화면에 그려내는 서비스를 제공하는 것이다. 그리고 X클라이언트는 X서버의 이런 디스플레이 서비스를 이용해서 자신의 모습을 화면에 표시할 수 있게 되는 것이다. 이 모든 구조가 클라이언트/서버 방식으로 구현되어 있으니 클라이언트와 서버는 완전히 분리될 수 있는 것이다.
그렇다면 사용자가 리눅스용 GUI 응용 프로그램들을 지금 쓰고 있는 컴퓨터에 디스플레이하려면 어떻게 해야 할까? 답은 X윈도우 서버를 현재 쓰고 있는 컴퓨터에 설치해서 사용한다는 것이다. 클라이언트/서버 환경에서 보통은 웹 브라우저와 같이 사용자는 클라이언트 프로그램을 쓰게 되는 경우가 많기에 이런 경우 왜 X클라이언트가 아니고 X서버를 내 데스크탑에 깔아야 하는지 잘 이해하지 못하는 경우가 많은 것 같다.
하지만 X서버는 X클라이언트에게 디스플레이 서비스를 제공하는 서버가 맞으며, 사용자에게는 데스크탑에 X클라이언트의 모습을 출력시켜 주는 기능을 제공하는 응용 프로그램인 것이다. 따라서 사용자는 X서버만 설치하면 OS에 상관없이 어디서나 리눅스 GUI 응용 프로그램들을 불러 쓸 수 있다는 얘기가 된다. 보통, 윈도우에서 많이 쓰이는 X서버로는 Exceed, Xmanager 그리고 공개인 XFree86이 있다.
Xmanager(www.netsarang.co.kr)의 경우 국산 프로그램으로 속도도 빠르고 평가판 다운로드가 가능하며 한글 폰트까지 내장되어 있어 편리하다. 윈도우용 XFree86은 공개라는 장점이 있지만 속도가 상대적으로 느리다는 단점이 있다. 이제 직접 리눅스용 X클라이언트를 윈도우 데스크탑에 띄워 보자. X클라이언트는 DISPLAY 환경 변수를 참조해서 X서버와의 연결을 시도한다. 즉, DISPLAY 환경 변수는 우리가 알아서 설정해 줘야 한다. 서버와 클라이언트의 구분에 유의하면서 다음 명령어들을 하나하나 실행시켜 보자.
- 윈도우즈 데스크탑에서 엑스 서버 실행
- telnet이나 ssh로 리눅스 컴퓨터 접속
- DISPLAY 환경변수에 윈도우즈 데스크탑의 아이피 주소와 디스플레이
번호를 설정. 보통 디스플레이 번호는 0번을 쓰면 된다.$ export DISPLAY=<윈도우즈 데스크탑 아이피 주소>:0.0
- 원하는 엑스 클라이언트 실행
$ xterm &
여기서 ssh를 이용한 X11 forwarding 기능에 대해 잠깐 알아보자. 앞의 과정에서 DISPLAY 환경 변수를 세팅하기가 의외로 번거로울 수 있는데 X11 forwarding 기능을 이용하면 ssh로 접속을 시도할 때마다 이 DISPLAY 정보가 알아서 자동으로 세팅된다.
윈도우에서 cygwin에 포함된 ssh와 XFree86을 X서버로 쓰는 경우 /etc/ssh_config나 홈 디렉토리의 .ssh_config에 다음 2줄을 추가한다. Xmanager와 같은 X서버를 쓸 때는 연결 방식을 ssh로 설정하는 것으로 보통 충분하다.
Host <리눅스 서버의 IP 혹은 *>
ForwardX11 yes
이렇게 하면 DISPLAY 환경 변수 설정이 필요 없게 되며 특히 윈도우 데스크탑이 사설 IP를 쓰는 IP 공유기 뒤에 있고, 리눅스 서버가 IP 공유기 바깥에 있는 경우와 같이 DISPLAY 환경 변수 설정이 곤란한 상황에서 아주 유용하게 쓰인다.
리눅스의 사용, 유닉스 셸에서의 파일 관리
KDE와 GNOME과 같은 리눅스 데스크탑 환경의 발전의 영향으로 요즘은 리눅스를 쓰면서 처음부터 유닉스 셸을 접하는 사람들의 비율이 예전처럼 많지는 않은 것 같다. 아마도 터미널 방식의 커맨드 라인 인터페이스 (command line interface)가 불편할 것이라는 선입관이 많이 작용하는 이유도 상당할 것 같은데 개발자 입장에서 기본적인 유닉스 명령어는 필수이며 유닉스 셸은 조금만 익숙해지면 무척이나 쓰기 편한 인터페이스 환경이다. 파일 관리를 중심으로 가장 기본적인 유닉스 명령어들을 한번 더 체크해 보도록 하자.
파일 리스트 보기 - ls
가장 먼저 배우게 되는 유닉스 명령어의 대표격이다. 긴 파일 리스트를 보여주는 ls -l, 숨겨진 파일(리눅스에서 .로 시작하는 파일은 모두 숨겨진 파일이다)까지 보여주는 ls -al에 추가해서 디렉토리 뒤에는 /, 실행 파일 뒤에는 *, 심볼릭 링크(윈도우의 ‘바로가기’에 해당한다)에는 @를 붙여주는 -F 옵션까지를 기억해 두자. GNU ls에서는 한글 파일명이 잘 보이지 않는 경우 간혹 --show-control-chars 옵션을 쓰기도 한다. pwd는 현재 디렉토리를 알려주는 명령어이다.
$ pwd
/home/jwsohn
$ ls
Mail dragon.txt public_html storage www
bin hangul_fonts share swarm_for_fedora_core_1
doc man src temp
$ ls -F
Mail/ dragon.txt public_html@ storage/ www/
bin/ hangul_fonts/ share/ swarm_for_fedora_core_1/
doc/ man/ src/ temp/
$ ls -F bin
ex@ rview@ rvim@ vi@ view@ vim* vimdiff@ vimtutor* xxd*
파일 이름 자동 완성 기능, 디렉토리 옮겨 다니기 - cd
리눅스에서 많이 쓰는 bash와 tcsh에는 파일 이름 자동 완성(filename autocompletion) 기능이 있다. 파일 이름이 상당히 긴 경우 그냥 탭(tab) 키만 눌러 주면 쉘이 알아서 파일 이름을 사람 대신 타이핑해 주는 기능인데 여기에 일단 맛들이고 나면 심지어는 윈도우에도 bash를 깔게 될 정도로 그 마수에서 벗어나기가 쉽지 않다. 혹 아직까지 이 기능을 써 보지 않은 독자들을 위해서 간단한 예를 들어 보자. 앞의 파일 리스트에서 swarm_for_fedora_core_1 디렉토리에 들어가기 위해서는 다음과 같은 명령을 입력해야 한다.
$ cd swarm_for_fedora_core_1
모두 다 타이핑하려면 귀찮으니 이 경우 자동완성 기능을 이용하면,
$ cd sw
$ cd sw [TAB] # 탭 키를 누른다.
$ cd swarm_for_fedore_core_1 # bash가 파일 이름을 대신 타이핑해 준다.
$ cd sw [TAB] # 탭 키를 누른다.
$ cd swarm_for_fedore_core_1 # bash가 파일 이름을 대신 타이핑해 준다.
s로 시작하는 디렉토리가 3개 있는데 만약 s만 타이핑하고 탭 키를 누르면 어떻게 될까?
$ cd s
$ cd s [TAB] # 탭 키를 누른다. bash가 비프음으로 파일명 중복을 알려준다.
$ cd s [TAB] # 탭을 한번 더 누른다. 중복 파일명이 보인다.
share storage
src swarm_for_fedora_core_1
$ cd sw # w를 하나 더 타이핑해 준다.
$ cd sw [TAB] # 이후로는 앞의 경우와 같다.
$ cd s [TAB] # 탭 키를 누른다. bash가 비프음으로 파일명 중복을 알려준다.
$ cd s [TAB] # 탭을 한번 더 누른다. 중복 파일명이 보인다.
share storage
src swarm_for_fedora_core_1
$ cd sw # w를 하나 더 타이핑해 준다.
$ cd sw [TAB] # 이후로는 앞의 경우와 같다.
참고로 윈도우와는 달리 리눅스에서는 디렉토리 이름에도 와일드카드를 쓸 수 있다.
$ cd ~ # ~를 생략하고 cd만 입력해도 된다.
$ pwd
/home/jwsohn
$ cd sw*
$ pwd
/home/jwsohn/swarm_for_fedora_core_1
$ pwd
/home/jwsohn
$ cd sw*
$ pwd
/home/jwsohn/swarm_for_fedora_core_1
cd 명령과 관련해서 점 1개(.)는 현재 디렉토리, 점 2개(..)는 한 단계 위의 디렉토리(parent directory), 그리고 ~ 는 사용자의 홈 디렉토리(보통은 /home/<사용자 계정>이다)임을 꼭 외워두자.
디렉토리 생성과 삭제 - mkdir, rmdir
말 그대로이다. mkdir, rmdir 뒤에는 복수 개의 디렉토리가 올 수 있다.
파일 복사 - cp
리눅스 명령어 중 복수 파라미터가 필요한 명령어는 반드시 두 번째 파라미터를 생략해서는 안 된다는 원칙이 있다. 파일 복사 cp는 원본 파일 하나, 복사된 파일 하나 해서 두 개의 파라미터를 가지는 대표적인 명령인데 우선 다음 예를 보면서 그 의미를 살펴보자. 다운받은 한글 폰트의 백업본을 만드는 과정이다.
$ cd hangul_fonts/
$ ls
iyagi.pcf.gz johabg16.pcf.gz johabp16.pcf.gz johabsm16.pcf.gz
iyagis16.pcf.gz johabm16.pcf.gz johabsg16.pcf.gz johabsp16.pcf.gz
$ cp iyagi.pcf.gz iyagi.pcf.gz.backup # cp 명령의 일반적인 형식
$ ls iyagi.pcf.gz*
iyagi.pcf.gz iyagi.pcf.gz.backup
$ cp iyagi.pcf.gz iyagis16.pcf.gz .. # 복수 개의 파일 복사. ..에 유의하자
$ cd ..
$ ls
Mail dragon.txt iyagis16.pcf.gz share swarm_for_fedora_core_1
bin hangul_fonts man src temp
doc iyagi.pcf.gz public_html storage www
mv
mv는 move의 약자라고는 하나 여러 가지 기능을 갖고 있다. 유닉스에서 파일 이름을 바꾸는 명령이 무엇이냐는 질문에 mv라고 대답하면 novice에서 user로 승급하게 된다는 농담도 있는데 실로 간단하면서도 여러 응용을 보여주는 참으로 재미있는 명령어이다. 역시 사용 예를 보자.
◆ 파일이나 디렉토리 이름 변경
$ mkdir backup
$ mv backup storage # backup을 storage로 변경
◆ 디렉토리를 통째 이동
$ ls
Mail bin dragon.txt man share storage temp
backup doc hangul_fonts public_html src swarm_for_fedora_core_1 www
$ cd storage
$ mv ../hangul_fonts ../doc . # 상위 디렉토리 두개를 현재 디렉토리로 옮김
$ ls -F
doc/ hangul_fonts/
별로 쓰일 일이 없을 것 같던 현재 디렉토리 기호 (.)가 유용하게 쓰이고 있음을 볼 수 있다. 윈도우 데스크탑에서 마우스 드래그앤드롭으로 폴더를 옮기는 것과 아주 흡사하다.
파일 지우기 - rm
파일을 삭제할 때는 rm 명령을 쓴다. -r 옵션을 쓰면 디렉토리도 지울 수 있다. 리눅스에서 rm 명령으로 한번 삭제한 파일은 복구가 되지 않으니 rm 명령을 쓰기 전에는 항상 여러 번 확인하는 습관을 들이는 것이 좋다.
심볼릭 링크 만들기 - ln -s
ln 명령에는 아예 심볼릭 링크를 의미하는 -s 옵션을 붙여 외워버리자. 심볼릭 링크는 윈도우 파일 매니저의 바로가기에 해당한다. ln -s 명령을 쓸 때는 항상 원본 파일/디렉토리 이름이 앞에, 만들어지는 심볼릭 링크가 뒤에 간다는 점을 잘 외워두자.
$ ln -s storage my_stuff
$ ls -ld storage my_stuff
lrwxrwxrwx 1 jwsohn jwsohn 8 5월 20 08:21 my_stuff -> storage
drwxr-xr-x 2 jwsohn jwsohn 4096 5월 20 08:08 storage
참고로 심볼릭 링크를 지워도 원본에는 영향이 없다.
$ rm my_stuff
$ ls -ld storage
drwxr-xr-x 2 jwsohn jwsohn 4096 5월 20 08:08 storage
개발자 입장에서 계속 살펴볼 리눅스
지금까지 간략히 개발자를 위한 리눅스 시스템과 배포판 선택시 유의할 사항, 기본 유닉스 명령어에 관해 알아보았다. 다음 글부터는 이번 글에 다루지 못한 고급 수준의 중요 유닉스 명령어와 시스템 관리 기초를 다지고 리눅스의 다양한 개발 환경을 어떻게 활용하는 것이 좋은지 개발자의 입장에서 계속 살펴보기로 한다. @
|
댓글 없음:
댓글 쓰기