전공과목 정리/리눅스시스템 + 시스템프로그래밍

[리눅스시스템🐧] 11장 프로그래밍 환경

최연재 2024. 1. 6. 22:48

교재 : 리눅스 시스템 원리와 실제 (창병모, 생능출판)

 

11.1 프로그램 작성과 컴파일

1) gedit 문서 편집기 -> 프로그램 작성

2) gcc 컴파일러

- gcc(GNU cc) 컴파일러 : c 프로그램을 컴파일한다. 옵션을 사용하지 않으면 실행파일 a.out를 생성한다.

$ gcc [-옵션] 파일

- 간단한 컴파일 및 실행

$ gcc test.c
$ a.out // 실행

- -c 옵션: 목적 파일 생성

$ gcc -c test.c

- -o 옵션: 실행 파일 생성

$ gcc -o result test.o
$ gcc -o result test.c

- 실행

$ result

 

3) 다중 모듈 프로그램

(1) 단일 모듈 프로그램

  • 코드의 재사용이 어렵고 여러 사람이 참여하는 프로그래밍이 어렵다. 

ex)

#include <stdio.h>
#include <string.h>
#define MAXLINE 100

char line[MAXLINE]; // 입력 줄
char longest[MAXLINE] // 가장 긴 줄
void copy(char from[], char to[]);

// 입력줄 가운데 가장 긴 줄 프린트
int main() 
{
	int len, max=0;
    while (fgets(line, MAXLINE, stdin)!=NULL){
    	len = strlen(line);
        if (len > max){
        	max = len;
            copy(line, longest);
        }
    }
    
    if (max > 0) // 입력 줄이 있었다면
    	printf("%s", longest);
        
    return 0;
}

// from을 to에 복사 (to가 충분히 크다고 가정)
void copy(char from[], char to[]) {
	int i=0;
    while ((to[i] = from[i])!='\0') ++i;
}

(2) 다중 모듈 프로그램

  • 여러 개의 .c 파일들로 이루어진 프로그램
  • 일반적으로 복잡하며 대단위 프로그램인 경우에 적합

ex) main 프로그램과 copy 함수를 분리하여 별도 파일로 작성

- 파일

  • main.c
#include <stdio.h>
#include <string.h>
#include "copy.h"
#define MAXLINE 100

char line[MAXLINE]; // 입력 줄
char longest[MAXLINE] // 가장 긴 줄

// 입력줄 가운데 가장 긴 줄 프린트
int main() 
{
	int len, max=0;
    while (fgets(line, MAXLINE, stdin)!=NULL){
    	len = strlen(line);
        if (len > max){
        	max = len;
            copy(line, longest);
        }
    }
    
    if (max > 0) // 입력 줄이 있었다면
    	printf("%s", longest);
        
    return 0;
}
  • copy.c
#include <stdio.h>

// from을 to에 복사 (to가 충분히 크다고 가정)
void copy(char from[], char to[]) {
	int i=0;
    while ((to[i] = from[i])!='\0') ++i;
}
  • copy.h // 함수의 프로토타입을 포함하는 헤더파일
#define MAXLINE 100

void copy(char from[], char to[]);

 

- 컴파일 :

$ gcc -c main.c
$ gcc -c copy.c
$ gcc -o main main.o copy.o

or

$ gcc -o main main.c copy.c

 

11.2 자동 빌드 도구

1) make 시스템의 필요성

- 다중 모듈 프로그램을 구성하는 일부 파일이 변경된 경우

: 변경된 파일만 컴파일하고 파일들의의존관계에 따라서 필요한 파일만 다시 컴파일하여 실행파일을 만드는 것이 좋음.

 

- 예

  1. copy.c 소스 코드를 수정
  2. 목적 파일 copy.o 생성
  3. 실행 파일 생성

- make 시스템

  • 대규모 프로그램의 경우 헤더, 소스 파일, 목적 파일, 실행 파일의 모든 관계를 기억하고 체계적으로 관리하는 것이 필요
  • make 시스템을 이용하여 효과적으로 작업

2) 메이크파일

