사용형식 [찾을 디렉토리경로] [찾기옵션] [찾은후행할 작업]

 

option

[찾을 디렉토리경로]

.     : 현재 디렉토리 이하를 검색대상으로 한다.

/     : 루트디렉토리(파일시스템전체) 이하를 대상으로 한다.

~ID : 지정된 ID의 홈디렉토리이하를 대상으로한다.

 

[찾기옵션]

-empty            : 비어있는 파일을 찾는다.

-uid UID          : 지정된 UID를 갖는 파일을 찾는다.

-gid GID          : 지정된 GID를 갖는 파일을 찾는다.

-group 그룹명  : 지정된 group을 갖는 파일을 찾는다.

-name            : 지정된 형식의 패턴을 가지는 파일을 찾는다.

-newer           : 지정된 파일 이후에 생성된 파일을 찾는다.

-perm             : 지정된 퍼미션을 가진 파일을 찾는다.

-used 일자수   : 최근 n일 이후에 변경된 파일을 찾는다.

-user              : 지정된 파일을 소유하고 있는 소유자의 모든 파일을 찾는다.

 

[찾은후 수행할 작업]

-print                    : 찾은 내용을 보여준다.

-exec "수행명령어" : 검색된 파일을 대상으로 :수행명령어"를 실행한다.

 

 

[예제]

특정 사용자의 ID 소유로된 모든 파일 찾기.

[os] find / -user khi083 -print

 

 

현재 디렉토리 이하부터 test 파일명을 찾아 보여준다.

[os] find . -name test -print

 

khi083 사용자의 홈디렉토리에서 test 파일명을 찾아 보여준다.

[os] find ~khi083 -name test -print

 

특정 파일을 찾은 후 자동 삭제방법.

[os] find ~khi083 -name test -exec rm -f {} \;

 

지정한 소유자의 모든 파일을 찾아서 확인하기.

[os] find / -user khi083 -exec ls -l {} \;

 

특정용량 이상되는 파일들 모두찾기.

[os] find /usr/ -size +10000k -exec ls -l {} \;                        -- 약 10MB이상

 

특정 퍼미션을 가지고 있는 파일들을 모두 찾기

[os] find / -perm 4755 -exec ls -l {} \;

 

존재하는 모든 링크파일 찾기

[os] find / -type l -exec ls -l {} \;

 

디렉토리 이하에서 "doc" 라는 문자를 포함하고 있는 파일을 찾아서 파일의 위치와 파일명, 포함된 행을 출력한다.

[os] find /etc type f -exec egrep -i "doc" /dev/null {} \;

 

 

-------------------------------------- 보안 관련된 find --------------------------------------

지정된 일자 이후에 변경된 모든 파일 찾기(서버점검시에 서버해킹으로 인하여 변경된 파일을 찾을 경우)

[os] find / -used 2 -exec ls -l {} \;                                        -- used 뒤에 나오는 숫자는 "일" 즉, 24시간 단위.

 

지정된 파일보다 이후에 생성된 파일 찾기(해킹된 파일이나 백도어 파일을 찾은 후에 그 파일과 함께 시스템에 생성된 파일찾기)

[os] find / -newer /root/file1.txt -exec ls -l {};                          -- used 뒤에 나오는 숫자는 "일" 즉, 24시간 단위.

 

root소유의 SetUID 파일 찾기

[os] find / -user root -perm -4000 -print

 

서버내부에서 .bash_history 파일을 모두 찾아서 확인하기(root소유의 .bash_history파일이 용량이 0이라면 이는 매우 심각한 경우로서 거의 99%이상은 해킹되었다고 보셔도 무방하다.)

[os] find / -name .bash_history -exec ls -l {} \;

 

소유자가 없는 파일 또는 소유그룹이 없는 무적파일 찾기

[os] find / -nouser -o -nogroup -print                                      -- -o옵션은 "OR"를 의미한다


출 처 : http://blog.naver.com/nixblade?Redirect=Log&logNo=10092313804

[출처] find 명령어 |작성자 케이

리다이렉션과 파이프

 

시스템에 로그인하면쉘은 기본적으로 표준 입력장치로 키보드표준 출력장치로 모니터를 설정한다.

리눅스 시스템에서 리다이렉션과 파이프

-       입력과 출력의 방향을 변경할 수 있다.

 

리다이렉션

 

표준 출력의 리다이렉션

-       화면 출력을 파일 출력으로 바꾸는 것

-       리다이렉션을 의미하는 문자 è ‘>’

n  ex)  $ ls –al > test
이렇게 입력하였을 때 명령이 실행된 결과가 test 파일에 저장

-       파일이 이미 존재하고 있더라도 해당 파일을 무조건 덮어 씌우므로..
‘>>’ 
을 사용하여 이미 존재하는 파일의 끝에 추가하여 쓰도록 한다.

n  ex) $ ls –al >> test2
   $ cat test2
   $ ls –al >> test2
   $ cat test2

 

표준 입력의 리다이렉션

-       표준입력을 키보드에서 파일로 바꾸는 것

 

* sort 명령어 : 키보드로부터 입력된 데이터를 오름차순으로 정렬하여 그 결과를 표준 출력장치인 모니터 화면에 보여주는 명령어

 

-       표준 입력의 리다이렉션 è ‘<’

n  ex)  $ sort < names
          names 
파일로부터 입력받아 그 결과를 표준출력장치인 화면에 출력

n  ex)  $ sort < names > sorted
          
표준 입력과 표준 출력을 동시에..

 

 

 

파이프라인

 

파이프

 - 어떤 명령의 실행결과를 다음 명령의 입력 값으로 만들기 위해 두 명령어를 같이 쓸 수 있게 해주는 것!

파이프를 만들기 위해 두 명령어 사이에 | (vertical bar)를 놓아야 한다.
두 명령어 사이에 | 가 놓이면, | 을 기준으로 왼쪽은 표준 출력 명령이 되고오른쪽은 표준 입력 명령이 된다.

n   표준 출력 | 표준 입력

 ex)  cat names | sort | more
cat 
명령은 names 파일을 표준 출력하고, sort 명령은 cat에서 표준 출력된 데이터를 입력 값으로 받아 정렬한다정렬된 데이터를 다시 표준출력하며, more 명령은 sort에서 정렬된 데이터를 출력한다.

 

 

 파이프라인 분리 - Tee

 

파이프라인 분리

-       하나의 입력을 가지고 두 개의 동일한 출력을 가지는 명령어
파이프에 tee를 위치시키면 입력 데이터에 대한 두 개의 동일한 출력을 만들어 낼 수 있다는 것!

-       일반적 형식

n  tee filename

n  ex ) $ cat  names   sort  |  tee  sorted  | pr
          
파이프라인 tee를 이용해 데이터를 정렬하여 sorted라는 이름으로 저장하고 인쇄하는 예


