# System_Programming

# 1. LINUX

# 특징

  • 서버/클라우드에 많이 사용되는 운영체제
  • kernel + shell + system처럼 기본 프로그램만 설치되어있는 리눅스를 사용하면 c언어를 컴파일 하는것도 굉장히 빨라진다. 윈도우에서 네시간 걸리면 compile이 리눅스에서는 10분이면 될 수도 있다.
  • UNIX 계열이다.
  • 프로그래머 스타일이다.
  • plain하게 프로그래밍이 가능하다.
    • C언어도 몇가지가 있다.
    • ANSI C가 표준인데 리눅스에서 쓸 수 있다.

# History

  • Linus Torvalds

    • 가 유닉스를 기반으로 개발
    • 다중 사용자, 다중 작업(시분할 시스템, 멀티 태스킹)을 지원하는 유닉스와 유사
  • GNU 프로젝트 : GNU is not Unix

    • 유닉스는 여러 회사에서 각자 개발, 소스를 공유하지 않았다.

    • 리차드 스톨만 : 상호협력 문화로 돌아갈 것을 주장하며 GNU 선언문을 발표

    • 유닉스를 대체할 수 있는 공개돼있는 운영체제를 만들자! 그리고 이를 위해 Free Software Foundation 설립과 GNU Public License 규약을 만든다.

    • GPL : 기술은 공유하고 마음대로 수정 업데이트 가능하다. 그러나 새로 만든 기술은 마찬가지로 GPL을 따라야 한다.

    • 운영체제 커널 개발 시도 : GNU Hurd.

      image-20210509025719523

    • 운영체제를 만들기 위해선 만들어야 할 레이어들이 굉장히 많다.

    • vi : 유닉스 계열의 에디터. improved 버전은vim이라고 불린다.

    • 라이브러리, 컴파일러, 에디터, 쉘 이런것들을 다 만들어 줘야 유닉스를 대체할 수 있다.

  • GNU Project X Linux

    • 핵심인 커널 개발이 계속 지연된다.
    • 이때 리누스 토발즈가 리눅스 커널 소스를 오픈한다.
    • 리차트 스톨만의 GNU 프로젝트 산출물과 리눅스OS를 합치게 된다.
    • GNU도 열심히 만들었는데 억울하게 다들 리눅스라고만 불러서 스톨만이 슬퍼한다.

# Linux Files

  • 모든것은 파일이라는 철학이 있다.
    • 모든 인터렉션은 파일 I/O처럼 다루어진다. 외부디바이스도!
  • File Namespace
    • 윈도우 : A드라이브, C드라이브
    • 리눅스 : 전역 네임스페이스
      • /media/floppy/
  • 파일은 inode 고유값과 자료구조에 의해 주요 정보 관리

# Linux Process

  • 리눅스 실행 파일 : ELF(Executable and Linkable format)
    • 프로세스의 구조(stack, heap, text, data, bss 등을 정의한다)
  • 다양한 시스템 리소스
    • 시스템콜 호출을 통해 리소스 처리 관리 가능
      • 타이머, 시그널, 파일, 네트워크, 디바이스, IPC
  • 가상 메모리 지원
  • 프로세는 pid(프로세스ID) 고유값을 구분. (파일은 inode)
  • init 프로세스(첫번째 프로세스)를 기반으로 fork() 시스템콜을 해서 부모자식 관계로 신규 프로세스를 만든다.

# Linux 권한

  • 시분할 시스템이여서 다중 사용자 접속이 가능하다.
  • 이를 사용자/그룹으로 나누어서 권한을 나눠줄 수 있다.
  • root라는 기본 아이디가 있어서 이게 슈퍼관리자다.
    • 해커들의 최대 목표는 root관리자를 획득하는 것
  • 파일마다 사용자/그룹에 대해
    • read, write, execute의 권한을 관리한다.
    • 접근 권한 정보는 inode의 자료구조에 저장된다.

# 2. Ubuntu

aws에서 진행

# 3. Shell

# Shell 사용법

  • shell : 사용자와 운영체제간 인터페이스
    • 사용자의 명령 해석 - 시스템콜 호출 - 커널에 명령
    • cli 혹은 gui 가 존재

