4-1 파일 기본 (학습)

do·2022년 3월 28일
0

API

목록 보기
15/42

리눅스 파일과 파일 시스템

(1) 파일

  • 파일 - 관련 있는 정보들의 집합
  • 파일 시스템 - 파일들이 디스크 상에서 구성되는 방식
    • 파일에 이름을 붙이고 저장, 탐색을 위해 파일을 어디에 위치시킬 것인지 나타내는 체계

(2) 파일 종류

Regular file

  • 데이터를 가지고 있으면서 디스크에 저장됩니다.
  • 텍스트 파일은 사용자가 쉽게 읽을 수 있는 문자로 구성 되어있습니다.
  • 실행 파일이나, 이미지 파일은 바이너리로 저장되어서 사용자가 읽을 수 없는 형태로 구성 되어있습니다.

Directory

  • 디렉토리 자체도 하나의 파일로, 한 디렉토리는 다른 디렉토리들을 포함함으로써 계층 구조를 이룹니다.
  • 다른 파일들의 목록을 가지고 있거나, 그 파일들의 정보(주소)를 가지는 포인터들을 가집니다.
    • 읽기, 쓰기, 변경 등을 이용하기 위해 권한이 필요합니다.
    • 디렉토리 파일에 직접적으로 쓰는건 커널에서만 가능합니다.
  • 원본 파일의 inode에 대한 직접적인 포인터
  • 하나의 하드 링크 파일을 생성하면 원본 파일과 하드 링크 파일은 동일한 정보를 가지게 되어 어느 하나의 파일이 변경되어도, 두 파일 모두 동일한 내용과 크기로 변형됩니다.
  • 이미 존재하는 데이터의 위치만 가리키고 있으며 별도의 데이터를 저장하지 않기 때문에 용량을 차지하지 않습니다.
  • 원본 파일의 inode를 가리키는 정보가 있는 파일
  • 윈도우의 바로가기 기능과 유사합니다.
  • 자신이 가리키고 있는 파일의 위치를 데이터로서 저장하기 때문에 약간의 용량(4KB)을 차지합니다.
  • 과정.
  1. 사용자가 파일(또는 파일과 관련된 정보)에 액세스하면, 파일 이름을 사용하지만 내부적으로 파일 이름은 먼저 디렉토리 테이블에 저장된 i-node 번호로 매핑됩니다.
  2. 그런 다음 해당 inode 번호를 통해 해당 i-node에 액세스됩니다.
  3. 원본 파일에 대한 정보가 포함되어 있지 않으며, 원본 파일 위치에 대한 포인터만 포함되므로 새로운 i-node를 가진 링크파일이 생성됩니다.

심볼릭 링크와 하드 링크의 차이점

구분심볼릭 링크하드 링크
생성 명령어ln -s [원본명] [링크명]ln [원본명] [링크명]
생성 종류파일과 디렉토리 모두 생성파일만 생성
링크 기능파일 또는 디렉토리 이름에 대한 링크를 가리킴원본 파일에 대한 참조 또는 포인터
원본 파일을 이동시키거나 삭제할 경우액세스 불가능액세스 가능
inode 번호다름동일함
다른 파티션 링크 여부가능불가능
특징데이터 접근시 원본 i-node를 경유함i-node로 바로 데이터에 접근함
디렉토리도 가능함디렉토리 지원하지 않음

Special file

  • 물리적인 장치에 대한 내부적인 표현
    • 키보드(stdin), 모니터(stdout), HDD, 마우스, 프린터 등의 장치들 또한 하나의 파일로 처리합니다.
    • 소프트웨어가 표준 입출력 시스템 호출을 사용하여 장치 드라이버와 상호 작용할 수 있게 해줍니다.
  • ls -al /dev/를 통해 /dev 하위의 디바이스 파일들을 볼 수 있습니다.
    • - 파일, d 디렉토리, c 캐릭터, b 블록, l 심볼릭
  • 캐릭터 디바이스 파일 -> 입력 매체
    • 터미널, 프린터, 키보드 등의 문자 기반 장치 파일
    • 시스템의 I/O 버퍼를 사용하지 않으며, 바이트 단위 입출력을 사용합니다.
    • 하드웨어에서 바이트 단위로 입출력만 수행하고 그 밖의 작업은 수행하지 않습니다.
      • 따라서 입출력 성능을 향상시키기 위해서는 응용 프로그램에서의 조작이 필요합니다.
    • I/O 송수신 속도 낮음
  • 블록 디바이스 파일 -> 저장매체
    • 하디드스크, CD/DVD 등의 저장 장치 파일
    • 수 바이트 크기의 블록 단위로 입출력을 수행합니다.
    • I/O 송수진 속도 높음