- 메이크파일 : 실행 파일을 만들기 위해 필요한 파일들과 그들 사이의 의존 관계를 기술

- make 시스템 : 메이크파일을 이용하여 파일의 상호 의존 관계를 파악하여 실행 파일을 쉽게 다시 만듦.

- 사용법 : make 시스템은 메이크파일(makefile, Makefile)을 이용하여 보통 실행파일을 빌드한다. (옵션을 사용하여 별도의 메이크파일을 지정할 수 있다.)

$ make [-f 메이크파일]

- 메이크파일의 구성 형식

목표(target): 의존리스트(dependencies)
    명령리스트(commands)

ex)

main: main.o copy.o
    gcc -o main main.o
    copy.o
main.o: main.c copy.h
   gcc -c main.c
copy.o: copy.c
    gcc -c copy.c

 

 

11.4 gdb 디버거

1) gdb

- 가장 대표적인 디버거 : GNU debugger (gdb)

-  gdb 주요 기능

  • 정지점(breakpoint) 설정
  • 한 줄씩 실행
  • 변수 접근 및 수정
  • 함수 탐색
  • 추적(tracing)

- 명령어 : gdb 디버거는 실행파일을 이용하여 디버깅 모드로 실행한다.

$ gdb [실행파일]

- gdb 사용을 위한 컴파일 : -g 옵션을 이용

ex)

$ gcc -g -o longest longest.c
$ gcc -g -o main main.c copy.c

 

2) gdb 기능

- 소스 보기 : l

  • l [줄번호]  : 지정된 줄을 프린트
  • l [파일명]:[함수명] : 지정된 함수를 프린트
  • set listsize n : 출력되는 줄의 수를 n으로 변경

- 정지점 : b(reak), clear, d(elete)

  • b [파일:]함수 : 파일의 함수 시작 부분에 정지점 설정
  • b n : n번 줄에 정지점을 설정
  • b +n : 현재 줄에서 n개 줄 이후에 정지점 설정
  • b -n : 현재 줄에서 n개 줄 이전에 정지점 설정
  • info b : 현재 설정된 정지점을 출력
  • clear 줄번호 : 해당 정지점 삭제
  • d : 모든 정지점 삭제

- 프로그램 수행

  • r(un) 인수 : 명령줄 인수를 받아 프로그램 수행
  • k(ill) : 프로그램 수행 강제 종료
  • n(ext) : 멈춘 지점에서 다음 줄을 실행하고 멈춤.
  • s(tep) : n과 같은 기능 함수 호출 시 함수 내부로 진입
  • c(ontinue) : 정지점을 만날 때까지 계속 수행
  • u : 반복문에서 빠져나옴
  • finish : 현재 수행하는 함수의 끝으로 이동
  • return : 현재 수행 중인 함수를 빠져나옴.
  • quit : 종료

- 변수 값 프린트 : p(rint)

  • p [변수명] : 해당 변수 값 프린트
  • p 파일명::[변수명] : 특정 파일의 전역변수 프린트
  • p [함수명]::[변수명] : 특정 함수의 정적 변수 프린트
  • info locals : 현재 상태의 지역 변수 리스트

 

11.4 vi 에디터 : 기본 텍스트 에디터

1) 명령 모드 / 입력모드

-vi 에디터는 명령 모드와 입력 모드가 구분되어 있으며 시작하면 명령 모드

- 마지막 줄 모드

  • :wq : 작업 내용을 저장하고 종료(ZZ와 동일한 기능)
  • :q : 아무런 작업을 하지 않은 경우 종료
  • :q! : 작업 내용을 저장하지 않고 종료

 

2) vi 내부 명령어

(1) 원하는 위치로 이동하는 명령어

- 커서 이동

  • h, ← : 한 칸 왼쪽
  • j, ↓ : 한 칸 아래쪽
  • k, ↑  : 한 칸 위쪽
  • l, → : 한 칸 오른쪽
  • BACKSPACE : 왼쪽으로 한 칸
  • SPACE : 오른쪽으로 한 칸
  • - : 이전 줄의 처음
  • + : 다음 줄의 처음
  • RETURN : 다음 줄의 처음
  • 0 : 현재 줄의 맨 앞
  • $ : 현재 줄의 맨 끝
  • ^ : 현재 줄의 첫 글자
  • W : 다음 단어의 첫 글자
  • B : 이전 단어의 첫 글자