image-20210509164746673

  • 이 중 bash를 배우겠습니다.

# 다중 사용자 지원 명령어

  • UNIX는 시분할 시스템을 통해 다중 사용자를 지원한다.
  • whoami : 아이디 알기
  • passwd : id의 패스워드를 바꾼다. aws로 만든 ec2 ubuntu에서는 pw설정이 되어있지 않아서 잘 모르겠다.
  • useradd : 기본 설정을 자동으로 하지 않는다.
  • adduser : 기본 설정을 자동으로 한다. 이걸 기본으로 쓴다.
    • id를 만들면 해당 아이디 디렉토리가 /home/ 밑에 만들어진다. useradd하면 이게 안 만들어지고 기타 설정들도 안 만들어진다. adduser를 해보자. root가 아니면 안된다.
  • sudo : root권한으로 실행한다. root 계정으로 로그인 하지 않은 상태에서 가능하다.
    • 특정 유저들만 sudo를 사용할 수 있게 설정한다. ubuntu 유저는 사용 가능하다.
    • /etc/sudoers 파일에서 설정 변경 가능
    • 여기에 image-20210509174015222
    • 추가해주면 이제 keith 도 sudo 가능
    • 왜 그냥 root를 안쓰냐? sudo쓰면서 주의하란 말임.
  • /home/user/.bashrc, /home/user/.profile : 사용자의 기본 설정이 있다.
  • su :
    • su root : 현재 사용자 환경설정 기반(.bashrc, .profile) root로 변경
    • su - root : 변경 사용자 환경설정 기반 root로 변경
  • shift v : 한줄 선택
    • y 복사
    • p 붙여넣기
  • man ls : 를 쳐서 옵션들을 볼 수 있다 (manual)
  • cat : vi를 쓰지 않고 터미널에서 바로 내용을 본다.
  • head, tail : cat과 비슷한데 첫 10줄, 끝 10줄만 본다.
  • more : 한 화면에 꽉 차게만 띄우고 space누를때마다 페이지, 엔터누를때마다 한줄씩 넘길 수 있다.
  • rm : remove. 조심해야된다. 그냥 삭제됨. 리눅스엔 휴지통이 없다.
  • rm -rf 디렉토리명 : recursive force 로 하위폴더 전부다 삭제

# ls와 파일권한

image-20210509174807799

image-20210509175036976

  • 1칸 / 3칸 / 3칸 / 3칸
  • 파일이면 - 디렉토리면 d
  • 소유자 / 그룹 / 공개
  • 읽기 / 쓰기 / 실행

# chmod (change mod)

image-20210509175617337

image-20210509175728298

image-20210509175759282

  • -R directory : directory 하위의 모든 파일들에게 설정. r은 recursive

# chown (change owner)

image-20210509180510646

  • 그룹이 빈경우는 사용자의 default 그룹 적용
  • 사용자가 빈경우 사용자의 default 그룹 적용

# Redirection and pipe

# Standard Stream

  • command로 실행되는 프로세스는 세가지 stream이 있다.
    • stdin : standard input stream
    • stdout : standard output stream
    • stderr : standard error stream
  • 모든 스트림은 plain text로 console에 출력된다.

# redirection

  • 표준 스트림의 흐름을 바꿀수 있다.
    • < ,> 를 사용함
    • 출력의 방향을 바꿀 수 있다.
    • 명령어 표준 출력을 화면이 아니라 파일에 쓰고 싶을때!
      • ls > files.txtls내용을 files.txt에 쓰고 싶다. 파일이 없으면 만들어 준다.
      • ls >> files.txt 현존하는 files.txt의 뒤에 내용을 추가해준다.

# pipe

프로세스간 통신에 씌였던 파이프. 근데 여기선 redir과 연결해서 생각하고 ipc와 연결해서 생각하지 않아도 된다.

  • 한 프로세스의 출력 스트림을 다른 프로세스의 입력 스트림으로 사용할 때

    image-20210510162309284

  • ls | grep files.txt : ls 명령 출력이 grep 명령 입력스트림으로 들어감

    • grep : 입력 키워드를 찾는 명령어

    • ls | grep issue : issue라는 단어가 있는 ls결과를 찾는다.

    • image-20210510163059795

    • grep -i sometext 식으로 많이 쓰인다.

      image-20210510163421907

