파일의 연결과 연결해제
파일을 연결(link)에는 "심볼릭 링크" 와 "하드 링크" 의 2가지가 존재한다. 하드링크는 연결을 원하는 원본파일의 inode 를 가지고 파일을 직접 만들지만 (파일복사), linke 는 inode 를 가지고 파일을 만들지 않고, 단지 파일만을 참조한다.
심볼링 링크의 경우 서로 다른 파일시스템 사이를 연결할수 있지만(파일을 단지 참조하는 것이므로), 하드 링크의 경우 다른 파일시스템 사이를 연결할수는 없다.
그 이유는 하드링크가 inode 를 가지고 파일을 연결한다고 했는데, 다른 파일시스템 의 경우 inode 가 중복될수가 있기 때문(즉 유일한 파일 이라는걸 확인할수 없음)이다.
그러므로 서로다른 파일시스템(파티션) 사이에 파일 복사를 원한다면, 별도의 함수를 만들어서 써야 한다.
이러한 파일시스템을 넘나드는 파일의 연결을 신경써야 한다면, 파일을 직접 read 해서 write 하는 함수를 만들어서 사용해야 할것이다.
파일의 링크를 해제하기 위해서는 unlink(2) 를 사용하면 된다.
유닉스 쉘상에서도 이러한 파일 링크를 위한 "ln" 이라는 시스템 명령어가 존재하는데, "-s" 옵션을 사용하면 심볼릭 링크 "-d" 를 사용하면 하드링크를 시키게 된다.
하드링크와 심볼링 링크
우선 심볼릭 링크 쪽을 보면 파일시스템이 다른데도 별문제 없이 링크가 됨을 알수 있다.
그러나 서로다른 파일시스템(장치)간에 하드링크를 하려고 할경우 에러가 나는걸 볼수 있을것이다.
위에서 말했듯이 inode 를 가져가기 때문이다.
위의 예제에서 "-d" 옵션을 이용한 하드 링크에서 에러가 발생한 이유는 서로다른 장치에 있는 파일을 하드링크 시키려고 했기 때문이다.
아래는 간단한 예제이다.
예제: link.c
#include <unistd.h> #include <string.h> #include <stdio.h> int main(int argc, char **argv) { int opt; if ( argc != 4) { printf ("Usage: ./link [s|h] [원본파일] [복사파일]\n"); return -1; } if(access(argv[2], F_OK) != 0) { printf("원본파일이 없습니다\n"); return -1; } if(access(argv[3], F_OK) == 0) { printf("이미 파일이 존재합니다\n"); return -1; } while((opt = getopt(argc, argv, "sh")) != -1) { switch(opt) { case 's': printf("심볼릭링크\n"); symlink(argv[2], argv[3]); break; case 'h': printf("하드링크\n"); link(argv[2], argv[3]); break; } } }
예상과 달리 --; 썩 그럴듯하게 돌아갈 것이다.
명령행 옵션의 처리를 위해서 getopt 를 사용했는데 getopt 에 대한내용은 getopt를 이용한 프로그램 인자처리를 참조하기 바란다.
"-s" 옵션을 주면 symlink(2)를 이용해서 심볼링 링크를 만들고,
"-h" 옵션을 주면 link(2)를 이용해서 하드링크를 만든다.
"-d" 옵션을 주면 해당 파일의 연결을 해제한다.
파일권한및 소유주/그룹 변경 파일의 실행권한은 "유저", "그룹", "그밖의 유저(other)" 에 대한 권한을 각기 지정해 줄수 있다.
[root@localhost test]# ls -al
-rwxr-xr-x 1 root root 13953 1월 24 2002 access
-rw-r--r-- 1 root yundream 180 1월 24 2002 access.c
-rw-r--r-- 1 root root 708 1월 24 2002 access.c.html
-rwxr-xr-x 1 root root 25250 7월 31 21:57 accumulate
-rw-r--r-- 1 root root 346 7월 31 21:57 accumulate.cc
-rwxr-xr-x 1 root root 13976 8월 17 16:40 add
-rw-r--r-- 1 root root 101 8월 17 16:40 add.c
-rwxr-xr-x 1 root root 25333 7월 31 22:37 adjacent_difference
-rw-r--r-- 1 root root 389 7월 31 22:37 adjacent_difference.cc
-rwxr-xr-x 1 root root 14104 8월 18 14:29 alarm
-rw-r--r-- 1 root root 230 8월 18 14:29 alarm.c
-rwxr-xr-x 1 root root 13791 1월 14 2002 argc
-rw-r--r-- 1 root root 214 1월 14 2002 argc.c
-rw-r--r-- 1 root root 777 1월 14 2002 argc.c.html
-rwxr-xr-x 1 root root 15191 12월 19 2001 array
-rw-r--r-- 1 root root 742 12월 19 2001 array.c
-rwxr-xr-x 1 root root 13678 9월 20 00:43 asc
-rw-r--r-- 1 root root 38 9월 20 00:42 asc.c
위는 "ls -al" 의 결과 이다. ls -al 을 사용할경우 각 파일권한, 파일의 소유자, 소유그룹등에 대한 상세한 정보를 볼수가 있다.
ls -al 의 결과 가장 앞의 10자리가 파일의 권한을 나타낸다. 이 10자리중 가장 앞자리는 파일의 타입(일반파일, 디렉토리, FIFO, 소켓)을 명시하고, 나머지 9자리가 파일의 권한을 나타내는데, 3자리씩 끊어서 각각 "소유자", "그룹", "Other" 에 대한 권한을 명시한다.
"w"는 쓰기권한, "r"은 읽기권한, "x"는 쓰기권한, "-" 는 권한없음을 나타낸다.
그러므로 위의 access 파일은 소유자인 "root"유저에게 대하여 "rwx"(읽기, 쓰기, 실행) 권한이 부여되어 있고, "root"그룹에 포함된 유저와 그밖의 유저에 대해"r-x"(읽기, 실행) 권한이 부여된다.
access.c 파일을 보면 "root" 사용자에게 "rw-"(일기, 쓰기), yundream 그룹에 포함된 유저와, 그밖의 유저에게 대하여서는 단지 "r--"(읽기) 권한만 부여되어 있음을 알수 있다.
소유자 그룹 Other
+-+-+-+ +-+-+-+ +-+-+-+
|R|W|X| |R|W|X| |R|W|X|
+-+-+-+ +-+-+-+ +-+-+-+
4 2 1 4 2 1 4 2 1
우리는 쉘상에서 파일권한변경을 위해 아래와 같은 명령을 사용한다.
[root@localhost test]# chmod 755 test.sh
소유주와 그룹의 변경을 위해서는 아래와 같은 명령을 사용한다.
[root@localhost test]# chown yundream.cvs test.sh
Linux 상에서는 chown 을 이용하여 파일에 대한 소유주와 그룹을 동시에 변경할수 있지만 다른 Unix 에서는 그룹변경을 위해서 "chgrp"를 사용해야만 할것이다.
C 에서는 파일권한 변경을 위해서 chmod(2), 소유주/그룹 변경을 위해서 chown(2) 함수를 제공한다.
예제 : mychown
#include <sys/types.h> #include <pwd.h> #include <unistd.h> int main(int argc, char **argv) { struct passwd *my_pass; my_pass = getpwnam(argv[1]); if (my_pass == NULL) { printf("%s 유저가 없음\n", argv[1]); exit(0); } printf("%s : %d\n", argv[1], my_pass->pw_uid, my_pass->pw_gid); if (chown(argv[2], my_pass->pw_uid, my_pass->pw_gid) !=0) { perror("error : "); } }
프로그램이 하는 일은 간단하다.
첫번째 아규먼트는 그룹권한을 변경할 유저의 ID 이고, 두번째 아규먼트는 권한을 변경할 파일 이름이다.
프로그램을 실행하면 해당파일의 소유주와 소유그룹이 변경되고, 파일권한이 664 로 변경될것이다.