출처 : http://blog.naver.com/dbwls0105?Redirect=Log&logNo=30037806187

리눅스 터미널을 열었는데

쉘 프롬프트 모양이

 

bash-3.1#

 

이런식으로 나와 있을 경우가 있습니다.

이런경우 현재 디렉토리 위치도 모를뿐더러 현재 user가 누군지도 모릅니다.

 

vi .bashrc 를 열어서

export PS1="[\u@\h \W]\$"  를 추가해줍니다.

 

source .bashrc를 통해 bashrc를 다시 읽습니다.

 

 

옵션)

\t 현재 시간을 HH:MM:SS 형식으로 보여준다.
\d 날자를 "요일 월 일" 형식으로 보여준다. Tue Jan 23
\s 쉘의 이름을 보여준다.
\w 현재 작업디렉토리를 완전경로로 보여준다.
\W 현재 작업디렉토리의 이름을 보여준다.
\u 현재 사용자의 사용자명
\h 호스트만
\H 호스트이름전체
\# 현재 명령의 명령 번호
\$ root이면 #, 일반사용자이면 $
\! 이 명령의 히스토리 번호
\nnn 8진수 nnn에 해당하는 문자
\[ 비출력문자의 시퀀스를 시작한다.
\] 비출력문자의 시퀀스를 마친다.

 

 

참고)

- Ubuntu 기본 프롬프트
PS1="${debian_chroot:+($debian_chroot)}\u@\h:\w\$" 
 
- CentOS 기본 프롬프트
PS1="[\u@\h \W]\$"


debian 계열에서 apt-get update를 하다가 보면 공개키가 없다고 에러가 나올때가 있다.
문제가 되는 공개키를 B5B7720097BB3B58라고 하면, 아래와 같이 하면 해결 할 수 있다.
(아래의 공개키는 emdebian archive의 키)

insidexino@insidexino-desktop:~$ gpg --keyserver wwwkeys.eu.pgp.net --recv-keys B5B7720097BB3B58
gpg: requesting key 97BB3B58 from hkp server wwwkeys.eu.pgp.net
gpg: key 97BB3B58: "Emdebian Archive Signing Key" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1
insidexino@insidexino-desktop:~$ gpg --list-keys 97BB3B58
pub   1024D/97BB3B58 2007-04-30
uid                  Emdebian Archive Signing Key
sub   2048g/FEFD537E 2007-04-30

insidexino@insidexino-desktop:~$ gpg --export 97BB3B58 > 97BB3B58.gpg
insidexino@insidexino-desktop:~$ sudo apt-key add ./97BB3B58.gpg 
OK


아래의 명령어로 필요한 공개키가 추가 되었음을 확인 할 수 있다.

insidexino@insidexino-desktop:~$ sudo apt-key list
/etc/apt/trusted.gpg
--------------------
pub   1024D/97BB3B58 2007-04-30
uid                  Emdebian Archive Signing Key
sub   2048g/FEFD537E 2007-04-30

Maybe a lot of people already know this, but I will write it down here, in case anyone forget it, or of somebody does not know already.

To upgrade the Linux Debian Stable Etch to testing Lenny, just need to follow these two steps.

1. Edit sources.list

sudo vi /etc/apt/sources.list

and change all words etch to lenny, or stable to testing

2. Update and upgrade

sudo aptitude update

sudo aptitude install apt dpkg aptitude

sudo aptitude full-upgrade

that is all, this also work if you want to go from lenny to sid, just change yoursources.list accordingly.

It is also better if you start your Debian Linux in text mode, so GDM or KDM could be restarted without problems.

You may be interested in reading this.


요즘 리눅스는 많이 쉬운것 같다... 단 명령어 세번으로 자동으로 시스템이 업그레이드 된다...

전체적인 시스템 부팅 과정은 아래와 같다.


 

■ 부트로더 : 부트섹터(MBR, Master Boot record)에 적재되어 있는 프로그램.

                   CentOS에는 GRUB

                   부트로더에 의해 선택된 운영체제로 부팅 시작

 

■ 커널 : 부트로더에 의해 운영체제 부팅이 시작되면 맨 먼저 커널(kernel)이 동작됨.

             부팅 시 시스템 내의 하드웨어를 인식하여 그에 대한 정보를 보여주는데 이를 커널 메시지

             한다.

 

■ 부트스플래시 : 부팅 진행 상황을 그래픽으로 보여주는 것. 

   (BootSplash)   CentOS에서는 RHGB(RedHat Graphical Boot)이 기능 제공

 

■ 루트 파일 시스템 마운트

    커널 동작 후 initrd.gz 또는 initrd.img로 된 램 초기 디스크가 동작하여

    리눅스가 설치된 파티션을 루트 파일시스템으로 읽기 모드(Only-read)로 마운트됨

    운영체제 적재 끝나면 rc.sysinit 스크립트에 의해 로컬 디스크가 읽기/쓰기 모드로 다시 마운트됨

   

    * 응급복구모드에서는 루트 파일시스템이 읽기 모드로만 마운트되어 있으므로, 읽기/쓰기 모드로

      재 마운트 시켜 주어야 시스템 파일 수정 가능(mount -o remount,rw /)

 