# foreground and background process

폰 노이만 구조에 의해 실행 파일은 모두 메모리에 우선 올라간다. 코드 이미지 또는 바이너리를 실행파일이라고 하고 실행 중인 프로그램은 프로세스라고 한다.

  • 프로세스에는 다음과 같은 상태 정보가 있다.

    • 가상 메모리 및 물리 메모리 정보
    • 시스템 리소스 관련 정보
    • 스케쥴링 단위
  • 리눅스는 기본적으로 다양한 프로세스가 실행된다 . 유닉스의 철학이 여러 프로그램이 서로 유기적으로 각자의 일을 수행하면서 전체시스템이 동작하도록 하는 모델이기 때문.

# foreground process

  • 기본적으로 터미널에서 실행하는 모든 것. 프로세스 수행 종료까지 사용자가 다른 입력을 하지 못한다.

# background process

  • 사용자 입력관 상관없이 실행됨.
  • 실행하고 뒤에 &를 붙여주면 백그라운드로 실행되며 백그라운드 job 번호와 PID가 뜬다.
  • ps를 쳐서 백그라운드에 실행됨을 확인할 수 있다.

image-20210510194034435

# 프로세스 관리 및 제어

  • ctrl z : 프로세스를 중단한다.

  • jobs : bg프로세스들을 보여준다.

    • image-20210510194626367
  • bg : 최근에 중단되 bg프로세스를 실행한다.

  • ctrl c : 프로세스를 죽인다.

  • ps : 프로세스 상태 확인

  • kill -9 pid 하면 프로세스 죽이기 가능. -9는 force의 뜻

  • kill %jobnumber 해도된다.

    image-20210510195204132

  • 프로세스 중 웹서버가 있는데 이런건 24시간 돌아간다. 데몬 중 하나임.

# 리눅스 파일 시스템

모든 것은 파일이다. -unix

  • 마우스, 키보드, 마이크 이런것도 전부 파일과 같이 다루어짐
  • 모든 자원에 대해 추상화 인터페이스로 파일 인터페이스를 활용한다.
  • cd /dev : 에 가면 device들을 볼 수 있다.
    • tty : 터미널. 가상 파일 시스템 인터페이스를 통해 가상 터미널(가상 디바이스)에 연결돼있다.

# 슈퍼 블록(super block)

image-20210510214157519

  • 슈퍼 블록 : 파일시스템에 관한 정보가 있다. 전체 사이즈, 어떤 파일시스템 알고리즘인가?
  • 파일이름과 inode는 매핑되어 있다. 프로세스와 pid가 매핑되어 있듯이
  • image-20210510214415566

# 리눅스 파일 시스템 탐색

# inode

  • 리눅스 파일 탐색 (/home/ubuntu/link.txt)
    • 각 디렉토리 엔트리(dentry) 탐색
      • 엔트리는 해당 디렉토리 파일/디렉토리 정보가 있다.
    • '/' dentry 에서 'home'을 찾고, 'home' dentry에서 'ubuntu'를 찾고, 'ubuntu' dentry 에서 link.txt 파일이름에 매핑돼있는 inode를 찾는다.
    • Each dentry maps an inode number to a file name and a parent directory.

image-20210511085303705

  • home 아래에 내 계정
  • media, mnt : 디바이스, 추가 ssd
  • etc : 다양한 설정 파일들
  • dev : 마우스 / 키보드 / 터미널
  • bin, sbin : 쉘 명령어의 실행 파일들. 'PATH'설정 돼 ㅇㅆ음
  • boot : 부팅 관련
  • var/log : 로그파일들 생김. 서버 쓰면 자주 씀.

# 하드 링크