(2) 파일 소유자, 그룹

  • 기본적으로 root라는 슈퍼 계정이 생깁니다.
  • 모든 사용자는 하나 이상의 그룹에 소속되어야 하고, 사용자마자 읽기, 쓰기, 삭제 등 특정 목적에 따라 권한을 다르게 부여할 수 있습니다.
    /etc/passwd 사용자 정보가 저장된 경로
    /etc/group 그룹 정보가 저장된 경로
    chown [옵션] 유저[:그룹] 파일 소유자 및 그룹 변경
    chgrp 자신이 속한 그룹 변경
    ls -l 파일의 소유자 확인하는 명령어

(3) 파일 모드

User, Group, Others

  • 권한을 지정할 대상을 포함한 파일의 속성
  • 읽기(R) 쓰기(W) 실행(X)
  • 위 3가지 권한을 user group others에 대해 각각 지정할 수 있게 만들었습니다.
    chmod [옵션] [모드] [파일] 파일 및 디렉토리의 권한을 수정하는 명령어
    예시.
    chmod g+x 파일명 g(group)에 실행 권한을 줌
    chmod o-w 파일명 o(others) 쓰기 권한을 빼앗음
    chmod a=rw 파일명 a(all)에게 읽기, 쓰기 권한을 지정함
    chmod 777 모든 권한 추가
    chmod 743 user 모든 권한 허용, group 읽기 허용, others 실행, 쓰기 허용

Set-user-id bit

  • 8진수 4000
  • 실 사용자에서 프로그램 소유자의 ID로 유효사용자(EUID)가 변경됩니다.
  1. setuid 비트가 설정된 파일은 실행 순간만 그 파일의 소유자 권한으로 실행합니다.
    • 실행 순간만 권한을 빌려온다라고 이해하면 쉽습니다.
    • 대부분 슈퍼유저가 소유한 소수 프로그램들에만 주어집니다.
  2. root 권한이 필요없는 프로그램에 소유주가 root로 되어있고 setuid가 설정된 경우는 보안상으로 매우 취약합니다.
    • 일반 사용자로 접근하는 경우도 setuid 설정으로 실행 가능해지기 때문입니다.
  3. 설정 방법
    chmod 4xxx 파일 비트 설정
    chmod u+s 파일 비트 설정
    chmod u-s 파일 비트 해제

Set-group-id bit

  • 8진수 2000
  • 유효 그룹 ID(EGID)를 사용자의 실제 그룹 ID에서 파일 소유자의 그룹 ID로 변경합니다.
  • 이 디렉토리에 새로 설정된 파일들은 디렉토리 그룹 소유권보다 파일 생성자의 그룹 소유권을 얻습니다.
  1. 설정 방법
    chmod 2xxx 파일 비트 설정
    chmod g+s 파일 비트 설정
    chmod g-s 파일 비트 해제

Sticky bit

  • 8진수 1000
  • 특정 디렉토리를 누구나 자유롭게 사용할 수 있게 하기 위함 입니다.
    • 파일 또는 디렉토리 생성은 누구나 할 수 있습니다.
    • 단 디렉토리에 적용되면 디렉토리 소유자, 파일 소유자, 또는 슈퍼유저가 아닌 사용자들은 파일을 삭제하거나 이름을 변경하지 못하도록 막습니다.
  • sticky bit를 공유모드라고도 합니다.
  1. 설정 방법
    cdmod 1xxx 파일 비트 설정
    cdmod o+t 파일 비트 설정
    cdmod o-t 파일 비트 해제

(4) 파일 시스템

ext4(4th Extended File System)

  • 리눅스 전용 디스크 기반 파일 시스템
  • 저널링 기능: 데이터를 디스크에 기록하기 전에, 파일 시스템의 저널(로그)에 수정사항을 기록하는 방식
    • 파일의 정확성 체크가 빠르고 정확하게 이루어집니다.
    • 데이터 복구 기능을 강화합니다.
  • 볼륨 크기 1EB 이상 지원, 서브 디렉토리 수 64,000
  • 파일 시스템의 축소와 확장이 자유롭습니다.
  • 파일에 디스크 할당 시 물리적으로 연속적인 블록을 할당합니다.

xfs(eXtended File System)

  • 저널링 파일 시스템
  • Extent 기반이 탄탄해진 상태로, 고성능 대용량 파일 시스템에 가장 적합합니다.
  • EXT4가 가지고 있는 거의 모든 기능이 지원됩니다.
  • 증설은 가능하지만, 축소가 불가능합니다.
  • 최대 용량 8EB의 대용량 파일도 다룹니다.

btrfs(B-tree File System)