■ 시스템 초기화 프로세스(init, inittab)

    1. 루트 파일 시스템이 마운트된 후 프로세스 ID(pid) 1번 값을 가지는 init 프로세스에 의해

       시스템 초기화 실행

       *  init 프로세스는 로그인 프롬프트 나오기 전까지 파일 시스템 점검, 서비스 프로세스 관리, 가

          상 콘솔 접속 관리, 실행 레벨 관리 등 리눅스 사용환경을 위한 초기화 작업 실행

     2. init 프로세스가 실행되면 가장 먼저 /etc/inittab 파일을 읽어들임

         

        3. inittab 파일은 맨 처음 /etc/rc.d/rc.sysinit 스크립트 구동

          (네트워크 설정, 호스트이름 설정, /proc 마운트, 시스템 시간 설정, 시스템 폰트 구동, 스왑 구

           동, 루트 파일 시스템 및 리눅스 파일 시스템 마운트 및 점검, 하드 디스크 최적화, Raid 디바

           이스 구동 등의 작업 진행)

        4. default로 지정되어 있는 /etc/rc.d/rc 디폴트번호 가 실행됨

 

   ○ 런레벨

   <런레벨 정의> : 런레벨은 총 7가지가 있음

   - 0 : 시스템종료(halt)

   - 1 : 싱글유저(윈도우의 안전모드와 유사, root의 비밀번호 변경 가능)

   - 2 : 멀티유저(NFS(Network File System) 기능 제외)

   - 3 : 멀티유저(모든기능 포함, 콘솔 부팅)

   - 4 : 사용 안함

   - 5 : x윈도우

   - 6 : 재부팅   

 

     5. 시스템 재시작 Ctrl-Alt-Del키 설정

      

      재시작키 설정을 없애려면 주석 처리

      만약 명시된 사용자만이 이 조합키를 사용할 수 있게 하려면 -a 옵션 사용

        -> /etc/shutdown.allow 파일 만들고 여기에 사용자 추가

 

    6. UPS 전원 부족 시에 자동으로 셧다운하기


        UPS 파워가 부족할 경우 2분 후에 자동으로 셧다운

        UPS 전원이 충전되어 전원 공급에 문제가 없을 경우 실행한 셧다운 명령을 취소

 

    7. 가상 콘솔 접속을 위한 mingetty 설정

    

    리눅스에서는 6개의 가상 콘솔을 제공

    가상 콘솔을 제공하는 프로토콜 : getty (주로 mingetty와 mgetty가 많이 사용됨)

    respawn은 커널 메모리 상에서 프로세스가 실행되었다가 죽으면 다시 실행되어 살아날 수 있도록

    해 주는 명령. 로그아웃 후에도 계속 같은 로그인 프롬프트가 뜨는 이유.

 

     8. X window 실행

       

       실행레벨이 5인 경우 preefdm 스크립트에 의해 엑스 윈도우로 부팅 이루어짐

       /etc/sysconfig/desktop 파일에 명시되어 있는 오픈 데스크톱 유형에 따라 엑스 디스플레이 관

       리자가 실행되어 엑스 로그인 화면 나타남

       CentOS에서는 GNOME을 기본 데스크톱 환경으로 지원하므로, gdm(Gnome Display Manager)

       가 동작함

 부팅 과정 중 커널이 적재되고 장치 드라이버가 초기화되면 커널은 /etc, /bin 이나 /sbin에 있는 init 프로그램을 실생시킨다. init은 다목적 프로그램으로, 새로운 프로세스를 생성하거나 프로그램이 종료되었을 때 이를 다시 시작하는 기능이 있다. 또한 init은 여러 프로그램을 실행하고 시스템이 부팅할 때 스크립트를 실행할 책임을 진다. init의 모든 동작은 /etc/inittab 파일을 통해 제어한다.

 /etc/inittab 파일을 이해하기 위해서는 우선 실행 레벨이라는 개념을 이해해야 한다. init에서 실행 레벨은 현재 시스템 상태를 명시하는 숫자 또는 문자다. 예를 들어, 시스템 실행 레벨이 3으로 변경되면 /etc/inittab의 모든 항목 중 실행 레벨이 3이라고 되어 있는 것을 실행한다. 실행 레벨은 /etc/inittab 안의 항목을 그룹으로 묶는 유용한 방법이다.


현재 나의 데비안 시스템 inittab 설정 파일....

run level 2로 설정 되어 있다.. 주석을 보면
run level 0 : halt
run level 1 : single-user mode
run level 2-5 : multi-user mode
run level 6 : reboot 
으로 설정 되어 있는 것을 알 수 있다.

여기서 run level 0을 실행 시켜 보기 위해 
# init 0 
명령을 주자 시스템이 꺼졌다.

위 파일의 각 필드는 콜론(:)으로 구분한다. 
첫번째 필드는 임의의 식별자로 어떤 것이든 상관없으며 파일 내에서 다른 것과 총돌하지 않으면 된다. 
둘째 필드는 명령이 실행될 실행 레벨이다.
셋째 필드는 init이 그 항목을 어떻게 처리할 것인지 지시한다.
넷째 필드는 init이 실제 실행할 명령이다.

id : 2 : initdefault     -> 디폴티 run level 2로 설정

si : : sysinit : /etc/init.d/rcS     -> 시스템을 부팅할 때 init에게 /etc/init.d/rcS을 실행 하도록 한다. 이 파일은 기본 시스템 초기화를 처리해주는 명령을 담은 간단한 셸 스크립트다. 예를 들면, 스와핑 긴능을 켜고 파일시스템을 점검하고, 마운트하며, 시스템 시간을 CMOS 시간에 맞춘다.

10 : 0 : wait : /etc/init.d/rc 0
11 : 1 : wait : /etc/init.d/rc 1
12 : 2 : wait : /etc/init.d/rc 2
13 : 3 : wait : /etc/init.d/rc 3
14 : 4 : wait : /etc/init.d/rc 4
15 : 5 : wait : /etc/init.d/rc 5
16 : 6 : wait : /etc/init.d/rc 6
-> 실행 레벨 0부터 6까지, 어디로 들어가든 /etc/init.d/rc 스크립트에 적절한 실행 레벨 인수를 사용하여 실행한다. rc는 다목적 시동 스크립트로서, 각 실행 레벨에 알맞은 스크립트를 실행시켜 준다. 여기서 action 필드는 wait다. init에게 주어진 command를 실행하고, 종료할 때까지 기다린 후 다음 작업으로 넘어가라는 지시다.
-> 각 실행 레벨의 스크립트는 (데비안의 경우) /etc/rcN.d에 있다. 여기서 N은 시작할 실행 레벨 번호다. 따라서 실행 레벨 2라면 /etc/rc2.d의 스크립트를 사용한다. 이 디렉토리들의 내용을 살펴 보면 Snnxxxx나 Knnxxxx 형태의 파일을 볼 수 있는데 K로 시작하는 서비스를 죽이는 스크립트이며, S로 시작하는 스크립트는 서비스를 시작할 때 사용하는 스크립트다. 이름에 들어 있는 nn은 서로의 실행 순서를 맞추려는 것으로 낮은 번호의 스크립트는 높은 번호의 스크립트보다 먼저 실행된다.
-> 같은 서비스를 서로 다른 실행 레벨에서 시작하고 중지하기 때문에 같은 스크립트를 여러 곳에 복사하는 것보다 심볼릭 링크를 사용하고 있다. 따라서 각각의 S, K 파일은 모든 서비스의 시동/셧다운 스크립트를 포함한 중앙 디렉토리를 가리키는 심볼릭 링크일 뿐이다. 데비안의 경우 이 중앙 디렉토리는 /etc/init.d 이다. 그러므로 특정 서비스를 시동 시키거나 중지시키고 싶을 때는 /etc/init.d에 위치한 스크립트를 이용하면 쉽게 할 수 있다.

/etc/init.d/networking stop  : 네트워크 서비스 중단
/etc/init.d/networking start  : 네트워크 서비스 시작

또 다른 중요 시스템 설정 스크립트는 /etc/init.d/rc.local이 있다. 이 스크립트는 다른 시스템 초기화 스크립트를 실행한 뒤에 실행된다. (보통 각각의 /etc/rcN.d에 S99rc.local이라는 심볼릭 링크를 만들어 둔다. 99라는 숫자는 s 스크립트가 가질 수 있는 가장 큰 숫자이므로 가장 나중에 실행된다) 부팅 중 다른 특별한 시스템 명령을 실행하길 원하거나 어디에서 실행시켜야 할지 모를 때는 rc.local 파일을 편집하여 사용하면 된다.

