본문 바로가기
Computer Science/UNIX & Linux

[UNIX/Linux] ep0) 시스템 프로그래밍의 이해

by 클레어몬트 2024. 9. 4.

UNIX, 그야말로 운영체제계의 goat
모든 운영체제가 UNIX에 영향을 받았다고 해도 과언이 아니다. 심지어 Windows 까지도 분명 UNIX에 영향을 받은 부분이 무조건 있을 것이다. (Windows는 오픈소스가 아니라서 자기네들의 코드를 공개하지 않는다)

Windows를 제외하고는 모두 UNIX가 조상이다

 
서버의 운영체제는 요즘 90%가 다 Linux를 쓴다. 그래서 금융권에서는 UNIX를 Linux로 대체하는 U2L(UNIX to Linux)이 확산되고 있다.
 
※ 리눅스 시스템에서 라이브러리는 보통 /usr/lib 에 위치한다
정적 라이브러리: 프로그램을 컴파일할 때 같이 적재되어 실행 파일을 구성한다
공유 라이브러리: 실행 파일에 포함되지 않아 메모리를 효율적으로 사용하기 위해 사용한다
 


 

[파일시스템 - 파일과 디렉터리]

절대 경로(absolute path): 루트 디렉터리부터 시작하는 경로

상대 경로(relative path): 현재 디렉터리부터 시작하는 경로

 

(참고) 대부분 OS에서의 특수문자 기능

현재 디렉터리: . 

부모 디렉터리: .. 

홈 디렉터리: ~(틸다)

 

 


[유닉스(리눅스) 명령어] - 와일드카드(*) 적용 가능
ㅁ 로그인 / 로그아웃 명령
ㅇ ssh / telnet: 리눅스 시스템에 접속

$ ssh www.naver.com
$ telnet www.naver.com

 
(참고) 유닉스 서버 연결 명령어

ssh s19010809@203.250.148.46 -p 1074

 
하지만 이렇게 연결하면 rsa 암호화 알고리즘을 사용하라면서 에러가 난다. 서버의 rsa 알고리즘이 구식 알고리즘이라서(보안에 취약) macOS에서 지원하지 않거나 제한한다. 따라서 옵션을 이용해 사용할 수 있게 강제로 허용시켜야 한다.

ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa s19010809@203.250.148.46 -p 1074

 
ㅇ exit / logout: 리눅스 시스템에 접속 해제

$ exit
$ logout

 
 
ㅁ 파일/디렉터리 명령
ㅇ pwd : 현재 내 위치 확인 (print working directory)
 
ㅇ ls : 현재 선택할 수 있는 목록들을 보여줌 (list의 줄임말)
ls -l : line by line으로 파일 상세정보를 보여줌 / ls -a : 숨김파일까지도 보여줌 (list all)

ls -al : 모든 파일의 상세정보를 보여줌


ㅇ cd : 지정 위치를 이동하고자 할 때 / cd .. : 상위폴더로 이동 / cd ~ : home으로 이동 (change directory)
 
ㅇ touch 1.c : 1.c 파일 생성
 
ㅇ cp file1.c file2.c : file1.c 파일을 file2.c 이름으로 파일을 복사
cp -r 복사할 디렉터리 : 디렉터리를 복사
 
ㅇ mv 옮길 파일 / 옮길 장소 : 파일을 이동 / 이름을
 
ㅇ rm 1.c : 1.c 파일을 삭제
rm -r 삭제할 디렉터리 : 디렉터리를 삭제 (여기서 -r은 recursive의 r이다 - 재귀적으로 디렉터리 안의 내용을 모두 삭제해서)
 
ㅇ mkdir : directory 생성
 
ㅇ rmdir : 빈 directory 삭제
 
ㅇ cat 1.c : 1.c 파일 내용을 출력 (concatenate)
cat 1.c 2.c : 1.c와 2.c를 결합하여 출력
cat 1.c 2.c > newFile : 1.c와 2.c를 결합하여 새로운 파일을 만듦
 
ㅇ more 1.c : 1.c 파일 내용을 화면 크기에 맞춰서 출력
 