btrfsext4
파일 시스템 기능데이터 보호 기능(예:스냅샷, 복제 및 특정 시점 복구)btrfs보다 적은 하드웨어 요구사항
데이터 무결성 보호
각 공유 폴더의 사용자 할당량
볼륨의 주요 용도데이터 무결성과 보호가 필요한 중요한 기업 데이터 저장성능이 요구되는 다음 기능 또는 패키지 사용: Surveillance Station
일반적인 파일 공유에 권장 또는 서버 가상화

*Surveillance Station: IP 카메라 모니터링을 통해 보안을 유지하는 시스템

(5) 마운트

  • 운영체제가 물리적인 장치를 이용할 수 있도록 연결합니다.
  • 리눅스는 모든 장치를 파일 단위로 관리하기 때문에, 새로 추가된 장치는 임의의 디렉토리(mount point)에 연결시켜 사용해야합니다.
    • 마운트 포인트: 하드디스크를 운영체제로 연결할때 사용한 디렉토리
    • 마운트 포인트는 비어있는 디렉토리를 사용해야합니다.
      - 사용 중이던 디렉토리를 마운트 포인트로 이용할 경우, 존재하던 파일과 디렉토리에 접근할 수 없습니다.
      - 마운트 포인트 해제 시 기존의 파일 및 디렉토리에 접근 가능합니다.
      /etc/fstab 시스템 부팅시 마운트 정보를 읽어들이는 파일
      /etc/mtab 현재 시스템의 마운트 정보를 저장하고 있는 파일

(6) 파일 시스템 구조

리눅스 파일 시스템의 구조는 boot block으로 시작되며, boot block은 컴퓨터 시스템을 부팅하기 위한 부팅에 관련된 이미지를 갖고 있습니다.
1. 리눅스가 처음 실행되면, 부트블록을 제일 먼저 읽어 리눅스를 가동합니다.
2. 부트블록이 주 기억장치에 모두 올라가게 되면, 리눅스는 제일 처음 init 프로세스를 기동하게 되고, init 프로세스의 PID(Process Idenficiation Number)는 1번이 부여됩니다.

boot block

  • 파일 시스템으로부터 리눅스 커널을 적재시키기 위한 프로그램

super block

  • 파일 시스템의 크기, 블록 수 등 이용가능한 빈 블록 리스트와
    빈 블록 리스트에서 그 다음 빈 블록을 가리키는 인덱스 정보가 있습니다.

inode (index-node)

  • 파일이나 디렉토리에 대한 모든 정보를 가지고 있는 구조
  • 리눅스가 파일에 접근할 때 inode 값으로 접근합니다.
  • Inode가 가지고 있는 정보
    • 파일 모드(권한) / 링크 수 / User ID / Group ID / 파일 크기 / 파일 주소 / 마지막 접근 정보 / 마지막 수정 정보 / 아이노드 수정 정보
  • 한 파일이 사용하는 모든 블록을 가리키는 포인터들을 포함하는 하나의 블록
  • 파일을 삭제하면 inode 값이 -1이 되고, inode-list에서 해당 inode가 0으로 바뀝니다. 파일을 삭제하면 inode 값이 0으로 바뀌는 것으로, 그 자리는 새로 생성되는 파일이 차지할 수 있음을 의미합니다.

data block

  • 실제 데이터가 저장되어 있는 파일

(7) umask

  • 권한을 설정할 때 수동으로 권한을 주지 않고, 파일이나 디렉토리 생성됨과 동시에 권한이 주어지도록 하는데, 이를 umask 라고 합니다.
  • 파일의 허가권 값은 최대 666이고, 디렉토리의 경우 777입니다. 여기서 umask 값을 뺀 값이 해당 파일의 허가권이 됩니다.
  • 예시) umask 명령어를 입력하면 0022가 출력되는데, 그 파일의 허가권은 644가 됩니다. 파일의 기본 허가권은 666이기 때문에, 666-022=644의 권한을 가집니다.

(8) 함수

stat()

기능. 구조체를 통해 파일의 정보를 얻는 함수(크기, 권한, 생성일시, 최종 변경일 등)
헤더. #include <sys/stat.h>
원형. int stat(const char* filename, struct stat* buf)
매개변수1. const char* filename 첫번째 인자로 주어진 filename의 상태를 얻어와서 두번째 인자인 buf에 채워집니다. 경로를 명시하지 않을 때는 현재 디렉토리를 기준으로 파일을 찾습니다.
매개변수2. struct stat* buf 파일의 stat 구조체를 저장합니다.
리턴값. int 성공하면 0을, 에러 발생은 -1을 리턴

lstat()

기능. 심볼릭 링크 파일의 원본 파일의 상태를 얻어온다는 것을 제외하고는 stat()함수와 동일합니다.
헤더. #include <sys/stat.h>
원형. int lstat(const char* filename, struct stat* buf)
매개변수1. const char* filename
매개변수2. struct stat* buf
리턴값. int 성공하면 0을, 에러 발생은 -1을 리턴

