==========================================================================================
-= 새로운 [최종 문서] 입니다. =-
약간의 수정과 추가 사항을 포함한 지금의 이 글을 최종 문서로 합니다.
죄송하지만 아래의 글을 다시 확인 하시기 바랍니다..
커널 컴파일 내용 이외의 글도 있으니, 많은 리눅스 사용자 분들에게 도움이 되기를 바랍
니다. ==========================================================================================
[ 허준의 커널 컴파일 보감 ]
작성자 : 류종훈 (queenrjh at chollian.net)
리눅스를 어느정도 사용한 사용자라면 커널 컴파일이라는 것을 접하고, 이에 빠지면 중
독증 환자 가 되어 버리는 것을 종종 목격하게 됩니다. 하지만, 처음 컴파일 하는 사람이나
어느 정도 맛을 본 사람도 프로그램밍을 할 줄 알거나 시스템에 대해 어느정도 알고 있는
사람이 아니라면, 마치 무슨 주문도 같은 명령을 내려 자신만의 우월함을 과시하듯 컴파일
시에 화면에 출력되는 메세지 를 즐겁게 바라보고 있는 마법사를 초보자들은 옆에서 부러
움으로 넋을 잃고 보게 됩니다. 저 또한 많은 것을 알고 있지는 않지만, 그런 심정을 느끼
는 분 들에게 도움이 되고자 쓰게 되었 습니다. 이 글이 커널 컴파일에 대해 모든 것이라
고 말하지는 않습니다. 하지만, 많은 분들에게 여러 리눅스 마법사들의 주문(?)을 조금이나
마 알아 듣기위한 번역서가 되길 바랍니다. -------------------------------------------------------------
----------------------------- * 이 글은 rpm 과 소스로 커널 컴파일 할 때의 두가지 경우 모두 설명
하겠습니다. 커널 컴파일 에 관심이 있어 그에 관련된 글을 읽어 보았거나, 한 번이라도
커널 컴파일을 해 본 경험이 있는 사람들을 위한 글입니다. 처음 커널 컴파일 할 때의 각
명령의 내용이 이해가 안가셨던 분들이나 명령을 무작정 외워서 커널 컴파일 했던 분들은
이 글이 아주 많은 도움이 될 겁니다. * 참고: 글 중에 '자동으로 되는 내용입니다' 또는 '
알아서 됩니다' 라는 식을 글을 보게 되는데, 간혹 글을 읽는 어떤 분께서 '그럼 뭐
하러 설명해 놨어?' 라고 하시는 분은 안 읽으셔도 됩니다. 위 에도 말씀 드렸지만
단순히 외워서 하는 '그냥 그렇게 하면 되는거야' 라는 식이 아닌 왜 그렇게 되고,
왜 그렇게 해야 하는지에 관점을 두어 쓴 글 임을 알립니다. ----------------------------------------
-------------------------------------------------- > 먼저 커널의 개요와 컴파일의 필요성에 대해 간
략히 설명을 하겠습니다. 커널이란 운영체제의 가장 핵심을 이루는 부분입니다. 도스에
서는 IO.SYS 와 MSDOS.SYS 이 그에 해당하고, 윈도우즈에서는 kernel32.dll 라는 파일이 기본적인
장치들의 구동과 입/출력을 담당 하는 부분이라는 것을 아시는 분은 다 아실겁니다.
일반적인 리눅스 배포판의 커널은 여러 다른 많은 종류의 하드웨어와 상당수의 설정들을
지원 해 야 하기 때문에 커널의 크기가 커지고, 사용하지 않는 기능이 많이 추가 되었으므
로 자신의 시스 템에 최적화되지 못해 퍼포먼스가 다소 떨어집니다. 이런 경우 필요한 사
항만으로 커널을 컴파일 해서 불필요한 기능들을 모두 제거하면 커널이 상당히 작아지고
성능에도 많은 향상을 가져올 뿐 만 아니라 기본 배포판에서는 없는 기능을 새로 추가할
수도 있습니다. 더구나 리눅스는 커널 소스가 공개되어 있기 때문에 최신 버젼의 소스를
가져와서 자신의 시스템 에 최적화하여 사용할 수 있다는 것도 아주 매력적인 일 입니다.
커널을 소스로 가져올 수 있는 공식 사이트는 ftp://ftp.kernel.org/pub/linux/kernel/ 입니다. 이
디렉토리 안에는 여러 버전 의 디렉토리들이 있는데 각 버젼의 디렉토리 안에는 두 종류(gz
ip, bzip2)로 압축된 커널 소스와 패치 파일이 있습니다. 원하는 버젼의 커널 소스를 가져
오면 됩니다. 하지만, 공식 사이트는 전세계의 사용자들로 인해 트래픽이 심하기 때문에
우리나라의 미러 사이 트를 이용하는 것이 속도가 빠릅니다. 우리나라의 커널 소스 미러
사이트는 ftp://ftp.bora.net /pub/linux/kernel/ 과 ftp://ftp.nuri.net/pub/Linux/kernel/pub/linux/kernel/ 이 있습
니다. 참고로, 현재 최신 버전은 안정 커널이 2.2.17pre-* 이고, 개발 커널은 2.4.0-test-* 입니다
. ------------------------------------------------------------------------------------------ 아래의 모든 작업
은 root 로 로그인 해서 해야 합니다. 참고로, 다음과 같은 명령으로 여러분의 커널 버젼을
확인해 볼 수 있습니다. [root@jegal jegal]#uname -r <-- 단순히 커널 버젼만 표시 합니다. '-a'
라는 옵 션도 한번 해 보세요..
rpm 으로 할 경우 커널 컴파일에 필요한 파일은 ftp://ftp.redhat.com 에서 받아오시면 됩니다.
일반 사용자인 경우 다 받을 필요는 없고, 다음의 두 개의 파일만 가져와서 설치하면 됩
니다. [root@jegal jegal]#rpm -Uvh --nodeps kernel-header-(커널버젼).i386.rpm
[root@jegal jegal]#rpm -Uvh --nodeps kernel-source-(커널버젼).i386.rpm
rpm 파일을 위와같이 -Uvh 옵션으로 설치할 경우 기존의 설치된 kernel-header 와 kernel-source
파일들을 자동으로 지우고 새 버젼의 파일로 대체 하게 됩니다. 그렇기 때문에 이전 버젼
의 커널 소스가 꼭 필요하신 분은 다른 이름으로 백업하시고, 새 버젼을 설치 하시기 바랍
니다. CPU 가 2개 이상일 경우에는 kernel-smp-(커널버젼).i386.rpm 파일을 받아와야 하고, 노트북
에서 리눅스를 실행 시키려면 전원 관리 기능을 제공하는 kernel-pcmcia-cs-(커널버젼).i386.rpm도
설 치해야 합니다. 소스로 설치 시에는 조금 다릅니다. 자세한 것은 나중에 설명 하겠
습니다. 위와 같이 두개의 파일을 설치 하는데 뒤의 --nodeps 옵션은 header를 풀려면 source가 s
ource를 풀려면 header 가 있어야 한다고 설치를 거부 하기 때문에 이 옵션을 주어 강제로 설
치 합니다. 설치를 하면 /usr/src/linux-(커널버젼) 라는 디렉토리가 생깁니다.
그리고, 기존의 linux 링크를 지우고, 다시 linux 라는 이름으로 linux-(커널버젼) 를 새로 링크
시킵니다. 참고로 rpm 으로 설치 시에는 자동으로 되는 내용입니다.
[root@jegal jegal]#cd /usr/src
[root@jegal src]#rm -rf linux
[root@jegal src]#ln -s linux-(커널버젼) linux
소스를 가져와서 컴파일 할 때는 이를 /usr/src 밑에 풀어줍니다. 압축을 풀면 위의 rpm 과는
반 대로 linux 라는 디렉토리에 압축이 풀립니다. 다음과 같이 합니다.
[root@jegal src]#tar xzvf linux-(커널버젼).tar.gz (압축이 bzip2일 경우는 xlvf 옵션을 준다)
[root@jegal src]#mv linux linux-(커널버젼)
[root@jegal src]#ln -s linux-(커널버젼) linux
그런데, 여기서 왜 꼭 linux 라는 링크를 만들어서 쓰는지 의구심을 갖는 분이 계실 겁니다.
반드시 꼭 이렇게 해야 하는 것은 아니지만, /usr/src 디렉토리 아래에 여러 버젼의 리눅스
커널 소스를 두고 작업을 할 때 편하게 하기 위해 linux-(커널버젼) 이라는 이름으로 각 각
컴파일 시 에 그냥 쓰기 보다는 간단히 linux 라는 이름으로 링크를 시켜두고 사용하면 편하
기 때문입니다. 그리고, 시스템의 심볼릭 링크가 새로운 커널 트리를 제대로 가리키고 있
는지 확인해야 합니다. 보통 rpm 파일이 아닌 소스를 풀어서 하는 경우에 해주어야 하는 것
이지만 레드햇 사용자의 경우 /usr/include 디렉토리에 아래처럼 링크를 해주지 않아도 기본
적으로 잡혀 있습니다. 확인 차 한 번 'ls -l asm linux scsi' 로 확인 해 보시고 안 되어 있다면,
아래와 같이 해 주시면 됩니다. [root@jegal src]# cd /usr/include
[root@jegal include]# rm -rf asm linux scsi
[root@jegal include]# ln -s /usr/src/linux/include/asm-i386 asm
[root@jegal include]# ln -s /usr/src/linux/include/linux linux
[root@jegal include]# ln -s /usr/src/linux/include/scsi scsi
위에 것은 왜 링크를 해주어야 하는 거냐고 질문을 하는 분도 계시 겠군요.. /usr/include 디
렉 토리는 표준 C 라이브러리 헤더 파일이 있는 중요한 디렉토리 입니다. 각 커널 소스에는
헤더 파 일이 딸려 오는데 컴파일 할 때 그 중에 asm linux scsi 디렉토리의 헤더 파일들을
불러 와야만 에러 없이 컴파일이 되는 경우가 있습니다.
시스템의 컴파일 환경 값으로 헤더 파일은 /usr/include 에서 불러 오기 때문에 커널 소스의
것 으로 링크를 해 주는 것입니다.
------------------------------------------------------------------------------------------
여러분의 시스템에 필요한 드라이버나 새로운 기능 또는 수정된 내용의 다양한 패치를 할
경우가 있습니다. 패치를 해야 할 경우에는 /usr/src/linux/scripts 디렉토리에 여러 단계의 패
치 작업 을 자동으로 실행하는 스크립트 patch-kernel 이 있습니다. /usr/src 아래에 가져다 놓
은 커널 패치 파일들과 커널 소스의 버전과 비교하여 patch-kernel 은 순서에 따라 알아서 패
치를 적용합 니다.
[root@jegal src]#/usr/src/linux/scripts/patch-kernel
하지만, 리눅서라면 자동으로 되는 것도 좋지만 직접 패치도 해 보는 것이 많은 도움이
될 겁니 다. 우선 패치 파일도 압축 파일로 되어 있습니다. 압축을 풀어서 사용해도 되고
압축된 파일을 바로 패치 하는 법도 있습니다. 패치 파일을 /usr/src 에 복사 한 후 다음과
같이 하면 됩니다. 아래는 압축을 풀지 않고 바로 패치 할 경우 입니다.
[root@jegal src]#gzip -cd newpatch.gzip | patch -p0 <-- 압축파일이 gzip 일 경우
[root@jegal src]#bzip2 -cd newpatch.bz2 | patch -p0 <-- 압축파일이 bzip2 일 경우
** 여기서 잠깐! : 간혹 패치 파일이 확장자만 .gz 인 경우가 있습니다. gzip 으로 압축을
풀 려고 해도 안 되었던 분들이 계실 겁니다. 편집기로 파일안을 한번 들여다 보시면, 압
축 파일이 아닌 패치 내용이 보일 겁니다. 이럴 경우는 그냥 확장자만 '.patch' 로 바꾸어서
아래의 내용을 참고로 패치 하세요. **
이번에는 압축을 풀고 패치를 할 경우 입니다. 먼저 압축을 풀어야 겠지요? 압축을 푼 패
치 파일 의 확장자는 .patch 나 .diff 끝나는게 대부분 입니다. 위와 마찬가지로 패치 파일이
/usr/src 디렉토리에 있을 경우입니다.
[root@jegal src]#patch -p0 < newpatch.patch
여기서도 의구심을 항상 갖고 계신분은 -p0 은 무얼까 하고 생각하시는 분이 계실 겁니다..
쓸데 없는 의심 빼고는 항상 궁금증을 갖고 계시는 분은 좋은 자세 입니다. 그럼, -p0 라는
것은 무엇 인지 알려 드리겠습니다. 그리고, 위 에서 패치 파일을 /usr/src/ 에 복사 하라고
했는데 왜 꼭 그곳에다 복사해야 했는 지도 궁금 하셨을 겁니다. 패치라는 것은 잘 아시
다 시피 어떤 곳을 고 치거나 수정하기 위한 것으로 바뀌어질 부분만을 포함 하고 있는 파
일 형식으로 되어 있습니다. 패치가 적용될 파일은 linux 라는 디렉토리 안에 있는 특정 파
일을 수정 해야 하기 때문에 linux 디렉토리로 직접 들어가지 않을 경우에는 -p0 라고 옵션을
주어야 제대로 패치가 되게 됩니다. 물론, 패치 파일 안의 설정이 linux 라는 경로 안의 특
정 파일들을 수정하도록 하기 위한 내용이 있기 때문에 그렇게 되는 겁니다.
그렇다면 -p1 은 무얼까요? 눈치가 빠른 분은 아셨겠지만 linux 디렉토리로 직접 들어가서
패치 할 경우에 사용 합니다. 사실 이렇게 주는 옵션은 패치를 만든 분의 설명 파일을
먼저 읽고 해 야 합니다. 보통 'README' 파일을 보거나 직접 .patch 파일 안을 직접들여다 보는
것도 좋습니다. 자.. 제목도 '커널 컴파일 보감' 이라고 썼으니 그에 해당하는 내용도 충실
해야 겠죠? 그렇다면, .patch 내용도 한번 훑어 봅시다..
=============================================================================
diff -urN v2.2.15/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.2.15/linux/arch/alpha/kernel/irq.c Wed May 3 17:16:30 2000
+++ linux/arch/alpha/kernel/irq.c Wed Jun 7 14:26:42 2000
@@ -896,7 +896,13 @@
unsigned long __init init_IRQ(unsigned long memory)
{
wrent(entInt, 0);
+
- alpha_mv.init_irq();
+
+ /* If we had wanted SRM console printk echoing early, undo it now. */
+ if (alpha_using_srm && srmcons_output) {
+ unregister_srm_console();
+ }
+
return memory;
}
=============================================================================
맨위의 diff 라는 것이 보이는데 이 것은 패치 파일을 diff 명령에다 -urN 옵션을 주어 만들었
다 는 것을 나타 냅니다. diff 명령은 두 파일간의 차이점을 추출해 주는 정말 똑똑한 명령
입니다. diff 명령의 사용법을 간략히 알려 드리기 전에 왜 그 것이 필요한지 설명을 좀 하
겠습니다. 만일 'komputa' 라는 디렉토리 밑에 소스 파일이 있고, 그 디렉토리 안에 몇가지
내용을 어떤 이 유(버그나 기능 개선등..)로 수정한 후 tar 로 묶고, 압축을 해서 배포를 한
다고 가정 합니다. 그럼, 그 이전에 배포한 소스를 받아서 사용 중인 사람은 새로 수정된
소스의 용량이 얼마 되지 않는다고 하면, 다시 새로 받는 것은 문제도 되지 않지만, 소스
의 용량이 10 메가 이상이 된다면 모뎀 사용자들은 눈물을 흘려야 겠지요? 그래서, 소스
개발자나 버그 패치를 한 분은 바뀌어진 부분만 diff 명령으로 따로 추출해서 배포하고,
사용자들은 위에 설명한 patch 명령으로 수정하 면 되지요.. 정말 합리적이지 않나요?
여러분은 아직까지도 전 세계적으로 모뎀 사용자가 그것도 14,400bps 으로 사용하는 분이 아
직도 많다는 것을 아시면 놀랄겁니다.. 그걸 보면, 우리나라는 인터넷 선진국임에 틀림
없습니다. 초 고속 인터넷을 쓰는 집이 하루 하루 늘어가는 것을 보면...
그럼, diff 명령을 한번 알아 보죠.. 위에서 예로 설명한 'komputa' 라는 디렉토리를 다시 한
번 예로 들어 보겠습니다. 단, 중요한 것은 수정 되기 전의 파일과 수정 한 파일을 따로
갖고 있어 야 한다는 것입니다. 그래야 아무리 똑똑한 diff 명령이라도 둘 중의 차이점을 비
교해서 패치 파 일 이란걸 만들지 않겠습니까? 아래의 예에서 'komputa' 는 디렉토리이고,
그 안에 소스들이 있 다고 가정합니다.
[root@jegal jegal]#cp -r komputa komputa.org <-- 먼저, 원본 소스 디렉토리를 다른 이름으
로 복사 합니다.
그리고, 새로 수정 되어질 디렉토리인 'komputa' 안의 소스들을 수정합니다. 수정을 다 하셨
다면 다음과 같이 diff 명령을 내립니다.
[root@jegal jegal]#diff -urN komputa.org komputa > newpatch.patch
여기서 한가지 주의 해야 할 것은 komputa 디렉토리 밖으로 나와서 해야 합니다. 이 것은 위
에서 도 언급 했지만, 패치 시에 -p0 옵션을 주느냐.. 아니면, -p1 옵션을 주느냐의 민감한 차
이로 바 뀌기 때문 입니다.
위와 같이 하면 저 위의 예제로 보인 내용과 비슷한 내용의 패치 파일이 만들어 지는 것을
볼 수 있습니다. 이제 여러분도 패치 파일을 만들고, 패치도 적용할 수 있는 초보 마법사
가 된 것 입니 다. 위의 옵션중 '-u' 는 패치 파일의 내용을 일정 형식으로 생성하라는 것
이고, 'r' 옵션은 하 부 디렉토리의 수정된 소스 파일도 적용하라는 것이며, 마지막의 'N' 옵
션은 새로운 이름으로 생 성 하라는 것입니다.
마법사가 되기위한 길은 거져 먹을 만큼 쉬운 것이 아닙니다. 이 옵션을 직접 그 흔한 'hell
o' C 소스 파일을 원본 파일과 수정 파일을 하나씩 만들어서 직접 테스트 해 보세요. 옵션
을 주고 안 준 차이가 과연 무엇인지를.. 좋은 경험이 될 것입니다. 지금 바로 해 보세요
..
; 옵션 얘기가 나와서 말인데.. 참고로, 위의 예를 다시 들어 간혹 -urN 과 -u -r -N 이렇
게 따로 내릴 경우를 보게 되는데, 리눅스에서는 특별하게 달리 만들어진 프로그램이 아
닌 경우를 빼고 는 같은 것입니다. 또한, 옵션 중에 앞에 '-' 표시를 두개 붙인 '--force'
와 같은 옵션은 GNU 의 산물로써 GNU 에서 제작된 프로그램들은 알파벳 1개로 된 옵션 이외에
사람이 이해 하기 쉬운 단어 형식으로 된 옵션을 지원하므로, 단어 형식의 옵션 앞에는 '
-' 표시가 하나 더 붙습니다. 예를 들어, 도움말을 보기 위한 옵션으로 '-h' 와 '--help' 둘 다
지원합니다. 이제 위에서 예를 든 패치 파일 안의 내용이 이해가 좀 가나요? 아래를 다
시 봅시다.. 아직 양 이 안 차실테니 좀 더 알려 드리지요..
=============================================================================
diff -urN v2.2.15/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.2.15/linux/arch/alpha/kernel/irq.c Wed May 3 17:16:30 2000
+++ linux/arch/alpha/kernel/irq.c Wed Jun 7 14:26:42 2000
@@ -896,7 +896,13 @@
=============================================================================
첫 번째 줄은 지금껏 설명한 내용이고, 그 다음 줄에 --- 로 시작되는 줄은 수정 되기 이전
의 원 본 디렉토리 밑에 소스를 말하는 것입니다. 말할 것도 없이 다음 줄의 +++ 로 시작되
는 것은 새 로 고쳐진 소스를 말하는 것이지요.. 그 줄 뒤의 것은 소스 파일의 생성 시간
과 날짜 입니다. 그럼 다음의 것은 또 무얼 가리키는 것 일까요?.. 마치 무슨 암호문 같기
도 한데.. '@@' 문자로 시작되는 줄은 그 다음 줄 부터 과연 무엇이 수정 되는지를 알려주는
것입니다. '@@' 문자 뒤의 숫자에서 '-'표시로 시작되는 숫자는 원본 소스의 896 째 라인부터
그 아래 7 째 줄까지 내용이 빠진다는 것을 의미하고, '+' 로 시작하는 것은 수정되는 소스
파일의 896 째 줄 부터 13 줄의 내용이 첨가 된다는 것을 나타 냅니다. 아래를 다시 잘 보
면 이제 어느 정도 이해 가 될 것입니다.
그리고, '@@' 문자로 시작하는 그 다음 줄 부터의 내용에서 앞의 '-' 표시와 '+' 표시의 갯
수가 각 각 몇 개 인지를 세어 보세요. 그리고, 앞에 아무 표시도 없는 줄과 '-' 표시, 빈
공백 라인 을 포함해서 총 7 줄인 것을 알수 있습니다. 그 숫자가 -896,7 와 맞아 떨어 지는
것을 알 수 있 습니다. 또한, 앞에 아무 표시도 없는 줄과 '+' 표시, 빈 공백 줄을 포함 하면,
+896,13 도 역시 그 수를 의미 하는 것을 알 수 있습니다.
=============================================================================
@@ -896,7 +896,13 @@
unsigned long __init init_IRQ(unsigned long memory)
{
wrent(entInt, 0);
+
- alpha_mv.init_irq();
+
+ /* If we had wanted SRM console printk echoing early, undo it now. */
+ if (alpha_using_srm && srmcons_output) {
+ unregister_srm_console();
+ }
+
return memory;
}
=============================================================================
그럼, 왜 이렇게 커널과 별 상관 없는 듯한 얘기를 하는지는 제 맘을 헤아릴 수 있는 분이
나, 한 번 이라도 패치를 해 보려고 했다가 패치는 안되고 밑에 얘기할 .rej (rejected - '거부
된' 라는 뜻임) 파일만 잔뜩 쌓일 때의 실망감을 아는 분은 위의 패치 내용을 아는 것이 얼
마나 도움이 될 것 인지는 두 말하면 잔소리라는 것을 잘 아실 겁니다.
자.. (한숨 한번 쉬고.. 힘드네요..) 커널 소스도 마찬 가지 입니다. 만일 linux-2.2.14 소스를
사용하시다가 linux-2.2.17pre-* 의 최신 버젼을 사용하고 싶을 때, 인터넷 속도가 빠르신 분
은 거의 20 메가에 가까운 소스를 한번에 다 받으셔도 되지만, 그렇지 않은 분들은 여전히
눈물만.. 그래서, 패치 파일을 받아 와야 하는데 여기서 중요한 사실은 linux-2.2.14 과 linux-
2.2.17pre 사이의 중간 버젼의 패치를 모두 받아와야 한다는 것입니다. 즉, linux-2.2.15, linux-2.2.
16 버 젼의 패치가 필요 하다는 것이지요.. 하지만, linux-2.2.14 에서 linux-2.4.0-test* 버젼을
사 용하기 위해 그 중간 단계의 패치 버젼을 다 가져와서 사용 하려는 분이 있다면.. 없겠
죠?
; 어쨋든, 우여곡절을 다 겪어서 패치가 성공했다면 패치 대상이 된 파일의 원본은
이름끝에 .orig 라는 이름이 붙어 백업 됩니다. 패치 과정에서 문제가 생겨 실패 했다면 실
패한 파일 이름 뒤에 위에서 잠시 설명한 그 문제의 '.rej' 파일이 만들어 집니다. .rej 파
일을 잘 살펴 보시고, 다 시 패치 작업을 수행 합니다.
소스가 복잡한 경우에는 .rej 라는 파일이 각 디렉토리 마다 생길 수 있는데, 그 것을 일일
히 찾 는 다는 것은 시간 낭비이므로, 아래와 같이 find 명령으로 찾아 보시면 됩니다.
[root@jegal src]#cd linux
[root@jegal linux]#find . -name "*.rej"
위와 같이 해서 '*.rej' 파일을 찾을 수 없다면 패치가 성공한 것이므로, 다음과 같은 명령
으로 원본 파일인 '*.orig' 파일을 삭제합니다.
[root@jegal jegal]#find /usr/src/linux/ -name "*.orig" -exec rm -f {} ;
역시 또다른 암호문과 같은 명령이 시작 되는군요.. 리눅스나 유닉스는 이런 명령어와 옵
션의 천 국입니다. 열심히 공부해서 그 암호문들을 다 박살내 봅시다. 마법사들을 부러
워만 하지말고.. 위의 find 명령중 파일명을 인용 부호인 (") 으로 묶은 것은 별표 '*' 를 우
리가 흔히 알고 있듯 이 파일명 전체를 의미 하는 메타 문자 이므로, '.rej' 나 '.orig' 라는 확
장자를 포함한 파일을 쉘이 해석하기 위해서 이고, -exec 옵션은 끝의 세미 콜론 ';' 까지 중
간에 있는 명령을 수행 하 라는 것인데, 중간에 '{}' 라는 부분은 찾은 파일의 이름으로 대
체 되기 위해 쓰는 것이고, 세미 콜론 앞의 백 슬래시인 '' 표시는 뒤의 명령의 끝을 알리는
세미 콜론을 쉘이 먼저 해석하지 않 기 위해 쓰이는 것입니다.
그럼 (") 인 겹 따옴표로 묶은 것은 왜 일까요? 우리가 일반적으로 쓰는 홑 따옴표도 있는
데.. 우선, 홑 따옴표든.. 겹 따옴표든 이것을 '인용부호' (quote) 라고 부릅니다. 분명히 서
로 다른 기능이 있기에 구분해서 쓸 것이라는 것은 벌써 짐작 하셨을 겁니다. 그럼, 먼저
인용 부호의 필 요성에 대해 살펴 봅시다..
[root@jegal jegal]#echo I love you <-- love 다음에 공백을 2칸 이상 띄웠다면..
위와 같이 명령을 내리면 love 와 you 사이의 공백은 1칸 이상은 무시 됩니다. 그래서 출력은
다 음과 같이 'I love you' 라고 출력되게 됩니다. 여기서 '아 하~ ' 하고 눈치를 채셨을 겁니
다. 맞습니다. 공백을 포함한 문자열을 묶어서 사용할 때는 인용 부호를 쓰게 됩니다. 그
렇다면, 이 제 각 인용 부호의 차이점을 알아 보겠습니다.
[root@jegal jegal]#echo "I love you"
[root@jegal jegal]#echo 'I love you'
위의 두 차이점은 무엇일까요? 사실 위와 같이 단순 문자열을 묶어서 사용할 때의 차이점
은 없습 니다. 그러나, 다음의 예를 보죠..
[root@jegal jegal]#echo "I love you $SHELL"
[root@jegal jegal]#echo 'I love you $SHELL'
자.. 이제는 서로의 차이가 확연히 드러나는 순간입니다. 지금 리눅스 박스 앞에 앉아 계
시다면 위의 예를 한 번 해 보세요.. 이제 좀 아시겠지요? 겹 따옴표 (") 는 메타 문자를
해석 하면서 본인의 임무인 문자 열을 묶어서 나타 냅니다. 그러나, 홑 따옴표 (') 는 메타
문자를 무시하고 단순한 문자 열 로만 취급하게 됩니다. 이 차이는 아주 중요합니다. 별
생각없이 인용 부호를 사 용 하셨다면, 지금 부터 확실히 인지 하시고 쓰시기 바랍니다.
참고로, 위 에서 잠깐 설명했던 '' 나 '*' 또는, '$' 와 같은 문자를 '메타 문자' 라고 부르며,
각각 특수한 용도로 사용을 하게 됩니다. 위 의 세가지 말고도 많은 메타 문자가 있으며,
이 메 타 문자를 명령어가 해석하지 않고, 쉘이 먼저 해석하여 명령에게 그 값을 돌려주게
됩니다. 명 령어가 해석하고 싶어도 할 수 없습니다. 왜냐하면, 메타 문자는 쉘 만이 해
석 할 수 있는 특권 을 갖고 있으니까요. 꼭 기억 하세요.. 메타 문자를 함부로 처리하면
쉘 한테 혼납니다..
; 특히, 백 슬래시인 '' 는 메타 문자를 해석 시키지 않는 역할을 합
니다. 자기도 메타 문자이면 서 메타 문자를 제어하는 왕초 라고나 할까요? 단, 백 슬래
시 다음에 오는 메타 문자 한개만 그 기능을 없앱니다. 일정 범위 안의 메타 문자의 효력
을 없애기 위해서는, 위에서 설명한 홑 따옴 표 (') 만이 그 일을 할 수 있지요. 그럼, 다음
의 예를 조금 들어 보겠습니다.. [root@jegal jegal]#echo SHELL <-- echo 명령을 예와 같이 내리면
그냥 'SHELL' 이라 고만 출력 됩니다.
[root@jegal jegal]#echo $SHELL <-- 이번에는 사용하고 있는 쉘의 경로와 이름이 출력
되는 걸 볼 수 있습니다.
[root@jegal jegal]#echo $SHELL <-- 여기서는 '$SHELL' 라는 출력을 보여줍니다. '$'
의 기능을 '' 표시가 자신의 능력으로 막았군요.
'$' 표시는 변수의 기능으로 쓰기 위해 변수로 쓰일 문자 앞에 붙여 줌으로써, 그 문자가
변수라 는 것을 쉘에게 알려주는 메타 문자 입니다. 변수로 쓰이는 문자는 일반적으로 위
에서 'SHELL' 처럼 대문자를 사용 합니다. 물론 소문자를 사용하기도 합니다만, 대문자를
사용하는 이유는 단 지 관례라고 생각 하시면 됩니다. 눈에도 확연히 잘 띄구요..
그리고, 변수는 '환경 변수' 와 '지역 변수(사용자 정의 변수)' 로 나뉘어 집니다. 자신이
정의 한 변수를 쉘에서 계속 사용하려고 하신다면, 아래와 같이 쉘에서 정의를 하시고 사
용하시면 됩 니다.
[root@jegal jegal]#export STAR=Blizzard <-- export 명령으로 지역 변수를 환
경 변수화 시킵니다.
[root@jegal jegal]#echo $STAR
Blizzard
명령 뒤에 메타 문자가 나오면 먼저 쉘이 해석하고, 그 값을 명령에게 돌려 주기 때문에 ec
ho 명 령은 '$SHELL' 라는 메타 문자 다음의 것은 구경도 못하게 되고, '/bin/bash' 라는 값만 출
력하 게 됩니다.
음.. 얘기가 다른 길로 빠져 버렸군요.. 그래도, 아는 것은 힘이니까.. 으