검색결과 리스트
컴퓨터 연구/Linux 에 해당되는 글 106건
- 2021.04.02 우분투 패키지 생성
- 2019.04.24 MBR Partition Table 변경
- 2018.06.15 윈도우 설치할 때 콘솔 창 띄우기
- 2015.07.29 CentOS7에서 live555 빌드하기
- 2015.07.29 Samba 설정
- 2015.07.29 프로그래밍 언어로써의 셸
- 2015.07.29 셸 프로그래밍
- 2015.07.28 사용자 관리와 파일 속성 2
- 2015.07.28 make의 주석
- 2015.07.28 CentOS7 네트워크 설정
- 2015.07.28 리눅스에서 Samba 설치 및 설정
- 2015.07.27 make를 이용한 라이브러리 관리
- 2015.07.27 make 접미어와 패턴 규칙
- 2015.07.27 make 내장 규칙들
- 2015.07.27 make의 다중 대상
윈도우즈에는 .msi 설치 파일 또는 .exe 설치 파일이 있는데
우분투는 deb 파일이 있다
우분투에서는 패키지를 생성하기 위한 명령어를 dpkg 명령어를 이용한다
패키지를 생성하기 위해서는 다음과 같은 과정을 따른다
1. 기본 디렉토리 생성
패키지를 만들기 위한 디렉토리를 생성한다
예) mkdir mypack
이 폴더 안에는 다음과 같은 폴더가 존재해야 한다
- 한 개는 폴더이고 -- 두 개는 파일이다
mypack
- DEBIAN
-- control
-- preinst
-- postinst
-- prerm
-- postrm
- usr
- include
- lib
DEBIAN 폴더는 필수 폴더이고
* control
- 설치나 업로드 파일을 제어하기 위한 데이터를 가지고 있는 파일
- 하나 또는 그 이상의 문단으로 구성
문단은 빈 줄로 구성
각 문단은 보통 다른 패키지를 언급
(예 - 첫 번째 패키지 - 소스 패키지
두 번째 패키지 - 소스로부터 생성된 바이너리 패키지)
문단의 순서는 중요
- 문단은 일련의 데이터 필드로 구성
- Package : libc6 (Package - 필드 이름, libc6 - 필드 값)
빈 필드 값은 오직 소스 패키지 control 파일에서만 허용됨
바이너리 패키지에 관한 control 파일은 다음과 같은 속성을 가진다
1. Package (필수)
2. Source
3. Version (필수)
4. Section (추천)
5. Priority (추천)
6. Architecture (필수)
7. Essential
8. Depends et al
9. Installed-Size
10. Maintainer (필수)
11. Description (필수)
12. Homepage
13. Built-Using
위의 필드 목록은 다음 글에서 다룬다
* preinst
- 패키지 내에 포함된 파일을 설치하기 전에 실행되는 스크립트
* post inst
- 패키지 내 포함된 파일을 설치한 후에 실행되는 스크립트
* prerm
- 패키지 설치 이전 삭제해야 할 리스트
* postrm
- 패키지 설치 이후 삭제해야 할 리스트
Control File에서 Section 항목에 들어갈 수 있는 목록은 다음 사이트를 참조한다
packages.debian.org/unstable/
Debian -- List of sections in "sid"
List of sections in "sid" Administration Utilities Utilities to administer system resources, manage user accounts, etc. Mono/CLI Everything about Mono and the Common Language Infrastructure. Communication Programs Software to use your modem in the old fash
packages.debian.org
윈도우즈 10 을 설치할 때 NTFS로 대부분 포맷해서 진행한다
하지만 EFI 기반이라면 설치가 진행되지 않는다
따라서 변경해주어야 한다
1. 설치할 때 시리얼 키를 입력하라고 하면 Shift + F10을 눌려 도스 창을 띄운다
2. Diskpart 명령어를 입력한다
3. list disk 를 입력하여 디스크 목록을 선택한다
3. Windows를 설치할 파티션을 선택한다
- select disk 0
4. Clean을 해준다
- clean
5. 선택한 Disk를 GPT로 변경한다
- convert GPT
6. 나간다
- exit
7. 설치를 진행한다
- 윈도우 설치할 때 콘솔 창 띄우기
Shift + F10
누르면 됩니다.
콘솔 창 한 페이지 씩 넘기기
dir | more
Enter - 한 줄씩
Space - 한 페이지씩
http://www.live555.com/liveMedia/
여기에 가서 소스를 다운 받는다
0. g++을 설치한다
1. .tar.gz 확장자로 되어 있는 파일을 다운 받는다.
2. 압축을 푼다.
3. cd를 이용해서 live 디렉토리로 이동한다
4. ./genMakefiles <os-platform> 을 실행한다
- 여기서 <os-platform>은 "config.<os-platform>" 파일에 정의된 당신의 타겟 플랫폼이다.
ex) "linux" 또는 "solaris"
- 이것은 "live" 디렉토리와 각각의 서브 디렉토리에서 Makefile을 생성한다
5. make를 실행한다
- 만약 "make"가 실패하면 적절한 "config.<os-platform> 파일을 약간 수정할 필요가 있고,
다시 genMakefile을 "live" 디렉토리에서 재실행한다.
( COMPILE_OPTS 정의를 위해 또 다른 "-I <dir>" 플래그를 추가할 필요가 있을 수 있다.
- 일부 사람들은 디폴트로 미리 설치된 "make"의 버전보다 "gmake"라고 불리는 "make"의
GNU 버전이 더 잘 된다는 보고를 했다
- 만약 "gcc"버전이 3.0 이상이면, CPLUSPLUS_FLAGS에 -Wno-deprecated 플래그를
추가하기를 바랄 수도 있다
- 타켓 플랫폼에 대해 "config.<os-.platform>" 파일이 존재하지 않는다면,
템플릿으로 존재하는 파일들 중에 하나를 사용하여 시도해라
* 만약에 원하면, "make install"을 실행함으로써 헤더, 라이브러리, 응용프로그램을
또한 설치할 수 있다
0. g++, wget 설치
# yum install -y wget
# yum install -y gcc gcc-c++
1. .tar.gz 확장자 파일 다운
# wget www.live555.com/liveMedia/public/live555-latest.tar.gz
2. 압축을 푼다
# tar -xvzf live555-latest.tar.gz
3. cd를 이용해서 디렉토리로 이동한다
# cd live
4. ./genMakefiles <os-platform>을 실행한다
# ./genMakefiles linux-64bit
5. make를 실행한다
# make
6. RTSPClient 예제를 실행해본다
# cd testProgs
# ./testRTSPClient rtsp://xxx.xxx.xxx.xxx/ID
* Samba에서 공유 디렉토리 확인 방법
smbclient -L WindowsIP -U WindowsID
ex) smbclient -L 192.168.54.15 -U root5
* 공유할 디렉토리 마운트 방법
mount -t cifs //WindowsIP/Folder mountFolder/ -o username='root',password='1234'
ex) mount -t cifs //192.168.54.15/Samba linuxsamba/ -o username=root,password=1234
혹시나 username이나 password에 공백이 있으면 ' '로 묶어서 테스트 해본다
* 대화식 프로그램
- 키보드로 일련의 명령들을 입력해서 셸이 그것들을 실행하게 하는 방법
* 파일 작성법
- 명령들을 파일에 집어 넣고 그 파일을 하나의 프로그램으로서 실행하는 것
* 파이프와 재지정
$ ls -l > lsoutput.txt
: ls 명령의 출력을 lsoutput.txt라는 파일에 저장
표준 파일 서술자
0 : 프로그램의 표준 입력
1 : 프로그램의 표준 출력
2: 프로그램의 표준 오류 출력
만일 해당 파일이 이미 존재하면 새 내용이 기존 내용을 덮어 쓰게 된다
파일 끝에 새로운 내용을 덧붙이고 싶다면 >> 연산자를 사용한다
예를 들어,
$ ps >> lsoutput.txt
ps 명령의 출력을 해당 파일의 끝에 추가한다
표준 출력 이외의 출력을 재지정할 때는 > 연산자 앞에 해당 출력의 파일 서술자를 붙인다. 예를 들어 표준 오류 출력을 재지정하려 할 때에는 표준 오류 출력의 파일 서술자가 2이므로 2> 연산자를 사용하면 된다. 표준 오류의 재지정은 프로그램이 출력하는 오류 정보가 화면에 나타나지 않게 하고 싶을 때 유용하다
* 입력 재지정
$ more < killout.txt
killout.txt의 내용을 more에 입력한다
* 파이프
파이프 연산자( | )를 이용하면 프로세스들을 서로 연결할 수 있다. 리눅스에서는 파이프들로 연결된 프로세스들이 동시에 실행될 수 있으며, 자료가 흐름에 따라 자동으로 실행 일정이 조정된다. 간단한 예로, ps의 출력을 sort 명령으로 정렬해보자
만일 파이프를 사용하지 않으면 다음과 같이 두 단계를 거쳐야 한다
$ ps > psout.txt
$ sort psout.txt > pssort.out
그러나 파이프를 이용해서 프로세스들을 연결한다면 다음처럼 할 수 있다
$ ps | sort > pssort.out
그런데 출력 내용이 한 화면을 넘기면 보기 힘들어질 때 more를 추가하자
$ ps | sort | more
현실적으로 파이프로 연결할 수 있는 프로세스 개수는 한계가 없다
셀을 제외한 서로 다른 모든 프로세스들의 이름을 알파벳순으로 보고 싶다고 하자
$ ps -xo comm | sort | uniq | grep -v sh | more
이것은 ps의 출력을 알파벳순으로 정렬하고,
uinq를 이용해서 중복된 항목들을 제외하고,
grep -v sh를 이용해서 sh라는 이름의 프로세스를 제외하고,
마지막으로 이상의 결과를 페이지 별로 화면에 출력한다
이처럼, 각 명령의 결과를 개별 임시 파일에 저장하는 방식보다는 이처럼 명령들을 파이프로 연결하는 방식이 우아한 해법이다.
일련의 명령들을 수행할 때 같은 파일 이름을 두 번 사용해서는 절대 안된다
$ cat mydata.txt | sort | uniq > mydata.txt
를 수행하면 그냥 빈 파일이 만들어진다. mydata.txt 파일이 cat으로 읽히기 전에 덮여 쓰이기 때문이다.
리눅스에서 파일 관리를 하기 위해 먼저 알아야 할 파일의 속성을 알아보고,
다중 사용자 시스템인 리눅스에서 사용자를 관리하는 방법을 살펴보자
1. 사용자 그룹
리눅스는 다중 사용자 시스템이다. 즉 1대의 리눅스에 사용자 여러 명이 동시에 접속해서 사용할 수 있는 시스템이다.
리눅스를 설치하면 기본적으로 root라는 이름을 가진 슈퍼 유저가 있다.
이 root 사용자는 시스템의 모든 작업을 실행할 수 있는 권한이 있다.
또한 시스템에 접속할 수 있는 사용자를 생성할 수 있는 권한도 있다.
그런데 모든 사용자는 혼자서 존재하는 것이 아니라 하나 이상의 그룹에 소속되어 있어야 한다.
# vi /etc/passwd
이 파일을 열면 각 행의 의미는 다음과 같다
사용자 이름 : 암호 : 사용자ID : 사용자가 소속된 그룹 ID : 전체 이름 : 홈 디렉토리 : 기본 셸
이번에는 /etc/group 파일을 확인해보자
# vi /etc/group
각 행의 의미는 다음과 같다
그룹 이름 : 비밀번호 : 그룹 ID : 그룹에 속한 사용자 이름
CentOS7 수동 네트워크 설정
- 네트워크 — 어댑터 1 — 네트워크 어댑터 사용하기(E) 체크 — 다음에 연결됨(N) : 브리지 어댑터 — 무작위 모드 : 가상 머신에 허용 — 케이블에 연결됨 체크
- 네트워크 — 어댑터 2 — 네트워크 어댑터 사용하기(E) 체크 — 다음에 연결됨(N) : 브리지 어댑터 — 무작위 모드 : 가상 머신에 허용 — 케이블에 연결됨 체크
네트워크 설정 이전에 디바이스 이름 확인
# ip addr 을 입력하여 디바이스 이름을 확인한다
위의 그림에서는 enp0s3, enp0s8의 두 개의 디바이스 이름이 보인다
어댑터에 네트워크 설정을 하기 전에 디바이스 이름을 바꾸고 싶으면 다음을 참고한다
어댑터 1에 대한 네트워크 설정
- root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-enp0s3(DEVICE_NAME)
- 여기서 DEVICE_NAME은 Ethernet device name
- ( 이 예제에서는 DEVICE_NAME="centos_enp0s3" 이걸 입력)
- # vi /etc/sysconfig/network-scripts/ifcfg-DEVICE_NAME
- 여기에 다음과 같이 입력
- 저장 (편집 후 ESC - :wq - 엔터)
어댑터 2에 대한 네트워크 설정
- root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-enp0s3(DEVICE_NAME)
- 여기에 다음과 같이 입력
- 저장 (편집 후 ESC - :wq - 엔터)
- MAC 주소는 VirtualBox - 설정 - 네트워크 - 어댑터2 - 고급(D) - MAC 주소(M) 에 있는 것으로 설정
* 참고로 DHCP 설정은 다음과 같이 한다
- 리부팅(껐다 켜기)
- IP 주소는 고정 IP로 사용(브리지 설정)
명령어 용어
네트워크 통신 테스트
- yum check-update 입력해서 업데이트를 진행하는지 확인
- ping으로 테스트
필수 패키지 설치
$ yum
install
-y bind-utils // 네트워크 유틸리티
$ yum
install
-y vim // vi 개선 버전
$ yum
install
-y ntsysv // 서비스 관리
$ yum
install
-y system-config-firewall-tui // 방화벽 관리
$ yum
install
-y system-config-network-tui // 네트워크 관리
$ yum install -y setuptool // 관리프로그램 설치
$ yum install -y ntp // 시간 자동 설정 관리
윈도우즈 컴퓨터에 Virtual Box를 설치하고 CentOS7 리눅스를 설치했을 때
Samba를 이용해서 공유 폴더를 설정하자
* 실습
호스트(Windows)
- Windows에 자신의 자원을 사용할 사용자를 추가한다
- Windows의 자원을 공유시킨다
게스트(CentOS7)
- samba-client, cifs-utils를 설치한다
- smbclient 명령어로 Windows가 제공하는 자원을 확인한다
- smbmount 명령어로 Windows가 제공한 공유 폴더를 마운트한다
* 호스트(Windows)에서 폴더를 공유하자
1. Window 파일 탐색기에서 C:/CentOS_Common 폴더를 만든다(폴더 이름은 아무거나 해도 상관없다)
만든 폴더를 마우스 오른쪽 버튼으로 클릭한 다음 바로가기 메뉴에서 [속성] -> [공유]를 선택한 후, <공유> 버튼을 클릭해서 [그림 15-2]와 같이 Everyone 사용자를 선택한 다음 <추가>를 클릭하자
그리고 [사용 권한 수준]의 설정을 [읽기/쓰기]를 선택해 읽기 쓰기가 가능하도록 하고 <공유>를 클릭하자.
2. 최종적으로 '컴퓨터이름/CentOS_Common'이라는 네트워크 경로로 공유가 되었다. <닫기> 버튼을 클릭해서 공유 설정을 마친다. 공유한 폴더인 C:/CentOS_Common에 적당한 파일을 복사하자
3. 리눅스에서 접근을 허용하려면 리눅스에서 사용하려는 사용자를 추가하고 비밀번호를 지정해야 한다
명령 프롬프트를 관리자 모드(관리자 권한)로 실행한 후, 다음 명령을 입력하자
net user root 1234 /add --> root 사용자를 만들고 암호를 1234로 지정
필요하다면 제어판의 [사용자 계정]에서 추가된 root 사용자를 확인할 수 있다
ipconfig 명령어를 입력해서 Windows의 IP 주소를 확인하자
* 리눅스에서의 설정
- Windows에서 공유한 폴더를 게스트(CentOS7)에서 사용해보자
1. samba-client와 cifs-utils를 설치하자
yum install -y samba-client
yum install -y cifs-utils
2. 다음 명령어를 입력해 Windows에서 공유한 폴더가 보이는지 확인한다
smbclient -L WindowsIP주소
Enter root's password : --> Windows에서 생성한 root 사용자의 암호(1234)
공유된 컴퓨터의 이름과 공유 폴더(CentOS_Common)을 확인할 수 있다
3. 다음 명령을 입력해 Windows에서 공유한 폴더에 마운트할 디렉토리를 만들고 마운트 시킨다
mkdir 마운트할디렉토리이름(sambaMount)
mount -t cifs //WindowsIP주소/공유폴더이름 마운트할디렉토리이름
mount -t cifs //WindowsIP주소/CentOS_Common sambaMount
이상 폴더와 디렉토리가 공유되었다
* 더 이상 마운트할 필요가 없다면
unmount /CentOS_Common을 입력해 마운트를 종료한다
* Windows에서 리눅스 폴더와 프린터 사용
리눅스에서 공유해 놓은 디렉토리를 Windows에서 사용해보자
Windows 쪽에서는 별도로 설정해줄 것이 없다
Windows에서 리눅스의 자원을 사용해보자
1. samba와 system-config-samba 패키지를 설치하자
yum -y install samba system-config-samba
2. 디렉토리를 공유하자
systemctl restart smb
systemctl enable smb
systemctl status smb
를 차례로 입력해 Samba 서버를 시작/상시 가동/상태 확인하도록 설정하자
mkdir /share를 입력해 공유할 디렉토리를 생성하고, 'chmod 707 /share' 를 입력해 디렉토리 속성을 707로 변경한다
디렉토리 속성을 707로 변경한다
어느 정도 규모가 있는 프로젝트에서는 여러 컴파일 결과물들을 라이브러리 형태로 관리하는 것이 편할 때가 많다.
라이브러리는 목적 파일들을 하나로 합친 파일로, 관례적으로 .a라는 확장자(archive)를 가진다.
make 명령은 라이브러리를 편하게 관리할 수 있는 특별한 구문을 제공한다.
lib(file.o)라는 구문이 바로 그것인데, 이는 lib.a라는 라이브러리에 들어 있는 목적 파일 file.o를 지칭한다.
make에는 라이브러리 관리용 내장 규칙도 들어있다.
실제로 그 규칙을 풀어서 쓴다면 다음과 같다
.c.a:
$(CC) -c $(CFLAGS) $<
$(AR) $(ARFLAGS) $@ $*.o
이것은 .c 파일로부터 .a를 만들어내는 규칙이다.
보통의 경우 매크로 참조 $(AR)과 $(ARFLAGS)는 각각 ar과
옵션 rv로 확장된다. 따라서 이 규칙은
- 우선 소스 파일을 컴파일해서 목적 파일을 만들고,
- ar 명령을 이용해서 새 목적 파일을 라이브러리에 추가한다
이 규칙에는 여러 가지 특수 매크로들이 쓰이는데, 이들은 현재 시점에서의 해당 파일 이름들로 치환된다.
$< - 원본 이름
$@ - 대상 이름
$* - 접미어가 없는 이름
내장 규칙들은 파일 이름의 접미어(suffix)와 확장자를 기초로 적용된다.
특정한 접미어가 붙은 파일을 지정하면 make는 그에 해당하는 다른 접미어를 가진 파일을 생성한다.
대표적인 예는 .c와 .o 이다.
make는 이름에 .c가 붙은 파일을 컴파일해서 .o 파일을 만들어 낸다
이러한 접미어 기반 규칙을 사용자가 새로 만드는 것도 가능하다
이러한 경우 .cpp 파일로부터 목적 파일을 생성하는 새로운 접미어 규칙을 make에게 알려주는 것이다.
프로젝트에 소스 파일들이 많다고 할 때 이러한 접미어 규칙을 이용하면 Makefile이 훨씬 간결해지며, 또한 프로젝트에서 새 소스 파일을 추가하는 작업도 훨씬 쉬워진다.
Makefile에서 새 접미어 규칙을 추가할 때에는 두 가지 일을 해주어야 한다.
.SUFFIXES 명령으로 새 접미어를 등록하고
다음과 같은 형태의 대상에 실제 규칙을 지정해 주는 것이다.
.<기존 접미어> .<새 접미어> :
이러면 make는 접미어가 <기존 접미어>인 파일에 해당 규칙을 적용해서 이름이 같고 접미어가 <새 접미어>인 파일을 생성한다.
다음은 .cpp파일을 .o 파일로 컴파일하는 접미어 규칙이다
.SUFFIXES: .cpp
.cpp.o:
$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
여기서 .cpp.o: 라는 의존성 정의는 접미어가 .cpp인 파일을
그 아래의 규칙을 이용해서 .o 파일로 변환하라고
make에게 알려주는 역할을 한다
이런 형태의 의존성에 대한 규칙에서는 파일 이름을 명시적으로 지정할 수 없으므로 특별한 매크로들이 필요하다. 위의 규칙에서 $<을 볼 수 있을텐데,
이는 원본 파일(기존 접미어를 가진 파일)의 이름으로 확장된다.
참고로 -xc++ 플래그는 gcc에게 이것이 C++ 소스 파일임을 알려주는 역할을 한다.
한 가지 주목할 것은 C++ 소스 파일들에 대해 단지 .cpp에서 .o 파일로의 규칙만 정의하면 된다는 점이다.
.o 파일들을 이진 실행 파일로 만드는 방법은 make가 이미 알고 있다.
이제 make를 실행하면 make는 위의 새 규칙을 이용해서 bar.cpp를 bar.o를 만들어내고, 그런 다음 자신의 내장 규칙들을 이용해서 .o로부터 실행 파일을 만들어 낸다.
요즘의 make는 .cpp 확장자를 가진 C++ 소스 파일을 다루는 방법을 알고 있지만, 이런 접미어 규칙을 이용하면 한 종류의 파일을 다른 종류의 파일로 변환할 때 일이 아주 편해진다.
좀 더 최근 버전의 make는 이러한 접미어 기반 변환이나 기타 여러가지 작업을 가능하게 하는 좀 더 유연한 구문을 지원한다. 예를 들어 특수 문자 %를 이용하면 파일 확장자에만 의존하는 것이 아니라 좀 더 일반적인 파일 이름 패턴 부합 기능에 의존해서 변환을 수행하는 의존성 정의를 만드는 것이 가능하다.
다음은 앞에 나온 .cpp 접미어 규칙을 패턴 규칙을 이용해서 표현한 것이다.
%.cpp: %o
$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<
빌드 과정의 각 단계를 Makefile에 명시적으로 지정했으나, make에 있는 여러 내장 규칙(built-in rule)들을 이용하면 Makefile들을 더 간단하게 만들 수 있다. 이런 접근 방식은 소스 파일들이 많은 경우에 더욱 유용하다
우선 Hello world 프로그램을 만든다 - foo.cpp
#include <iostream>
#include <stdlib.h>
int main( )
{
std::cout << "Hello world~~!\n";
exit(EXIT_SUCCESS);
}
Makefile을 지정하지 않고 make를 실행해보자
$ make foo
g++ foo.cpp -o foo
놀랍게도 make는 자신이 알고 있는 내장 규칙을 이용해서 소스 파일을 성공적으로 컴파일한다. 종종 이런 내장 규칙들을 추론 규칙(inference rules)이라고 부른다. 내장 규칙들은 매크로등을 사용하므로, 매크로들을 적절히 설정함으로써 내장 규칙의 기본 행동 방식을 변경할 수 있다.
make의 내장 규칙들은 -p 옵션으로 확인할 수 있다.
make -p
하나의 Makefile로 여러 개의 대상 파일들을 생성하거나 여러가지 작업들을 선택적으로 수행하는 게 바람직한 경우도 종종 있다
다음 실습에서는 기존의 Makefile에 불필요한 목적 파일들을 삭제하는 clean 대상과 최종 응용프로그램을 다른 디렉토리로 옮기는 install 대상을 추가한다
clean - 대상을 rm 명령을 이용해서 목적 파일들을 삭제
그런데 rm 앞에 -를 붙였기 때문에 make는 rm이 보고한 오류를 무시한다
따라서 목적파일들이 없어서 rm이 오류를 돌려준 경우에도 make는 작업을 계속 진행하게 된다.
clean:
-rm main.o 2.o 3.o
또 clean 대상의 : 다음에 아무 것도 없다는 점 역시 주목하기 바란다
이는 make에게 이 clean 대상은 어떠한 것에도 의존하지 않음을 알려주는 역할을 한다. 이 경우는 make는 clean 대상이 항상 낡은 것이라고 간주하며, 따라서 make 실행 시 clean을 지정하면 항상 이 대상의 규칙이 실행된다
install 대상의 규칙은 myapp에 의존한다. 따라서 make는 이 대상의 규칙을 실행하기 전에 반드시 myapp을 만든다. 이 대상의 규칙은 셸 스크립트 형태이다. make는 규칙을 실행할 때 셸을 호출하며 각 규칙에 대해 새로운 셸을 사용하므로, 스크립트 명령들 전부가 하나의 논리적인 스크립트 문장으로 실행되도록 각 줄 끝에 \를 붙였다. 또한 이 문장은 @로 시작하므로, make는 이 문장을 출력하지 않고 실행한다.
install 대상의 규칙은 응용 프로그램이 최종적인 장소에 설치될 때까지 여러 개의 명령들을 차례대로 수행한다. 그런데 이 규칙이 한 명령의 성공 여부로 그 다음 명령의 수행 여부를 결정하는 것은 아니다. 만일 한 명령이 성공적으로 수행된 경우에만 다음 명령이 수행되길 원한다면 다음 예처럼 &&로 명령들을 연결해야 한다