링크는 유닉스 시스템에만 있는 독특한 기능이다.

  • cp 명령어 : copy
    • cp link.txt link3.txt : link.txt를 복사해서 link3.txt를 만든다
  • rm 명령어 : remove
    • rm link3.txt
  • ln : 하드링크
    • 윈도우에 바로가기가 있다면 unix에서는 링크가 있다.
  • ln link.txt hard.txt 를 하게되면 hard.txt가 생긴다.
    • 카피와 같은가? ㄴㄴ 동일한 inode번호와 데이터를 가지고 있다.
    • image-20210511091431375
    • 카피는 inode가 다른 번호가 생긴다.
    • 원본 변경시 링크도 당연히 변경
    • 원본 삭제시 링크는 그대로 있다
      • image-20210511092049892
      • 링크도 원본만큼 유효한 포인터이기 때문

# 소프트 링크

  • ln -s link.txt softlink.txt : -s를 붙여서 소프트링크를 해준다.
  • 윈도우의 바로가기와 더 비슷하다
  • 소프트링크는 inode 값이 다르다!
  • 원본 삭제시 소프트링크는 같이 삭제된다.
  • 별도의 inode이며 여기에 저장된 address는 원본파일의 inode이다.
  • 하드링크는 원본파일과 동일한 inode

# 특수파일

  • 디바이스
    • 블록 디바이스 : HDD, CD/DVD처럼 블록/섹터 단위로 데이터 송신, IO 송수신 속도 높다.
    • 케릭터 디바이스 : 키보드, 마우스 같은 바이트 단위 데이터. 손수신 속도가 낮다.

# 4. System_Programming

# 시스템콜과 API

# 시스템콜

  • 시스템 콜 : 사용자 영역에서 커널 영역으로 들어가는 함수
    • 여러 라이브러리(api)로 이뤄져있다.
    • 리눅스/유닉스는 c언어로 만들어져 있다.
    • how does it work
      • cpu가 커널 모드로 바뀜
      • instruction code(CPU가 제공)로 인터럽트(0x80)를 일으킨다.
      • IDT에서 0x80에 해당하는 함수를 실행. 0x80은 system_call() 이다.
      • image-20210511110539710
      • 함수에서 eax와 ebx 참조
      • eax레지스터에 시스템콜 번호
      • ebx레지스터에 인자값
      • 시스템콜 실행
      • image-20210511110226649
      • 사용자모드로 변경
  • c 라이브러리
    • 커널도 c언어로 이뤄져있다.
  • c 컴파일러

#

# API

  • 응용 프로그램과 분리된 하위 호환 인터페이스

    image-20210511155556865

  • 라이브러리

    • 동적 라이브러리

      • 바이너리가 이미 만들어져 있어서 사용시 여기에 붙여서 쓴다.
      • 실행할때 호출하며 실행파일로 컴파일할때는 같이 컴파일 되지 않는다.
      • api는 응용프로그램과 분리되어 있다. 그래서 라이브러리가 따로 업데이트 가능하다. 에러가 날 수도 있겠지만.
    • 정적 라이브러리

    • 대표적 라이브러리

      • 유닉스 C 라이브러리 : libc

        • cc : c compiler
      • 리눅스 C 라이브러리 : GNU libc,

        • gcc : gnu c compiler

          • aws에는 기본설치가 안 되어 있으므로 설치해주자

            sudo apt-get install gcc
            
            1
          • gcc -o test.c test : 컴파일

# ABI와 표준

# ABI(Application Binary Interface)

image-20210511160321732

  • 함수 실행 방식, 레지스터 활용, 시스템 콜 실행, 라이브러리 링크 방식 등

  • ABI가 호환되면 재컴파일없이 동작

  • 툴체인(컴파일러를 만드는 프로그램)에서 사용된다.

  • 함수의 인자들을 어떤 레지스터에 넣을 것인가? 같은 것을 정해준다.

    image-20210511160537397

# POSIX

  • API와 ABI를 표준화하려는 시도가 있었다. (IEEE)
  • 리차드 스톨만(자유 소프트웨어 재단)이 POSIX를 표준안으로 제안