ca : 12345 : ctrlaltdel : /sbin/shutdown -t1 -a -r now
-> 이 항목은 콘솔에서 Ctrl-Alt-Del 을 눌렀을 때 실행된다. 이 키조합을 누르면 보통 시스템은 재부팅하는 인터럽트가 발생한다. 리눅스에서는 이 인터럽트를 받아 init에게 보내고 init은 ctrlaltdel의 action 필드에 있는 항목을 실행한다. 여기서는 /sbin/shutdown -t1 -a -r now로 안전한 시스템 재부팅을 진행시킨다.

1: 2345 : respawn : /sbin/getty 38400 tty1
2: 23 : respawn : /sbin/getty 38400 tty2
3: 23 : respawn : /sbin/getty 38400 tty3
4: 23 : respawn : /sbin/getty 38400 tty4
5: 23 : respawn : /sbin/getty 38400 tty5
6: 23 : respawn : /sbin/getty 38400 tty6
-> 마지막으로 inittab 파일에는 처음 나오는 6개의 가상 콘솔을 /sbin/getty에서 실행하는 항목이 있다. 이 프로그램은 터미널의 로그인을 받아준다. 이 프로그램이 없다면 터미널은 그야말로 죽은 상태나 다름없으며 키보드나 마우스에 반응하지 않는다. getty 명령은 터미널 장치를 열고 터미널 드라이버에 다양한 매개변수를 설정하고 /bin/login을 실행하여 로그인 세션을 연다.
-> getty는 '보율(baud rate)'과 '장치'라는 두 개의 인수를 받는다. 리눅스 가상 콘솔의 포트명은 /dev/tty1, /dev/tty2등이다. 가상 콘솔의 보율은 일반적으로 38400이다.
-> getty 항목의 action 필드는 respawn인데 이는 해당 명령이 죽으면 init이 다시 명령을 실행한다는 뜻으며, 사용자가 로그아웃 할 때마다 getty 프로세스가 죽으며 이에 따라 getty 프로세스를 다시 실행시켜 로그인을 준비한다.





objcopy는 오브젝트 파일을 다른 오브젝트 파일로 복사할 때 사용한는데, 선택적으로 필요한 부분만을 복사할 수 있기 때문에 파일의 사이즈를 줄이는 데 주로 사용되고, 바이너리 포맷을 바꾸는 데도 이용된다.

 

 ex) objcopy hello hello.new

 

hello 파일을 hello.new로 복사, 기존의 hello와 동일하다.

 

 

 ex) objcopy -O binary hello hello.new

 

위 명령은 hello 파일에서 인스트럭션과 데이터만을 뽑아서 hello.new로 만든다. 이렇게 만들어진 hello.new는 ELF 헤더도 붙지 않은 순수한 바이너리 그 자체다. 주로 부트 로더를 만들 때 이런 식으로 사용하는데 이유는 모든 CPU마다 전원이 인가되었을 때 CPU가 인스트럭션을 처음 읽어서 실행할 번지가 정해져 있다. 예를 들면 i386 계열은 0xfffffff0 번지이고 ARM 계열 CPU는 0x0 번지며 MPC860 CPU 같은 경우 0xff00100번지다.

 

무슨 말이냐하면 i386 계열 CPU는 전원이 켜지는 순간 BIOS의 POST(Power On Self Test) 프로그램이 위치하는 0xfffffff0 번지의 인스트럭션을 제일 처음 읽어서 수행한다.

 

i386 PC 외의 CPU 같은 경우 처음 수행하는 프로그램은 부트 로더인데 이러한 부트 로더는 인스트럭션이 제일 앞에 와있는 바이너리여야 한다. 즉 ELF 헤더가 붙어서는 안 된다는 이야기다. ELF 헤더는 운영체제에서 필요한 정보지 CPU에서 필요한 정보는 아니다.

 

 

ex) objcopy -S hello hello.new

 

모든 심볼들과 재비치 정보들을 제거하여 hello.new 파일을 만든다. 그래서 바이너리 파일의 사이즈가 확실히 줄어든다.

 

 

-  참고 문헌 : 유닉스, 리눅스 프로그래밍 필수 유틸리디

[출처] objcopy|작성자 레토브


텍스트 변환을 위한 함수(Functions for Transforming Text)