ㅇ chmod : 권한을 변경 (change mode)

읽기(r), 쓰기(w), 실행(x)


1. 기호 방식 - chmod [who][operator][permission] 파일명

  • who: u (소유자), g (그룹), o (기타 사용자), a (모든 사용자)
  • operator: + (추가), - (제거), = (설정)
  • permission: r (읽기), w (쓰기), x (실행), s (특별 권한), t (특별 권한)

예시)
chmod u+x file.txt: 소유자(u)에게 실행(x) 권한을 추가
chmod g-w file.txt: 그룹(g)에서 쓰기(w) 권한을 제거

chmod u+x,o-x file.txt: 소유자(u)에게 실행(x) 권한을 추가 + 기타 사용자(o)에게 실행(x) 권한을 제거
chmod a=r file.txt: 모든 사용자(a)에게 읽기(r) 전용 권한을 설정

 

(특별 권한)

SUID(s): 파일을 소유자의 권한으로 실행 (Set User ID)

SGID(s): 파일을 그룹 소유자의 권한으로 실행하거나 디렉터리 내 그룹 소유권을 상속 (Set Group ID)

Sticky Bit(t): 디렉터리 내에서 파일 삭제 및 이름 변경을 소유자만 가능하도록 제한 (보통 공용 디렉터리에 사용된다)

 
2. 8진수 방식: chmod [소유자][그룹][기타 사용자] 파일명
읽기(4), 쓰기(2), 실행(1)

 

  • 7 (읽기 + 쓰기 + 실행): 4 + 2 + 1 = 7
  • 6 (읽기 + 쓰기): 4 + 2 = 6
  • 5 (읽기 + 실행): 4 + 1 = 5
  • 0 (권한 없음): 0

예시)
chmod 755 file.txt: 소유자는 읽기/쓰기/실행(7), 그룹과 기타 사용자에게는 읽기/실행(5)을 부여
chmod 644 file.txt: 소유자는 읽기/쓰기(6), 그룹과 기타 사용자에게는 읽기(4)만 부여

 

(특별 권한) - 앞자리에 숫자를 하나 추가한다

SUID(4), SGID(2), Sticky Bit(1)

e.g. chmod 6111 file.txt: SUID와 SGID의 특별 권한, 소유자와 그룹과 기타 사용자에게는 실행(1)을 부여

 

ㅇ grep "검색어" 1.c : 1.c에서 "문자열"에 해당하는 패턴을 검색
 
ㅇ diff 1.c 2.c : 두 파일의 차이를 표시
 
ㅇ man [command] : 해당 커맨드의 매뉴얼을 보여줌 (manual)
man [command] 1 ls: 일반적인 명령에 대한 설명
man [command] 2 ls: 시스템 호출
man [command] 3 ls: 라이브러리 함수
※ 섹션 번호 없이 man 명령어를 실행하면 가장 낮은 섹션이 기본적으로 출력
 
ㅇ ifconfig : 네트워크 인터페이스 설정 및 확인 (interface configuration)
※ 최신 리눅스 배포판에서는 ifconfig 를 더 이상 기본적으로 설치하지 않고 대신 ip 명령어를 지원하는 경우가 많다
 
ㅇ clear : 터미널의 과거 명령 기록들을 다 지운다 (터미널 창을 깨끗하게 다 치워준다)
 
ㅇ open . : 현재 작업 파일을 엶 (CLI가 아닌 GUI로 직접 눈으로 보면서 할 수 있음)
 
ㅇ vim 1.c : 1.c 파일을 vim 에디터로 엶
 
 
ㅁ 프로세스 명령
ㅇ ps : 현재 실행 중인 프로세스 정보 출력
ps -ef : 모든 프로세스의 상세 정보 출력

 

ps -ef | grep ftp

 
ㅇ kill : 프로세스 종료
kill -9 : 프로세스 강제 종료

kill 5001

 
 
ㅁ 기타 명령

+ uname: 현재 운영체제 확인

 
 
 
[vim 단축키]
ㅁ입력모드: a, i, o
그냥 타이핑하면 된다
 
esc: 탈출
 