# 시스템 프로그래밍과 버전

  • 소프트웨어는 계속 업데이트 되지만
  • 시스템 레벨단 기술은 70년대부터 꾸준하게 유지가 되고 있다.
  • 하위 시스템 레벨을 알고 있는게 중요하다.

# 5. Process Management

# PID

# Basic

  • 프로그램 : 바이너리, 코드 이미지, 응용 프로그램, application, 또는 실행 파일
  • 프로세스 : 현재 실행중인 프로그램(메모리 적재 + 프로세스 상태PCB)
  • 스레드
    • 리눅스는 무조건 기본 스레드가 포함된다
    • 싱글스레드 : 리눅스는 기본적으로 싱글스레드
    • 멀티스레드 : 강제로 여러개 띄운경우

# PID

  • 유니크한 pid
  • 부호형 16비트 정수값 -> 최대값은 2^15 = 32768
  • pid 값 한계 때문에 문제가 발생할 수 있다.
    • sudo vi /proc/sys/kernel/pid_max

# Process Layer

  • init process's PID = 1

  • init 프로세스는 운영체제가 만든다.

  • ppid를 통해 부모 프로세스의 pid를 알 수 있다.

    • ps -ef를 통해 알 수 있다.
    • e : 시스템 상 모든 프로세스 출력
    • f : UID, PID, PPID< CPU, STIME, TTY, TIME, CMD를 출력

# 프로세스와 owner

  • sudo vi /etc/passwd : pw뿐만 아니라 uid와 gid도 있다.

    image-20210511173615864

    • 사용자 : 비밀번호(가려짐):uid:gid
  • sudo vi /etc/shadow

# PID & System Call

  • getpid() : pid를 가져온다.
  • getppid() : ppid를 가져온다.
  • 둘다 시스템콜을 사용한다.

# Process 생성

  • 컴파일시 TEXT, DATA, BSS는 만들어지고 실행시 HEAP, STACK이 만들어진다.
  • 프로세스 생성 시
    • 전체 메모리 만들어진다
    • TEXT, DATA, BSS 부분(이미지)이 업로드 된다
    • 실행하면서 HEAP, STACK이 바뀌어 간다.
  • 프로세스 계층
    • 부모와 자식 프로세스가 있다.

# Fork

  • 동일한 코드, 데이터를 가진 프로세스를 만든다

  • 부모 프로세스는 그대로 살아 있다.

  • 자식 생성 시 Program Counter는 같은 위치

  • 리턴 값이 PID이다.

    • PID가 0이면 child
    • 아니면 부모여서 실행을 다르게 할 수 있다.

    image-20210511182252832

image-20210511184358959

# Exec

  • 별도의 새로운 프로세스를 만드는 것이 아니라 현재 공간에 덮어 씌운다.
  • 부모 프로세스는 사라진다.
  • 새로운 실행 파일!

image-20210509182607408

  • BSS, DATA, TEXT 전부 덮어씌워진다.
  • image-20210509182639121
  • execl(루트부터의디렉토리, argv[0], argv[1]... , NULL)

image-20210511183108589

  • execlp : path가 들어가있어서 풀 디렉토리를 안 쳐도 된다.

image-20210511183152951

  • execle : 환경변수를 사용자가 직접 세팅해서 쓴다. execlp는 기존설정된 path를 사용.

image-20210511183308360

  • v 가 붙으면 인자를 variable로 넣는다.

# wait

  • fork() 함수 호출시 자식프로세스가 종료할때까지 부모 프로세스가 기다림.
  • 부모 프로세스가 먼저 죽으며 좀비, 고아 프로세스가 생길 수 있다.
  • shell프로그램들은 전형적으로 이러하다.
  • fork()로 새로운 프로세스 복사후 execl()쓰는 것이 일반적이다.
  • shell자체가 기본적으로 fork를 따고 그 안에서 execl을 돌리는 형태다. wait()가 걸려있어서 꺼지지 않는다.