- 화면 이동

  • ^F : 한 화면 아래로
  • ^B : 한 화면 위로
  • ^D : 반 화면 아래로
  • ^U : 반 화면 위로

- 특정 줄로 이동

  • nG : n번째 줄로 이동
  • 1G : 첫 줄로 이동
  • G : 마지막 줄로 이동
  • :n : n번째 줄로 이동

- 탐색(search)

  • /탐색패턴 : forward 탐색
  • ?탐색패턴 : backward 탐색

 

(2) 입력모드로 전환하는 명령어

  • i : 커서 위치 앞에 삽입
  • a : 커서 위치 뒤에 삽입
  • l : 현재 줄의 앞에 삽입
  • A : 현재 줄의 뒤에 삽입
  • o : 현재 줄의 아래에 전개
  • O : 현재 줄의 위에 전개

 

(3) 수정 혹은 삭제 명령

- 현재 커서를 중심으로 이동

  • r : 한 글자만 변경
  • R : 입력하는 대로 겹쳐 쓰기
  • s : 현재 글자 삭제 삽입 상태
  • C : 커서로부터 줄 끝까지 변경
  • cc : 현재 줄 전체를 변경
  • cw :  현재 단어를 삭제하고 변경

- 삭제

  • x : 커서가 있는 문자 지우기
  • X : 커서의 왼쪽 문자 지우기
  • D : 커서부터 줄 끝까지 지우기
  • dw :  현재 단어 삭제
  • dd : 현재 줄 삭제
  • :n,m d : n~m번째 줄 삭제

 

(4) 대체, 수행취소/재수행

- 대체 명령 : 각 줄의 해당되는 첫 번째 단어만 삭제

  • :s/패턴/스트링 : 현재 줄에서 대체
  • :n,m s/패턴/스트링 : 지정된 줄 범위에서 대체
  • :n s/패턴/스트링 : 지정된 줄(n)에서 대체
  • s/패턴/스트링/g : 해당되는 모든 단어 대체

- 수행취소/재수행

  • u : 방금 전 수행 내용 취소 (Undo)
  • U :  현재 줄 수행 내용을 취소 
  • . :  방금 전 수행 내용 반복

 

(5) 복사 및 붙이기

- 줄 내용 복사

  • nY : 현재 줄에서 n개의 줄 복사
  • :n,m y : n번째 줄에서 m번째 줄까지를 버퍼에 복사

- 마지막으로 삭제/복사한 내용 붙이기(put)

  • p : 버퍼 내용을 커서의 뒤(혹은 아래)에 삽입
  • P : 버퍼 내용을 커서의 앞(혹은 위)에 삽입

(6) 파일에 저장 및 끝내기

- 파일에 저장

  • :w : 현재 파일에 저장한다.
  • :w 파일이름 : 지정된 파일에 저장한다. 

- 파일에 저장하고 끝내기

  • :wq : 현재 파일에 저장하고 종료
  • ZZ : 현재 파일에 저장하고 종료한다.

- 저장하지 않고 끝내기

  • :q : 아무런 작업을 하지 않은 경우 종료
  • :q! : 작업 내용을 저장하지 않고 종료

 

(7) 기타 명령

- 다른 파일 편집

  • :e 파일이름 : 현재 파일 대신에 주어진 파일 열기
  • :e# : 이전 파일을 다시 열기

- 줄 번호 붙이기 : 줄 번호를 붙이거나 없애기

  • :set number : 줄번호 붙이기
  • :se nu : 줄번호 붙이기
  • :set nonuber : 줄 번호 없애기
  • :se non : 줄번호 없애기

- 쉘 명령어 수행 : 편집기 내에서 쉘 명령어 수행

  • :!ls
  • :!cat