ㅁ편집모드
u : 되돌리기
ctrl + r : redo
dd : 한 줄 삭제
 
:q - quit
:q! - 강제종료
:w - write
:wq - write and quit
:wq! - 저장 후 강제종료
 
 
vimrc란?
vim에 관련한 사용자 커스텀 설정과 명령어를 저장하여 vim이 실행될 때마다 자동으로 적용되게 하는 파일이다. 이 파일을 통해 다양한 설정을 적용할 수 있으며, 기본적인 편집 기능을 플러그인 없이도 쉽게 설정할 수가 있다. (플러그인 사용 시 더 다양한 기능 사용 가능)
적용 방법은 최상위 루트 홈 디렉터리에 vimrc 파일을 추가해 주고 거기에 설정들을 세팅해 주면 된다.

일반적인 vimrc 파일의 위치:

  • Linux/MacOS: ~/.vimrc 또는 ~/.vim/vimrc
  • Windows: $HOME/_vimrc 또는 $VIM/_vimrc

[vimrc 커스텀 설정] vim ~/.vimrc
 
set ruler - 바이트 수 표기
set number - 옆에 줄 표기
syntax on - 색깔 넣어주는
set cindent - c언어 자동 들여주기
set autoindent - 이것도 자동 들여주기??
set wrap - ???
set colorcolumn=80 - 빨간 줄 행 표기 (왜냐하면 42서울의 놈 규격이 80줄 미만임)
:set moue=a - 마우스로 편집 가능
 
 
 
gcc(GNU Compiler Collection): GNU의 C 컴파일러
gcc test.c (일반적인 컴파일 방법)
gcc -o test test.c (그냥 컴파일을 하면 실행 파일명이 모두 a.out 으로 나오기 때문에 실행 파일명을 -o 옵션을 통해 지정해 준다)
-Wall 옵션: 코드 내에서 발생할 수 있는 여러 가지 잠재적인 문제들을 경고로 알려주는 옵션
 
 
(참고) for문 선언문에 for(int i = 0; …) 이렇게 하는 것은 C99부터 가능하기 때문에 만약 컴파일러 버전이 낮다면 컴파일할 때 따로 옵션을 붙여줘야 한다!

gcc -std=c99 -o test test.c

 
 
 
ㅁ Makefile: 유닉스 계열 운영체제에서 사용되는 프로그램 빌드 도구
make 명령: 파일 간 종속관계를 파악하여 Makefile(기술파일)에 적힌 대로 컴파일러에 명령하여 SHELL 명령이 실행되게 함(실행 파일을 생성)
자동화를 통해 시간 절약이 가능하다!
vi Makefile로 Makefile 만들고, make 명령어 해주면 명령 파일을 만들어준다
 
라이브러리 == 컴파일된 산물인 *. o(오브젝트) 파일을 여러 개 모아 놓은 것 
[확장자별 라이브러리 종류]
.a : 리눅스 / 정적 라이브러리
.so : 리눅스 / 동적 라이브러리
.lib : 윈도우 / 정적 라이브러리
.dll : 윈도우 / 동적 라이브러리
 
ㅇmake clean : 빌드 과정에서 생성된 임시 파일들(예: 오브젝트 파일, 실행 파일)을 삭제해 준다

CC = gcc
CFLAGS = -Wall # 모든 경고 메시지를 출력하도록 설정하는 옵션
TARGET = subnum # TARGET은 최종적으로 생성할 실행 파일의 이름을 정의

# 이 'all' 타겟은 $(TARGET), 즉 'subnum'을 만들어내는 작업을 수행
all: $(TARGET)

# 'subnum.o' 파일로부터 실행 파일 $(TARGET), 즉 'subnum'을 생성
$(TARGET): subnum.o
        $(CC) $(CFLAGS) -o $(TARGET) subnum.o

# 'subnum.c' 파일을 컴파일하여 'subnum.o' 오브젝트 파일을 생성
subnum.o: subnum.c
        $(CC) $(CFLAGS) -c subnum.c

# 오브젝트 파일(*.o)과 실행 파일 $(TARGET)을 삭제 (make clean 명령어)
clean:
        rm -f *.o $(TARGET)