# copy on wirte

  • 리눅스는 프로세스당 4gb의 가상메모리가 할당된다

    image-20210509201148106

  • 3~4gb : 커널 스페이스에 운영체제가 들어간다.

    • 프로세스당 들어갈 필요가 없기 때문에 물리메모리는 동일 영역을 사용한다.

      image-20210509201320467

  • 0~3gb : 유저

  • fork()는 새로운 프로레스 공간 생성 후 기본 프로세스 공간 복사

    • 4gb를 복사하면 프로세스 생성시간이 오래 걸린다.

    • 자식 프로세스 생성시, 부모 프로세스의 페이지를 그대로 사용한다.

    • 읽기가 아닌 쓰기를 할때 이때 페이지를 복사하고 분리한다.

    • 이렇게 프로세스 생성 시간을 줄일 수 있고 페이지 수도 최소화 할 수 있다.

      image-20210509201841606

# exit

  • exit() 시스템콜 : 프로세스 종류
  • 기본 구조 : 부모에서 fork치고 부모는 wait. 자식은 exec하고 부모로 돌아옴. 그 뒤에 뒷처리 함
  • 그렇기 때문에 프로세스 종료상태를 알려주는 exit이 필요하다.
  • 보통 비정상 종료를 할때 exit을 사용한다.
  • c언어 실행시
    • 사실 int main(){}함수도 start라는 함수 안에 있다. start는 라이브러로 compile될때 바이너리가 붙여져 있다.
    • start함수 내부에서 main이 진행되고 return 값이 나오면 main함수는 종료.
    • start함수의 남은 부분에서 뒷처리가 실행되고 마지막에 있는 exit이 실행되면서 종료된다
    • main함수 안에 exit을 쓰면 거기서 바로 start함수까지 끝나게 된다.
  • return vs exit
    • exit : 즉시 종료
    • return : main이라는 함수만 종료
  • exit(EXIT_SUCCESS) or exit(0)
  • exit(EXIT_FAILURE) or exit(1)
  • exit() 시스템콜 내부 동작
    • atexit() : 종료시 실행될 함수 등록가능
    • IO 스트림 버퍼 삭제(stdin, stdout, stderr)
    • 프로세스가 오픈한 파일 모두 종료
    • tmpfile()을 통해 생성한 임시 파일 삭제

# 6. IPC

image-20210509190933458

  • 기본적으로 process간에 정보를 주고 받을 수 없어서 나온게 IPC

  • File을 만들어서 공유하던가

  • 커널 공간을 공유함으로 주고 받을 수 있다.

  • 기법들

    • file
    • message queue
    • shared memory
    • pipe
    • signal
    • semaphore
    • socket
  • ipcs를 통해 kernel 공간 메모리 확인 가능

    image-20210509192747132

image-20210509192617961

# pipe

  • 부모 -> 자식. 단방향 통신

image-20210509191159802

  • pipe는 커널에 생성된다.

# message queue

  • 물리의 커널 영역에 message queue를 만들어서 주고 받는다.
  • 양방향 통신이 가능하다.

# shared memory

  • message queue는 fifo방식인데 이건 그냥 변수처럼 접근 가능하게 한다.
  • 공유메모리 key를 갖고 여러 프로세스가 접근 가능하다.
  • shmget : 공유메모리를 생성하는 system call
  • shmat : 메모리에 매핑
  • shmdt : 메모리 해제
  • shmctl : 공유 메모리 삭제

# 7. Signal

  • ipc기법처럼 쓰일 수 있지만 그것만으로 한정 할 순 없다.

  • 유닉스에서 30년간 이용

  • 커널 또는 프로세스에서 다른 프로세스에 어떤 이벤트가 발생되었는지를 알려주는 기법

  • ctrl c도 시그널의 한 예다.

  • ctrl z 프로세스를 백그라운드로 바꾼다. 이것도 시그널이다.

    image-20210509195647486

  • kill -l : 시그널을 다 볼 수 있다.

# 시그널과 프로세스

image-20210509200459210

  • 시그널을 순서대로 받아서 대기 시킨다.
  • blocked 64bit. 시그널이 64개여서 각각 막는지 안막는지 설정
  • sig : 어떤 동작을 처리할지 action에 정의돼있다.
  • 순서 :
    • 프로세스에 signal 발생 시 : signal 관련 자료구조에 signal이 들어가고
    • 프로세스는 각종 시스템콜과 인터럽트에 의해 커널모드로 수시로 바뀐다.
    • 사용자모드로 전환하는 시점에 마지막에 하는 일 중 하나가 시그널을 확인하고 실행해야되면 실행한다.