함수(functions)는 여러분이 makefile안에서, 작업할 파일들을 알아내거나 아니면 사용할 명령들을 알아낼 수 있도록, 텍스트를 처리하는 것이다. 함수는 dfn{함수 호출(function call)} 안에서 사용한다. 여기에서 함수의 이름과 함수가 작업할 텍스트(매개변수(arguments) 를 제공한다. 함수 처리의 결과는 makefile의 그 호출 위치에 삽입된다. 마치 변수가 대입된 것처럼.

함수 호출 문법(Function Call Syntax)

함수 호출은 변수 참조와 닯았다. 이것은 다음과 같이 보일 것이다:

$(function arguments)

또는 다음과 같이 보일 것이다:

${function arguments}

여기서 function는 함수 이름이다; make의 일부인 이름들 짧은 리스트의 하나. 새로운 함수를 정의하기 위한 준비는 없다.

arguments는 함수의 매개변수들이다. 이들은 함수와 하나 이상의 공백이나 탭으로 분리되며, 한 개 이상의 매개변수들이 있으면 그들은 콤머로 구분된다. 그런 공백문자와 콤머들은 매개변수 값의 일부가 되지 않는다. 함수 호출을 둘러싸는 데 사용한 구분자들은, 괄호들이나 중괄호들은, 짝이 맞는 꼴로만 나타날 수 있다; 다른 종류의 구분자들은 단신으로 나타날 수 있다. 매개변수들 자신이 다른 함수 호출들이나 변수 참조들을 가진다면 모든 참조들에 대해서 동일한 종류의 구분자들을 사용하는 것이 가장 현명할 것이다; `$(subst a,b,${x})' 이 아니라 `$(subst a,b,$(x))' 를 쓰자. 이렇게 하는 것이 좀 더 명확하기 때문이다. 그리고 한가지 종류의 구분자만이 참조의 끝을 찾기 위해서 서로 비교되기 때문이다.

각 매개변수 텍스트는 매개변수 값을 만드는 변수 대입과 함수 호출들에 의해서 처리된다. 이것이(이 결과가) 함수가 작동하는 대상 텍스트이다. 대입은 매개변수들이 나타난 순서대로 행해진다.

콤머들과 일치하지 않은 괄호나 중괄호들은 매개변수가 작성된것과 동일한 텍스트로 나타날 수 없다; 앞에 있는 공백들은 작성된 것과 같은 첫번째 매개변수의 텍스트로 나타날 수 없다. 이런 문자들은 변수 대입을 통해서 매개변수 값들로 넣어질 수 있다. 먼저 그것의 값들이 콤마나 공백 문자들로 구분된 변수 commaspace를 정의한 뒤 이들 변수들을 그런 문자들이 필요한 곳에, 다음과 같이, 대입한다:

comma:= ,
empty:=
space:= $(empty) $(empty)
foo:= a b c
bar:= $(subst $(space),$(comma),$(foo))
# bar is now `a,b,c'.

여기서 subst 함수는 foo의 값 전체에서 각 스페이스를 콤머로 변경하고 그 결과를 이 값에 대입한다.

문자 대입과 분석을 위한 함수들(Functions for String Substitution and Analysis)

다음은 문자열들에 대해서 작동하는 함수들이다:

$(subst from,to,text)
text 텍스트에 대해서 텍스트의 대치를 수행한다: 이것 안에서 from이 나오면 to로 대치된다. 그 결과가 대입된다. 예를 들어서
$(subst ee,EE,feet on the street)
`fEEt on the strEEt'를 대입한다.
$(patsubst pattern,replacement,text)
text 안에서 공백문자로 분리된 단어들 중 pattern와 매치되는 단어를 찾아서 그것들을 replacement로 변경한다. 여기서 pattern는 와일드카드 역할을 하는 `%'를 가질 수 있는데, 이것은 어떤 단어 내에 있는 임의 개수의 어떤 문자들과도 매치된다. replacement도 역시 `%'를 가질 수 있는 데 `%'pattern 안에서 `%'과 매치된 텍스트에 의해서 대치된다. patsubst 함수 호출에 있는 `%' 문자들은 앞에 역슬래쉬 (`\')를 써서 인용될 수 있다. `%'를 인용했을 역슬래쉬들은 더 많은 역슬래쉬들에 의해서 인용당할 수 있다. `%' 문자들이나 다른 역슬래쉬들을 인용하는 역슬래쉬는 패턴에서, 이것이 파일 이름들과 비교되거나 그안에 대입된 줄기를 가지기 전에, 제거된다. `%' 문자들을 인용할 위험이 없는 역슬래쉬들은 아무런 간섭도 하지 않는다. 예를 들어서 `the\%weird\\%pattern\\'`%' 문자 앞에 `the%weird\' 가 있고 뒤에 `pattern\\' 가 있다. 마지막 두 역슬래쉬들은 그들이 어떤 `%' 문자에도 영향을 미치지 않기 때문에 잔류한다. 단어들 사이에 있는 공백문자는 단일 스페이스 문자로 줄어든다; 이에 앞서거나 뒷선 공백문자들은 무시된다. 예를 들어서 다음은,
$(patsubst %.c,%.o,x.c.c bar.c)
`x.c.o bar.o' 라는 값을 만든다. 대입 참조(see section 대입 참조(Substitution References)patsubst 의 효과를 얻는 더 단순한 방법이다:
$(var:pattern=replacement)
는 다음과 동일하다
$(patsubst pattern,replacement,$(var))
두번째 짧은 표기 방법은 patsubst의 가장 일반적인 사용들 중의 하나를 단순하게 만든다: 파일 이름들의 끝에 있는 접미사(확장자?)를 교체한다.
$(var:suffix=replacement)
이것은 다음과 동일하다.
$(patsubst %suffix,%replacement,$(var))
예를 들어서, 다음과 같은 오브젝트 파일들의 리스트를 가지고 있다면:
objects = foo.o bar.o baz.o
이에 대응하는 소스 파일들의 리스트를 얻기 위해서 다음과 같이 쉽게 작성할 수 있다:
$(objects:.o=.c)
이것은 다음과 같은 일반형태를 사용하는 것 대신에 쓸수 있다:
$(patsubst %.o,%.c,$(objects))
$(strip string)
이 함수는 string의 앞뒤에 있는 공백문자들을 제거하고 내부에 있는 하나 이상의 공백문자들을 단일 스페이스로 교체한다. 그래서 `$(strip a b c )'의 결과는 `a b c'가 된다. strip 함수는 조건과 함께 사용될 때 아주 유용할 수 있다. 어떤 것을 빈 문자열 `'과, ifeq 또는 ifneq를 사용해서, 비교할 때 보통 빈 문자열과 일치하는 공백의 문자열을 원할 것이다 (see section Makefile의 조건 부분(Conditional Parts of Makefiles)). (그래서, ) 다음과 같은 것은 원하는 결과를 얻지 못한다:
.PHONY: all
ifneq "$(needs_made)" ""
all: $(needs_made)
else
all:;@echo 'Nothing to make!'
endif
ifneq 지시어에서 변수 참조 `$(needs_made)' 를 함수 호출 `$(strip $(needs_made))' 로 바꿈으로써 좀 더 엄격(robust)하게 만들 것이다.
$(findstring find,in)
이 함수는 in에서 find를 찾는다. 있다면 그 값은 find가 된다; 그렇지 않다면 그 값은 빈 것이 된다. 이 함수를 조건에서 사용해서 주어진 문자열 안에서 특정 문자열의 존재 여부를 검사할 수 있다. 그래서 다음과 같은 두 예제들은,
$(findstring a,a b c)
$(findstring a,b c)
`a'`' (빈 문자열) 각각을 만든다. findstring의 실질적인 응용에 대해서는 See section 플래그 검사 조건(Conditionals that Test Flags).
$(filter pattern...,text)
이 함수는 pattern 단어들 중의 임의의 것과 일치하지 않는, text 내의 공백문자로 분리된 단어들을 모두 제거하고 일치하는 단어들만을 리턴한다. 패턴은, 위의 patsubst 함수에서 사용된 패턴과 마찬가지로, `%'을 사용하여 작성된다. filter 함수는 한 변수 안에서 (파일 이름과 같은) 다른 타입의 문자열들을 분리 제거하는 데 사용될 수 있다. 예를 들어서:
sources := foo.c bar.c baz.s ugh.h
foo: $(sources)
cc $(filter %.c %.s,$(sources)) -o foo
`foo'`foo.c', `bar.c', `baz.s' 그리고 `ugh.h' 에 의존하지만 `foo.c', `bar.c' 그리고 `baz.s' 만이 명령안에서 컴파일러에 대해 지정되어야 한다는 것을 말한다.
$(filter-out pattern...,text)
이 함수는 text에서 pattern 단어들과 일치하는, 공백문자들로 분리된 단어들을 모두 제거하고 일치하지 않는 단어들만을 리턴한다. 이것은 filter 함수의 정확한 반대이다. 예를 들어서, 다음이 주어졌다면:
objects=main1.o foo.o main2.o bar.o
mains=main1.o main2.o
다음은 `mains'에 있지 않는 오브젝트 파일들 모두를 담고 있는 리스트를 생성한다:
$(filter-out $(mains),$(objects))
$(sort list)
이 함수는 list에 있는 단어들을 렉시컬(사전) 순서로 소팅하고 중복도니 단어들을 제거한다. 그 결과는 단일 스페이스들로 분리된 단어들의 리스트이다. 그래서,
$(sort foo bar lose)
이것은 `bar foo lose'를 리턴한다. 부수적으로 sort 함수는 중복된 단어들을 제거하기 때문에 이것을 소팅 순서에 대해서 신경쓰지 않더라도 이런 목적으로 이 함수를 사용할 수 있다.

다음은 substpatsubst 사용의 현실적인 예제이다. makefile이 VPATH 변수를 사용하여 make가 종속 파일들을 검색해야 할 디렉토리 리스트를 지정한다고 가정하자 (see section VPATH: 모든 종속물에 대한 검색 패스(Search Path for All Dependencies)). 이 예제는 C 컴파일러에게 동일한 디렉토리 리스트에서 헤더 파일들을 찾는 방법을 말하는 방법을 보여준다.

VPATH의 값은 `src:../headers'와 같이 콜론으로 분리되는 디렉토리 리스트이다. 첫번째, subst 함수는 콜론들을 스페이스들로 변경하는 데 사용된다:

$(subst :, ,$(VPATH))

이것은 `src ../headers'를 만든다. 그리고 나서 patsubst는 각 디렉토리 이름을 `-I' 플래그로 변경하는 데 사용된다. 이것은 변수 CFLAGS의 값에 더해질 수 있다. 이것은 자동으로 다음과 같이 C 컴파일러에게 전달된다:

override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))

