mount : 리눅스 터미널 파일시스템을 보는 방법
- dev/sda1 on : 디스크가 실제로 mount되어 붙어있음
- proc, sysfs on에 어플리케이션과 소통할 수 있는 통로(가상파일들) 시스템 정보를 얻어냄
cd /proc/ -> ls
- 커널에서 사용자들에게 정보를 줌
- 번호들이 쓰여있는 디렉토리들이 존재 : 프로세스의 정보들이 표시되어 있음
- 이 정보들을 보고 운영체제, 프로세스의 상태를 볼 수 있음
top
- cpu정보, 점유율
cat meminfo
- 메모리의 정보들이 존재
cat cmdline
- 커널 실행 옵션
cd /sys/ -> ls
- 커널의 특정기능을 키거나 끌 때 sys에서 write하면 됨
- 이렇게 리눅스나 유닉스에서는 모든 시스템 정보들이 파일을 통해서 이루어짐
프로그램을 만들기 앞서 사용될 시스템 콜들을 알아보겠습니다.
- perror : print 에러 메시지 -> 에러 메시지들을 출력해주는 시스템 콜
- exit(0) : 실행중이던 파일 종료
단순히 파일을 open하는 함수
argment를 받는 실행파일이기 때문에 main함수 안에 인자들을 넣음 argment들이 2개가 아니라면 (-> ./실행파일 open할 파일이름) 잘못됨을 알리고 프로그램 종료 잘 입력 되었다면 fd에 read모드로 파일을 open하고 fd가 -1(에러)이라면 에러메시지 출력 후 프로그램 종료 에러가 아니라면 파일이 열린것을 알림 유닉스의 cp명령어와 유사한 mycp프로그램을 작성 mycp는 첫 번째 인자로 지정된 파일을 두 번째 인자로 복사하는 함수 ex) ./mycp source-file dest-file 따라서 source-file은 read only, dest-file은 read and write로 만들 것 read의 경우 몇 바이트씩 읽을지 정해야 함 -> buf의 크기는 size_t count 정해진 만큼 읽다가 마지막 부분은 덜 읽어올 수 있음 write : 버퍼에 있는 내용을 카운트 만큼 씀 dest-file의 모드는 rw-rw-rw-로 세팅, 즉 (S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP,S_IROTH,S_IWOTH) -> 0666으로 표현 가능 버퍼사이즈를 1024로 define함 fd_in과 fd_out을 선언 argument가 3개일 경우만 실행 fd_in은 첫 번째 파일, 즉 복사할 파일을 read only로 open fd_out은 두 번째 파일, 붙여넣을 파일을 read and write only로 open하고 파일이 존재하지 않을 경우 creat함/ 0666은 유저, 그룹, 다른사용자 까지 모두 읽고 쓸 수 있음을 의미 fd_in 또는 fd_out이 오류가 나서 -1이 리턴됐다면 에러메시지를 출력하고 프로그램을 종료 제대로 return됐다면 buffer를 정해놓은 사이즈만큼 선언하고 nb에 read가 안될때 까지 while문을 실행 write로 fd_out에 읽어온만큼 작성 끝나면 fd_in과 fd_out을 close 후 프로그램 종료 write(2) 함수를 이용해 1byte씩 num-bytes만큼 반복하여 파일 끝에 붙여쓰기 디폴트로는 open(2)시에 O_APPEND 플레그를 사용하여 파일 끝에 첨부 함 3번째 인자로 x가 주어지는 경우, O_APPEND플레그를 사용하지 않고 각 byte를 첨부하기 위해서 lseek한 후에 write()를 사용 먼저 argument가 3개면 x를 쓰지 않았을 경우이므로 O_APPEND를 사용한다는 메시지를 출력 atoi함수는 문자열로 입력한 숫자를 정수형 숫자로 바꿔주는 역할을 함 num_byte에 몇 번이나 반복할지를 입력하는 것 fd에 open을 사용하여 파일을 열거나 만듦 -> write only고 O_APPEND사용 fd가 -1이면 에러메시지를 출력 후 프로그램 종료 for문을 사용하여 num_bytes만큼 write를 반복 -> 'o'를 넣음 argument가 4개이고 마지막 argument가 x라면 O_APPEND를 쓰지않고 위 과정을 실행 우선 O_APPEND를 사용하지 않고 lseek를 사용한다는 메시지를 출력한 뒤 위와 똑같이 atoi를 쓰고 fd에 open하는데 O_APPEND는 제외 에러 메시지도 똑같음 for문에서 그냥 write를 썼던 위 과정과는 달리 이번에는 lseek로 다음에 쓸 위치를 찾는 과정을 넣어야 함 lseek(fd,0,SEEK_END)는 SEEK_END 즉, 가장 마지막에서 +1을 한 자리에 offset을 정한다는 의미 모두 완료 되었으면 fd를 close함 결과를 보면 O_APPEND를 사용했을 경우에는 크기가 설정한대로 잘 작성 되었지만 사용하지 않은 경우 누락된 'o'가 있음을 알 수 있음 완전히 atomic한 시스템은 race condition이 일어나지 않음을 알 수 있음
cs
cs
cs
tee 명령어와 유사한 mytee 프로그램을 작성하자
- man 명령어를 통해 tee명령어의 사용법 확인 -> man 2 tee
- cat input_file | tee output_file 이런 식으로 사용하면
input_file의 내용이 출력됨과 동시에 output_file에 저장되는 명령어이다.
input으로 파일을 쓰지 않고 ls –l | tee output_file 이런 식으로 또 다른 명령어의 결과값을 input으로 줄 수도 있다.
-
내가 만든 mytee 소스 코드와 실행 결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define SZ_BUF 1024
int main(int argc,char *argv[]){
int fd;
if(argc != 2){
printf("mytee filename\n");
}
fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);
if(fd == -1){
perror("open");
exit(0);
}
else{
char *buffer[SZ_BUF];
int nb;
while(nb = read(0, buffer, SZ_BUF)){
write(fd, buffer ,nb);
write(1,buffer,nb);
}
printf("success\n");
close(fd);
exit(0);
}
} |
cs |
-
구현에 대한 간단한 설명
-
파이프라인으로 연결하여 넘겨준 인자는 argument에 속하는 것이 아닌 standard input으로 들어가기에 0이라는 숫자로 표현
-
따라서 mytee에 들어갈 argument는 명령어와 file이름 두 가지
-
argument의 수가 2개가 아니라면 오류메시지를 출력 후 프로그램 종료
-
2개를 만족한다면 입력한 file이름을 open으로 열고 만약 파일이 존재하지 않는다면 생성, 그리고 open할 때마다 사이즈를 0으로 초기화 시켜줌/ 사용자, 그룹, 다른 사용자까지 읽고 쓸 수 있도록 설정
-
리턴값이 -1로 에러가 발생한다면 오류 메시지 출력 후 프로그램을 종료
-
버퍼 사이즈(1024로 정의)만큼의 buffer를 선언
-
while문으로 파일이 모두 write되어 read값이 0이 될 때 까지 반복
-
읽은 값들을 fd(저장할 파일)에 write하면서 standard output에도 write
-
모두 완료되면 성공메시지를 띄우고 파일을 닫은 후 프로그램을 종료
'LINUX 실습' 카테고리의 다른 글
[함수 만들기]프로세스 시스템 콜 (0) | 2018.11.26 |
---|---|
[시스템 콜 파일(2)]myls, mycp2 함수 만들기 (0) | 2018.11.18 |
[System call 실습]System call의 기본 개념 (0) | 2018.11.02 |
[Git실습]Git사용법 부터 간단한 작성,수정,저장 (0) | 2018.10.17 |
[make 실습]기능별로 디렉토리를 나누어 make file 호출 (0) | 2018.10.07 |