# 8. Shell Script

  • 쉘을 사용해서 프로그래밍

  • 서버작업 및 devops를 위해 필요하다

  • 쉘 명령어에 문법이 추가된 형태

  • example

    • situation

      서버가 다운됨.

      저장공간이 없음.

      로그 파일 업데이트가 안되어 프로그램 비정상종료

      로그파일 누적이 원인

      로그파일 자동 삭제 방법은?

    • 해결

      쉘스크립트 생성 및 주기적 실행(cron tab)

  • 기본문법

    • 파일로 작성 후 파일을 실행
    • 가장 첫 라인은 #!/bin/bash
    • 실행 권한이 필요하다.
    • name.sh 형식이다.
    • # 은 주석 라인
    • 변수
      • 변수명=데이터
      • image-20210512094504581

# 리스트 변수

image-20210512095117630

리스트 변수를 쓸때는 중괄호를 써줘야 한다.

중괄호를 안쓰면 daemons를 변수로 하고(리스트의첫번째만 인식) [1]을 스트링으로 인식한다. 결과 : httpd[1]

# 사전 정의된 지역 변수

image-20210512095523535

# 연산자

image-20210512095839696

  • 백틱 꼭 쓰고
  • expr로 연산한다
  • 숫자와 기호는 다 한칸씩 띄운다.
  • 괄호와 곱하기 앞에는 역슬래시를 써야한다.

# 조건문

image-20210512171513385

if [ 조건 ]
then
	명령문
fi
1
2
3
4

image-20210512170907867

image-20210512170933316

image-20210512171054044

image-20210512171450358

# ping

  • IP주소가 서버를 가르킨다.
  • 핑은 연결돼있는 컴퓨터가 살아있는지 확인한다.
  • 확인 요청을 보내면 살아있으면 응답이 온다.
  • ping -c 1 192.168.0.1 1> /dev/null
    • -c : 한번만 확인해라. 안하면 초당 몇회씩 확인함
    • 0 표준입력, 1 표준출력, 2표준에러
    • $? : 마지막 결과값
#!/bin/bash
ping -c 1 192.169.0.1 1> /dev/null
if [ $? == 0]
then
        echo '핑성공!'
else
        echo '핑실패!'
fi

1
2
3
4
5
6
7
8
9

# for

#!/bin/bash
for database in $(ls)
do
        echo $database
done

1
2
3
4
5
6

# while

image-20210512172518830

# 예제 - 백업하기

#!/bin/bash

if [ -z $1 ]||[ -z $2 ]; then
        echo usage: $0 sourcedir targetdir