struct stat{
dev_t		st_dev;		//장치 파일의 위치 및 여부 (inode의 디바이스)
ino_t		st_ino;		//파일의 inode 번호
mode_t		st_mode;	//파일의 모드를 다룸 (파일의 종류를 알 수 있고, 퍼미션도 알 수 있음)
nlink_t		st_nlink;	//파일의 하드링크 수
uid_t		st_uid;		//user ID
gid_t		st_gid;		//group ID
dev_t		st_rdev;	//장치 파일(inode)를 기술
off_t		st_size;	//파일의 byte 크기
blksize_t	st_blksize;	//입출력에 최적인 블록 사이즈
blkcnt_t	st_blocks;	//파일에 할당할 수 있었던 블럭의 수
time_t		st_atime;	//마지막 액세스 시각
time_t		st_mtime;	//마지막 데이터 수정 시각
time_t		st_ctime;	//마지막 file status 수정 시각
};

특히 3번째 필드인 st_mode를 이용해 파일 타입을 확인할 수 있습니다.
S_ISREG(st_mode) 단순 파일인지 확인합니다.
S_ISDIR(st_mode) 디렉토리인지 확인합니다.
S_ISCHR(st_mode) 문자 디바이스인지 확인합니다.
S_ISBLK(st_mode) 블록 디바이스인지 확인합니다.
S_ISFIFO(st_mode) 선입선출 구조의 파일인지 확인합니다.
S_ISLNK(st_mode) 심볼릭 링크 파일인지 확인합니다.
S_ISSOCK(st_mode) 네트워크 통신에 필요한 소켓파일인지 확인합니다.

/* testing.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char* argv[])
{
	struct stat buf;
	stat(argv[1], &buf);

	if(S_ISREG(buf.st_mode))
		puts("regular file");
	else if(S_ISDIR(buf.st_mode))
		puts("directory");
	else
		puts("other file");
	return 0;
}

/* 컴파일 후 */
testing ../4-1
directory

rename()

기능. 파일 또는 디렉토리의 이름을 변경합니다.
newpath가 이미 존재하는 경우, newpath를 삭제하고 oldpath를 newpath 이름으로 변경합니다.
다만, 같은 mount된 파일 시스템에서만 동작합니다.
파일 to 파일, 디렉토리 to 디렉토리만 정삭적으로 수행됩니다.
헤더. #include <stdio.h>
원형. int rename(const char* oldpath, const char* newpath)
매개변수1. const char* oldpath 이름을 변경하려는 원본 파일 또는 디렉토리명
매개변수2. const char* newpath 변경될 새로운 이름
리턴값. 정상적으로 파일명 변경시 0, 오류 발생 시 -1.
상세 오류 내용은 errno 전역변수에 설정됩니다.
특징. rename()은 이름이 변경되어도 inode가 변경되지 읺기 때문에, oldpath에 대해 어떤 프로세스가 파일을 open하여 읽고 쓰기를 해도 newpath에 대해서 읽고 쓰기가 이루어집니다.

/* testing.c */
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(int argc, char* argv[])
{
    if (argc != 3) {
        printf("%s {src} {dest} \n", argv[0]);
        return 0;
    }

    if (rename(argv[1], argv[2]) == -1) {
        fprintf(stderr, "rename error: %s\n", strerror(errno));
        return 1;
    }
    return 0;
}

/* 컴파일 후 */
testing file1 file2
--file2로 이름 변경되었음--

umask()

기능. 파일 생성시 기본 권한을 제한하는 마스크일시적으로 변경합니다.
변경된 마스크 값은 프로세스가 종료되면 원래대로 돌아갑니다.
운영체제마다 기본적으로 설정된 umask 값이 있습니다. 제 pc의 umask 값은 0022로 (맨 앞의 0은 8진수를 의미함) 파일 생성시 0777 - 0022 = 0755.
0755의 권한을 가진 파일이 만들어집니다. 755 -> rwx,r-x,r-x
헤더. #include <sys/types.h> #include <sys/stat.h>
원형. mode_t umask(mode_t mode)
매개변수1. mode_t mode 원하는 umask 값
리턴값. mode_t 변경되기 전의 umask 값

chmod()

기능. 파일의 접근 권한을 변경
헤더. #include <sys/types.h> #include <sys/stat.h>
원형. int chmod(const char* filepath, mode_t mode)
매개변수1. const char* filepath 대상 파일의 경로
매개변수2. mode_t mode 파일의 권한
리턴값. 성공 시 1, 에러 발생 시 -1을 리턴하고 errno 설정

0개의 댓글