관리 메뉴

너와 나의 스토리

[Unix] 디렉터리 조작 실습 본문

Unix/실습

[Unix] 디렉터리 조작 실습

노는게제일좋아! 2019. 10. 12. 11:17
반응형

sys/stat.h

  • 파일의 상태에 대한 정보를 얻거나 설정
  • 해당 파일에 저장된 디바이스 번호, inode 번호, mode 등

 

실습: <sys/stat.h> 헤더를 사용해서 파일 state를 출력해보자
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc,char* argv[])
{
	struct stat buf;
    if(argc>1)
    {
    	printf("Arguments is not allowed! \n");
        return 1;
    }
    printf("argv[0]: %s \n", argv[0]);
    stat(argv[0],&buf);
    
    printf("Mode: %lo \n", (unsigned long)buf.st_mode); // 파일의 타입과 permission
    printf("UID: %d \n", (int)buf.st_uid); // 파일의 user ID
    printf("Size: %d \n", (int)buf.st_size); // 파일 사이즈
    printf("Modification time: %d \n", (int)buf.st_mtime); // 가장 최근 수정 시간
    return 0;
}

Mode: 100755에서 

앞의 3자리는 파일 타입을 나타내고, 뒤에 3자리는 permission을 나타낸다.

 

 

하드 링크와 심볼릭 링크

Hardlink는 원본 데이터를 가리키는 포인터가 여러개 생긴다고 생각하면 됨.

Softlink는 원본 파일을 직접 가리키는 포인터가 추가적으로 생기는 것

 

 

 

 

 

  • 위 사진에서 hardlink를 unlink해도 원본 파일이 남아 있으므로 원본 데이터는 그대로이다.
  • 하지만 Softlink를 unlink하면 원본 파일이 사라지게 된다.
  • hardlink를 unlink하고, 원본 파일도 unlink하면 사실상 파일을 삭제한 것과 같다.

 

실습: Hardlink 만들고 지우기
  • int link(const char* old, const char *new)
    • old 파일을 new 파일에 hard link
    • 결과: old와 new는 같은 파일을 가리킴
  • int unlink(const char *path)
    • path로 지정된 hard link를 제거
  • 리턴 값이 0이면 성공, 아니면 실패
#include <unistd.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	if(argc!=3)
    {
    	perror("Usage: ./mv <old> <new> \n");
        return -1;
    }
    if(ling(argv[1],argv[2])) // hardlink
    {
    	printf("Link failed. : %s -> %s \n", argv[1],argv[2]);
        return -2;
    }
    printf("File moved: %s -> %s \n", argv[1],argv[2]);
    return 0;
}

 

test.txt와 test3.txt는 같은 파일을 둘 다 가리키고 있으므로 2가되고 

test2.txt는 원본 파일 하나만 가리키므로 1

 

//unlink.c

#include <unistd.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	if(argc!=2)
    {
    	perror("Usage: ./mv <old> \n");
        return -1;
    }
    if(unlink(argv[1]))
    {
    	printf("Unlink failed. : %s \n", argv[1]));
        return -3;
    }
    return 0;
}

 

 

 

실습: 디렉터리 만들기
  • <sys/types.h>, <sys/stat.h>
  • int mkdir(const char* pathname, mode_t mode)
    • pathname: 생성할 디렉터리 경로
    • mode: 생성할 디렉터리의 permission
    • 리턴 값이 0이면 성공, 아니면 실패
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc,char* argv[])
{
	int i;
    for(i=1;i<argc;++i)
    	mkdir(argv[i],0777); // 인자로 들어온 것 전부 디렉터리로 만든다
        
    return 0;
}

* 권한 0777 넣을 때, 0을 붙이는 이유 -> 8진수임을 나타냄

 

 

만들었더나 권한이 0777로 안들어가고 0755가 됨

이유는? default umask 때문이다.

[0777&~default umask]한 결과가 0755인 것!

umask는 지정 가능하다 -> umask(0000) // 이렇게 설정하면 0777할 수 있음

 

 

실습: 디렉터리 지우기
  • <unistd.h>
  • int rmdir(const char *pathname)
    • 삭제할 디렉터리는 반드시 비어 있어야 한다.
    • 리턴 값이 0이면 성공, 아니면 실패
// rm.c
#include <stdo.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
	int i,res;
    dup2(1,2);
    
    for(i=1;i<argc;i++)
    {
    	res=rmdir(argv[i]);
        if(res) // 정상적으로 못 지우면 res가 0이 아님
        	printf("rmdir for %s failed. \n", argv[i]);
    }
    return 0;
}

 

 

실습: 디렉터리 위치 변경
  • <unistd.h>
  • int chdir(const char* pathname)
    • 디렉터리 위치는 현재 프로세스에 한정
  • int fchdir(int fd)
  • char* getcwd(char *name, size_t size)
    • size: name의 크기(충분히 커야함)
#include <unistd.h>
#include <stdio.h>

int main(int argc,char* argv[])
{
	char name[256];
    int i,res;
    
    printf("Current Dir.: %s \n", getcwd(name, 256));  // 현재 디렉터리 출력
    for(i=1;i<argc;++i)
    {
    	res = chdir(argv[i]); // 디렉터리 이동!
        if(res)
        	printf("Chdir for %s failed. \n", argv[i]);
        else
        	printf("Current Dir.: %s \n", getcwd(name,256));
    }
    return 0;
}
    

 

 

실습: 디렉터리 열기
  • <dirent.h>
  • DIR *opendir(const char *pathname)
    • 리턴 값이 NULL이면 실패, 아니면 성공
  • int closedir(DIR* dirp)
    • 열려있던 디렉터리를 닫음

 

실습: 디렉터리 읽기
  • <dirent.h>
  • struct dirent* readdir (DIR*dirp)
    • dirp: 열려 있는 디렉터리 포인터
    • 리턴 값은 디렉터리 엔트리이고, 실패시 NULL이 반환된다.
    • 디렉터리의 엔트리를 하나 읽어옴
    • 읽은 뒤에는 다음 엔트리로 넘김
  • void rewinddir(DIR* dirp)
    • dirp의 포인터를 처음으로 되돌림 (offset 되돌림)
#include <dirent.h>
#include <stdio.h>

int main(int argc,char *argv[])
{
	int res,depth=0;
    DIR* dirp;
    struct dirent* entry;
    
    if(argc!=2)
    {
    	perror("Usage: list <path> \n");
        return -1;
    }
    dirp=opendir(argv[1]);
    if(dirp==NULL)
    	perror("Directory cannot be opened. \n");
    while((entry=readdir(dirp))!=NULL)
    	printf("%10ld: %s \n", entry->d_ino, entry->d_name);
    closedir(dirp);
    return 0;
}
        

결과: 현재 디렉터리에 대한 inode 번호와 파일명이 모두 표시

 

 

 

 

 

 

출처:

반응형
Comments