else
        SRCDIR=$1
        DSTDIR=$2
        BACKUPFILE=backup.$(date +%y%m%d%H%M%S).tar.gz
        if [ -d #DSTDIR ]; then
                tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR
        else
                mkdir $DSTDIR
                tar -cvzf $DSTDIR/$BACKUPFILE $SRCDIR
        fi
fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  • 인자로 $1 과 $2 두개를 받는다. 제대로 안오면 사용법만 인쇄
  • date라는 함수로 시간 가져온다 : backup.현재시각.tar.gz
  • -d 로 디렉토리가 현재 있는지 없는지 판단한다
  • tar : 70년대부터 있던 압축명령. 원래는 묶기만 했는데 이제 압축도 한다.
    • x : 묶음 해제
    • c : 파일 묶음
    • v : 과정을 화면에 표시
    • z : gunzip 사용
    • f : 파일 이름 지정
    • 주요 옵션
      • tar -cvzf [압축된 파일 이름] [압축할 파일이나 폴더]
      • tar -xvzf [압축해제할 이름]

# 예제 - 로그파일 정리하기

  • 정책
    • 로그파일 2일 이상 -> 압축
    • 압축파일 3일 이상 -> 삭제
#!/bin/bash

LOGDIR=/var/log
GZIPDAY=1
DELDAY=2
cd $LOGDIR
echo "cd $LOGDIR"

sudo find . -type f -name '*.log.?' -mtime +$GZIPDAY -exec bash -c "gzip {}" \; 2>
sudo find . -type f -name '*.gz' -mtime +$DELDAY -exec bash -c "rm -f {}" \ 2>

1
2
3
4
5
6
7
8
9
10
11
  • find : 찾기.
  • . : 현재폴더
  • -type f : 디렉토리가 아닌 파일들만
  • * : 아무 str
  • ? : 한글자 (참고:정규표현식)
  • -mtime +$GZIPDAY : 2일 이상된 파일 검색
  • -exec bash -c "명령어1; 명령어2";: 파일들에 해당 명령어 실행

# 9. Thread

# Thread란?

  • 프로세스 내에서 실제로 작업을 수행하는 주체
  • 프로세스 안에는 한개 이상의 스레드가 작업을 수행
  • 스택과 PC register는 독립적으로 할당된다.
  • 커널의 도움 없이 상호 통신 가능. -> 동기화 문제를 해결해야한다.

image-20210512185718031

# Pthread란?

  • POSIX Thread
  • 저수준 API 100개 함수 제공
  • 핵심 라이브러리
  • 다른 스레드도 Pthread기반으로 구현

# Pthread 라이브러리

  • <phtread.h> 헤더파일

  • 함수는 pthread_로 시작

  • 그룹

    • 스레드 관리 : 생성, 종료, 조인, 디태치
    • 동기화 : 뮤텍스 등 동기화 관련 함수
  • glibc와 분리된 libpthread 라이브러리에 구현되어서 컴파일시 명시해줘야한다.

    gcc -pthread test.c -o test

# thread 생성

# thread 종료

보통 잘 안쓴다. 알아서 종료되기 때문.

# thread 조인

특정 thread가 끝날때까지 기다려주는 함수

# thread 디태치

스레드 종료시 즉시 관련 리스소 해제. 조인을 기다리지 않고 종료 즉시 해제.

  • 종료 후 상태값으로 후처리를 안하면 디태치, 사용하면 조인.
  • detach를 했다고 다음 코드들이 join처럼 기다리지 않고 그대로 실행된다.

image-20210513015121091

# mutex

phthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;
1

자원을 독점할수 있게 해준다.

# 10. System_Programming Advanced

# 메모리와 mmap

  • malloc : heap 영역에 동적 메모리를 생성한다.

  • free : heap영역의 메모리 해제 가능

  • mmap : 파일, 메모리, 프로세스가 있다고 생각하자. 프로세스에서 파일을 접근하는건 시간이 굉장히 많이 걸린다. mmap은 파일을 메모리에 매핑하여 미리 올려놓을수 있다. 이러면 시스템콜, 스케쥴러, 인터럽트, dma, 시스템버스 모두 필요 없어서 굉장히 빨라진다.

  • image-20210509203304038

  • 파일 액세스를 줄여서 성능을 높인다. 가상 메모리와 흡사한 메커니즘이다.

  • 장점

    • read, write의 반복적 파일 접근 방지
    • 파일 처리를 위핸 lseek(느림)를쓰지 않고 포인터 조작으로 탐색 가능
  • 단점

    • 페이지 사이즈 단위로 매핑된다(4kb)
      • 페이지 사이즈 단위가 정수배가 아니면 한 페이지 정도 낭비한다.
  • int msync(void *start, size_t length, int flags)

    • start : mmap() 을 통해 받은 메모리 맵의 주소
    • length : 동기화 할 길이
    • flags : 비동기, 동기 방식을 정한다. 동기시 블럭 상태로 대기 한다.
  • int munmap(void *addr)

# stat

inode 정보를 받아온다.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *path, struct stat *buf);
int fstat(int filedes, struct stat *buf);

1
2
3
4
5
6
7
  • stat : 스테이트
  • const : 패스정보
  • struct : 스테이트라는 구조체. inode자료구조를 가져온다.
  • int : file 디스크립터를 넣는다.

image-20210513023758209