이것의 효과는 텍스트 `-Isrc -I../headers'CFLAGS에게 사전에 주어졌던 값에 덧붙이는 것이다. override 지시어는, CFLAGS의 이저의 값이 명령 매개변수로 주어졌다 하더라도 새로운 값이 할당되도록 하는 데 사용된다 (see section override 지시어).

파일 이름들을 위한 함수(Functions for File Names)

내장 확장 함수들 몇가지는 특별히 파일 이름들을 또는 파일 이름들 리스트를 분해하는 데 연관이 있다.

다음 함수들 몇가지는 파일 이름에 대해서 특정 변환을 수행한다. 함수의 매개변수는 공백문자로 분리된, 일련의 파일 이름들로 취급된다. (앞뒤에 있는 공백문자들은 무시된다.) 이 일련의 파일 이름들 각각은 동일한 방식으로 변환되고 그 결과는 그들 사이에 단일 스페이스들을 넣어서 묶인 것이 된다.

$(dir names...)
이것은 names에 있는 각 파일 이름에서 디렉토리-파트를 추출한다. 파일 이름의 디렉토리-파트는 그 안에 있는 마지막 슬래쉬까지의 (그리고 이 마지막 슬래쉬를 포함한) 모든 것이다. 그 파일 이름이 슬래쉬가 없으면 디렉토리 파트는 문자열 `./'가 된다. 예를 들어서,
$(dir src/foo.c hacks)
`src/ ./'라는 결과를 만든다.
$(notdir names...)
이 함수는 names에 있는 각 파일 이름의 디렉토리-부분을 제외한 모든 것을 추출한다. 파일 이름에 슬래쉬가 없으면 변화되지 않는다. 그렇지 않는 경우 마지막 슬래쉬까지 모든 것이 그것으로부터 제거된다. 슬래쉬로 끝나는 파일 이름은 빈 문자열이 될 것이다. 이렇게 되는 것은 불행한 것이다. 왜냐면 이렇게 되는 것은, 그 결과가 항상 매개변수가 가지는 것과 동일하지 않은 개수의 공백으로-분리된 파일 이름들을 가진다는 것을 의미하기 때문이다; 그러나 우리는 다른 어떤 유효한 대안을 보지 못했다. 예를 들어서,
$(notdir src/foo.c hacks)
`foo.c hacks'라는 결과를 만든다.
$(suffix names...)
이 함수는 names에 있는 각 파일 이름의 접미사(확장자 ?)를 추출한다. 파일 이름이 소숫점(period)를 갖고 있다면 접미사는 마지막 소숫점부터 시작한 모든 것이다. 그렇지 않다면 접미사는 빈 문자열이다. 이것은 종종, names가 빈 것이 아닐 때도 그 결과가 빈 것이 될 수도 있으며, names가 다수의 파일 이름들을 가진다 하더라도 그 결과는 더 적은 개수의 파일 이름들을 가질 수 있다는 것을 의미한다. 예를 들어서,
$(suffix src/foo.c src-1.0/bar.c hacks)
`.c .c'라는 결과를 만든다.
$(basename names...)
이 함수는 names에 있는 각 파일 이름의 접미사를 제외한 모든 것을 추출한다. 파일 이름이 소숫점을 갖고 있다면 basename은 처음부터 마지막 소수점까지의 (소숫점은 포함하지 않음) 모든 것이 된다. 디렉토리 부분에 있는 소숫점들은 모두 무시된다. 소숫점이 없으면 basename은 전체 파일 이름이 된다. 예를 들어서,
$(basename src/foo.c src-1.0/bar hacks)
`src/foo src-1.0/bar hacks' 라는 결과를 만든다.
$(addsuffix suffix,names...)
매개변수 names는 공백문자들로 분리된, 일단의 이름들로 취급된다; suffix는 유닛으로써 사용된다. suffix의 값은 각 개별 이름의 끝에 더해지고 그들 사이에 단일 스페이스들을 추가한 더 큰 이름들이 그 결과이다. 예를 들어서,
$(addsuffix .c,foo bar)
`foo.c bar.c'라는 결과를 만들어낸다.
$(addprefix prefix,names...)
매개변수 names는 공백문자들로 구분된, 일단의 이름들로 취급된다; prefix는 유닛으로써 사용된다. prefix의 값은 각 개별 이름의 앞에 붙고, 그들 사이에 단일 스페이스들로 채워 연결된 더 커다란 이름들이 결과이다. 예를 들어서,
$(addprefix src/,foo bar)
`src/foo src/bar'라는 결과를 만든다.
$(join list1,list2)
이것은 두 매개변수들을 단어 단위로(word by word) 연결(concatenate)한다: 연결된 두개의 첫 단어들(각 매개변수에서 가지고 온 것)이 결과의 첫번째 단어를 구성하고 두개의 두번째 단어들이 결과의 두번째 단어를 구성한다. 이런식으로 계속된다. 그래서 결과의 n번째 단어는 각 매개변수의 n번째 단어로부터 온다. 한 매개변수가 다른 것보다 더 많은 단어들을 가진다면 여분의 단어들은 변경없이 결과에 복사된다. 예를 들어서 `$(join a b,.c .o)'`a.c b.o'를 생성한다. 리스트에서 단어들 간의 공백문자는 보존되지 않는다; 이것은 단일 스페이스로 대체된다. 이 함수는 dirnotdir 함수들의 결과들을 머지(merge)해서 이들 두 함수들에 주어진 파일들의 오리지널 리스트를 만들 수 있다.
$(word n,text)
이것은 textn번째 단어를 리턴한다. n의 합법적인 값은 1부터 시작한다. ntext에 있는 단어들 개수보다 더 크다면 그 값은 빈 것이 된다. 예를 들어서,
$(word 2, foo bar baz)
`bar'를 리턴한다.
$(wordlist s,e,text)
이것은 s로 시작하고 e로 끝나는(각각 포함) text안의 단어들 리스트를 리턴한다. se의 합법적인 값들은 1부터 시작한다. stext에 있는 단어들 개수보다 크다면 그 값은 빈 것이 된다. etext에 있는 단어들 개수보다 크다면 text의 끝까지의 단어들이 리턴된다. se보다 더 크다면 make는 그들을 서로 맞바꾼다(swap). 예를 들어서,
$(wordlist 2, 3, foo bar baz)
`bar baz'를 리턴한다.
$(words text)
이것은 text에 있는 단어들 개수를 리턴한다. 그래서, text의 마지막 단어는 $(word $(words text),text) 로 표현될 수 있다.
$(firstword names...)
names 매개변수는 공백으로 분리된, 일단의 이름들로 생각된다. 그 값은(이 함수의 결과값은) 그 시리즈의 첫번째 이름이다. 이름들의 마지막은 무시된다. 예를 들어서,
$(firstword foo bar)
`foo'라는 결과를 만든다. 비록 $(firstword text)$(word 1,text)과 같지만 firstword 함수는 그 단순성 때문에 남았다.
$(wildcard pattern)
pattern 매개변수는 파일 이름 패턴이다. 전형적으로 와일드 카드 문자들 (쉘 파일 이름 패턴과 동일한) 을 담고 있다. wildcard 함수의 결과는 패턴과 일치하는 현존하는 파일들의 이름들을 스페이스로 분리한 리스트이다. See section 파일 이름에 와일드카드 사용(Using Wildcard Characters in File Names).

foreach 함수(The foreach Function)

foreach 함수는 다른 함수들과 아주 다르다. 이것은 텍스트의 한 조각이 반복적으로 사용되도록 한다. 이때 매번 그것에 대해서 다른 대입이 수행된다. 이것은 쉘 shfor 명령, 그리고 C-쉘 cshforeach 명령과 닮은 것이다.

foreach 함수의 문법은 다음과 같다:

$(foreach var,list,text)

첫번째 두 매개변수들, varlist는 다른 것이 수행되기 전에 확장된다; 마지막 매개변수 text는 동일한 시간에 확장되지 않는다. 그리고 나서 list의 확장된 각 단어에 대해서 var의 확장된 값을 가지는 변수는 이 단어로 설정되고 그 다음에 text가 확장된다. 아마 text는 그 변수에 대한 참조를 담고 있을 것이다. 그래서 그것의 확장은 매번 다르다.

결과적으로 textlist에 있는 공백으로-분리된 단어들 개수만큼 확장된다. text의 여러 확장들이 그들 사이에 스페이스들을 넣어서 연결되어 foreach의 결과를 만든다.

다음 단순한 예제는 변수 `files'`dirs' 리스트의 디렉토리들에 있는 모든 파일들의 리스트로 설정한다.

dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

여기서 text`$(wildcard $(dir)/*)'이다. 첫번째 반복은 dir에 대해서 값 `a'을 찾아 넣고서 `$(wildcard a/*)'와 동일한 결과를 생산한다; 두번째 반복은 `$(wildcard b/*)'이라는 결과를 생성한다; 그리고 세번째는 `$(wildcard c/*)'.

이 예제는 다음 예제와 동일한 (`dirs'를 설정하는 것 빼고) 결과를 가진다:

files := $(wildcard a/* b/* c/* d/*)

text가 복잡할 때, 추가의 변수로, 그것에 이름을 주어서 가독성을 증진할 수 있다:

find_files = $(wildcard $(dir)/*)
dirs := a b c d
files := $(foreach dir,$(dirs),$(find_files))

여기서 우리는 변수 find_files를 이런 식으로 사용하고 있다. 우리는 평범한 `='를 써서 재귀적으로-확장되는 변수 하나를 정의했다. 그래서 그것의 값을 foreach의 제어하에서 다시 확장되어지는 실제 함수 호출에 따라서 가진다; 단순하게-확장되는 변수는 그렇지 않을 것이다. 왜냐면 wildcardfind_files를 정의하는 순간에 한번만 호출될 것이기 때문이다.

foreach 함수는 변수 var에 대한 항구적인 효과를 가지지 않는다; foreach 함수 호출 이후 이것의 값과 취향은 그들이 이전에 그랬던 것과 동일하다. 다른 list로부터 취해진 다른 값들은 잠시 동안만, foreach의 실행 동안만, 효력이 있다. 변수 varforeach의 실행동안 단순하게-확장되는 변수이다. varforeach 함수 호출 이전에 정의된 것이 아니라면 이것은 그 호출 뒤에도 정의된 것이 아니다. See section 변수의 두 취향(The Two Flavors of Variables).

변수들 이름들을 결과로 가지는 복잡한 변수 표현식을 사용할 때 상당히 조심해야 한다. 왜냐면 많은 이상한 것들이 유효한 변수 이름들이지만 여러분이 의도한 것이 아닐 수도 있기 때문이다. 예를 들어서,

files := $(foreach Esta escrito en espanol!,b c ch,$(find_files))

이것은 find_files 값이 이름이 `Esta escrito en espanol!' (es un nombre bastante largo, no?) 인 변수를 참조하고 있다면 유용하겠지만 이것은 실수일 가능성이 더많다.

origin 함수(The origin Function)

origin 함수는 변수들의 값에서 나타나지 않는다는 점에서 다른 함수들과 다르다; 이것은 하나의 변수에 대해서 어떤 것을 말하는 것이다. 특별히 이것은 이것이 어디로부터 온 것인가를 말한다.

origin 함수의 문법은 다음과 같다:

$(origin variable)

variable은 질의하고 있는 변수의 이름이다; 그 변수에 대해서 참조하는 것은 아니다. 그러므로 그것을 쓸 때 `$'나 괄호들을 일반적인 경우처럼 쓰지 않을 것이다. (그러나 그 이름안에서 변수 참조를 쓸 수 있다. 상수가 아닌 이름을 원한다면 말이다.)

이 함수의 결과는 그 변수 variable이 정의된 방법을 말하는 문자열이다:

`undefined'
변수 variable이 절혀 정의된 바가 없다면 이 값을 가진다.
`default'
변수 variable이, CC나 기타 등등처럼 일반적인 디폴트 정의를 갖고 있다면 이 값을 가진다. See section 묵시적 규칙에 의해 사용되는 변수(Variables Used by Implicit Rules). 디폴트 변수를 재정의한 것이라면 origin 함수는 추후 정의의 원천(origin)을 리턴할 것이다.
`environment'
variable 가 환경 변수로써 정의된 것이고 `-e' 옵션이 켜진 것이 아니라면 이 값을 가진다. (see section 옵션들의 요약(Summary of Options)).
`environment override'
variable 가 환경 변수로 정의되었고 `-e' 옵션이 켜졌다면 이 값을 가진다 (see section 옵션들의 요약(Summary of Options)).
`file'
variable이 makefile에서 정의된 것이라면 이 값을 가진다.
`command line'
variable이 명령행에서 정의된 것이라면 이 값을 가진다.
`override'
variableoverride 지시어로 makefile에서 정의된 것이라면 이 값을 가진다 (see section override 지시어).
`automatic'
variable이 각 규칙의 명령들의 실행에 대해서 정의된 자동 변수라면 이 값을 가진다 (see section 자동 변수들(Automatic Variables)).

이 정보는 주로 어떤 변수의 값을 믿고자 하는가 안하는가를 결정할 때 유용하다 (호기섬을 충족하는 것 말고). 예를 들어서 다른 makefile `bar'를 포함하는 makefile `foo'를 가지고 있다고 가정하자. 명령 `make -f bar'를 실행한다면, 환경이 bletch의 정의를 갖고 있다고 하더라도, bletch`bar'에 정의된 것을 원한다. 그러나 `foo'`bar'를 포함하기 전에 bletch를 정의했다면 그 정의를 오버라이드하기를 원하지 않을 것이다. 이것은 override 지시어를 `foo'에서 사용하고 그 정의를 `bar'에서 나중의 정의 이전에 정의함으로써 그렇게 할 수 있다; 불행하게도 override 지시어는 모든 명령행 정의들을 오버라이드할 것이다. 그래서, `bar'는 다음을 포함할 수 있을 것이다.

ifdef bletch
ifeq "$(origin bletch)" "environment"
bletch = barf, gag, etc.
endif
endif

bletch가 환경으로부터 정의되었다면 이것은 그것을 재정의할 것이다.

bletch의 이전 정의를 override하고자 하고 이것이 환경으로부터 온 것이라면, `-e'하에서조차, 여러분은 다음과 같이 쓸수 있을 것이다:

ifneq "$(findstring environment,$(origin bletch))" ""
bletch = barf, gag, etc.
endif

여기서 `$(origin bletch)'`environment' 또는 `environment override' 를 리턴한다면 재정의가 일어난다. See section 문자 대입과 분석을 위한 함수들(Functions for String Substitution and Analysis).

shell 함수(The shell Function)

shell 함수는 wildcard 함수 (see section wildcard 함수(The Function wildcard))를 제외하고, 이것이 make의 바깥 세상과 통신한다는 점에서, 다른 함수들과 다르다.

shell 함수는 대부분의 쉘에서 역홑따옴표(``')가 수행하는 기능과 동일한 기능을 수행한다: 이것은 command expansion을 한다. 이것은 쉘 명령인 매개변수를 취하고 명령의 결과를 리턴한다는 것을 의미한다. make가 이 결과에 대해서, 주변 텍스트로 이것을 대입하기 전에, 하는 유일한 처리는 각 개행이나 캐리지-리턴 / 개행 쌍을 단일 공백으로 변환하는 것이다. 이것은 또한 끝에 달린 (캐리지-리턴과) 개행을, 이것이 결과의 마지막이라면, 제거한다.

shell함수에 대한 호출에 의해서 실행된 명령은 함수 호출이 확장될 때 실행된다. 대부분의 경우 이것은 makefile이 읽힐 때이다. 규칙의 명령안에 있는 함수 호출들은 그 명령이 실행될 때 확장된다는 것이 예외이며, 이것은 다른 모든 것들과 마찬가지로 shell이라는 함수 호출에도 적용되는 것이다.

다음은 shell 함수의 사용에 대한 몇가지 예제들이다:

contents := $(shell cat foo)

이것은 contents`foo' 파일의 내용으로 설정한다. 각 라인을 분리하는 공백들(개행이라기 보다는)로.

files := $(shell echo *.c)

이것은 files`*.c'의 확장으로 설정한다. make가 아주 이상한 쉘을 사용하고 있지 않다면 이것은 `$(wildcard *.c)'과 동일한 결과를 얻는다. 


출 처 : http://www.viper.pe.kr/docs/make-ko/make-ko_8.html


이 글은 2008년에 운영하던 블로그에서 가지고 온 글입니다. 지금 그 블로그는 짤려서 관리자만 접속이 가능하더군요.
(약간 수정을 했습니다.)
-----------------------------------------------------------------------------------------------------
안녕하세요~
이번 포스팅은 데비안에서 커널 컴파일 하는것을 알아 보겠습니다!
자! 터미털을 하나 여시구요~!
차근차근 하나씩 따라해 주세요~!

1.커널 소스를 다운 받습니다.
http://kernel.org/ 에서 다운 최신 커널을 받으시면 됩니다~

2.데비안식 컴파일을 위한 패키지를 다운 받습니다.
oropinut@localhost:~$ su
Password:
localhost:/home/oropinut# apt-get install kernel-package libncurses5-dev
여기서 kernel-package는 make-kpkg를 사용하기 위해 설치를 하고..
libncurses5-dev는 make menuconfig 등의 유틸리티를 사용하기 위해 설치를 합니다.

3.커널 소스 압축을 풉니다.
localhost: /home/oropinut# mv linux-2.6.25.6.tar.bz2 /usr/src
localhost: /home/oropinut# cd /usr/src
localhost: /home/oropinut# tar xjvf linux-2.6.25.6
localhost: /usr/src# ln -s /usr/src/linux-2.6.25.6 /usr/src/linux

4.컴파일 옵션을 설정 합니다.
localhost: /usr/src# cd linux-2.6.25.6
localhost: /usr/src/linux-2.6.25.6# make menuconfig

5.컴파일 시작합니다.
localhost: /usr/src/linux-2.6.25.6# make-kpkg --revision=25.6 --initrd binary-arch

6.커널 패키지를 설치합니다.
localhost: /usr/src/linux-2.6.25.6# cd ~
localhost: /root# dpkg -i linux-headers-2.6.25.6_25.6_i386.deb
localhost: /root# dpkg -i linux-image-2.6.25.6_25.6_i386.deb

7.재시작을 합니다.
localhost: /root# shutdown -r now

자~! 커널컴파일이 끝났습니다~
재시작 하면 grub에 경우 자동으로 추가가 됩니다.

만약 틀린게 있거나 설명이 부실하다면 밑에 추가 내용을 써 주세요~

By oropinut(http://oropinut.tistory.com)

+ Recent posts