※ Makefile에서는 들여쓰기를 space bar로 하면 안된다! 무조건 tab으로 해야 컴파일이 된다

 

 


 
+

 
ar rc [.c 파일명] - 해당 .c 파일에 들어있는 .o파일을 추출
 
ar : 아카이브 생성 명령어 (ar : archive)
 
r : 지정한 archive로 obj 파일 추가
c : archive(library file) 생성
 
LIBS = ranlib <- 링크할 때 필요한 라이브러리를 추가
 
ranlib
정적 라이브러리를 성공적으로 사용하기 위해서 일부 시스템, 특히 버클리(Berkeley) 유닉스로부터 파생된 시스템에서는 라이브러리 목차를 만들 필요가 있는데, 이를 위해 ranlib을 사용한다. 리눅스와 같이 GNU 소프트웨어 개발 도구를 사용할 때에는 이러한 것이 필요하지 않으며 또한 실행한다 하더라도 문제가 없다.
 
 
 
CC, TARGET, OBJS가 매크로이름이고, $(매크로)로 사용할 수 있다.
$(TARGET) 그리고 $(OBJS)가 두 번 나오면, 단순하게 $@, $^로 표현 할 수 있다.
 
.c.o을 TARGET으로 하면, Makefile의 .c파일을 모두  .o로 바꿔준다.
$@은 .o를 TARGET 한다는 말이고, $<는 이를 위해 .c를 사용한다는 말.
 
 
꼬리말 규칙, 패턴 규칙
.c.o:
  gcc -c $(CFLAGS} $<
여기에서 .c.o 는 c를 입력파일로 받고, o파일로 만든다는 말인데,
<는 유닉스에서 redirection이다. 즉, c파일을 입력받는다는 말
즉, gcc -c $(CFLAGS) example1.c example2.c 처럼 된다.
 
 
CFLAGS : 컴파일 옵션
-Wall은 모든 에러, -g는 디버깅 모드
 
 
SRC = src file명 나열
SRCS = ${addprefix ${DIR}, ${SRC}}
 
//addprefix 전치사를 붙여줌
//또는 addsuffix를 이용하여 file명에 .c 또는 .o를 붙여줄 수도 있음
//ex) SRCS = $(addprefix $(SRCS_DIR), $(addsuffix .c, $(FILES)))
 
 
 
 
ㅁ 명령행 인자: 프로그램을 실행할 때 명령어와 함께 전달하는 추가적인 값
- argc: 인자 갯수 (argument count)
- argv: 인자 입력값 (argument vector)
 


입력) ./addnum 1 5
출력) 15

#include <stdio.h>
#include <stdlib.h>

int addnum(int a, int b); // a ~ b의 sum

int main(int argc, char* argv[]) {
        int sum = addnum(atoi(argv[1]), atoi(argv[2]));

        printf("sum 1 ~ 5 = %d\n", sum);

        return(0);
}

int addnum(int a, int b) {
        int sum = 0;
		while (a <= b) {
        	sum += a;
        	a++;
        }
        return sum;
}

 

여기서 argc = 3, argv[0] = "addnum", argv[1] = "1", argv[2] = "5" 이다.
 


입력) ./my_test5.c -p

출력) Welcome to Linux System Programming World!!!

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
    if (argc == 1) {
        printf("Usable Options : -p -n -h\n");
    }
    else {
        if (strcmp(argv[1], "-p") == 0) {
            printf("Welcome to Linux System Programming World!!!\n");
        }
        else if (strcmp(argv[1], "-n") == 0) {
            printf("Nice to meet argv[2]\n");
        }
        else if (strcmp(argv[1], "-h") == 0) {
            printf("Usable Options -p -n -h\n");
        }

    }
    return 0;
}

 

argv[1]로 -p를 입력
 

 

 

 

 

 

(참고)

#include <unistd.h> 의 unistd는 unix standard의 약자이다 
대박 ㅋㅋ 처음 알았다..


참고 및 출처: 시스템 프로그래밍 리눅스&유닉스(이종원)