'IT/프로그래밍 과제'에 해당되는 글 7건

ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-3

IT/프로그래밍 과제



2013/05/10 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-2


2013/05/05 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1


지난 포스팅에서 간략하게 필요한 알고리즘과 동작 방식에 대해

대충 알아보았었는데, 이번 포스팅에선 직접 살펴보고 구현해 볼 것이다.

(아래 파일 다운로드를 할 수 있다.)


먼저 하위 디렉토리를 탐색하기 위해선, 

우선 디렉토리인자 판별하는 구문이 필요하다.


디렉토리 오픈 후, readdir 함수와 lstat 함수를 통해 파일들을 읽어 저장 한 뒤에

stat 구조체의 st_mode로 구별하면 쉽게 디렉토리인지 판별이 가능하다.


하지만, 지난 ls 명령어 구현에서 Info_st라는 사용자 구조체에 이미 파일에 대한 정보가 저장 하도록 구현했으니, 구조체에 저장된 정보로 판별하도록 코딩을 해 볼 것이다.


구조체에 저장된 정보로 디렉토리 인지 판별은 파일 퍼미션의 첫자리가 'd'이면 디렉토리이다. 그리고 현재와 상위 디렉토리를 제외하기 위해서 "." ".."을 제외시켜야 한다. 이유는 현재 디렉토리에서 하위 디렉토리를 찾기 위함이다.


이를 간단히 코딩해 보면, 

이 if문을 해석해 보면 사용자 구조체의 퍼미션 첫째자리가 'd'이고

사용자 구조체 파일이름이 ".." "."이 아니면 이다.


즉, 디렉토리 일때만 실행되게 한 것이다.


이제 사용자 구조체에 정의되어 있는 파일이름에 해당하는 path를

디렉토리를 탐색하는 함수에 인자로 넣어주어 호출하기면 하면 재귀적으로 동작 할 것이다.


하지만, 이 path를 만드는데 고민이 필요했었는데. 이유는 lstat으로 불러온 정보는

파일 이름만 있었기 때문에 파일 이름만 넘겨주면 path가 완성되지 않았었다.


이를 고치기 위해서 생각한 방법이 디렉토리 탐색 함수의 인자로 받은 path 뒤에

lstat으로 불러온 파일 이름을 이어 붙여주면 된다.


이동작을 수행하기 위해 ls -al 과제1 이후에 새롭게 추가된 함수가 있는데 바로

ReadPathAndFilenameCpy 함수이다. 원형과 내용을 살펴보도록 하자.

디렉토리 탐색함수의 인자인 dirname과 filename이란 char 포인터를 인자로 받는다.

filename은 lstat으로 얻은 파일 이름을 가리키는 포인터 이다.


함수를 살펴보면,

메모리 소비를 줄이기 위해 고정 버퍼를 사용하는게 아니라,

할당을 통해 동적으로 메모리를 할당하는 것을 볼 수가 있다.


만약 처음 지장한 maxPathLen크기보다 path가 커진다면 ExtenMem 함수를 통해서

메모리를 realloc함수를 통해 크기를 늘리게 된다. 


함수에 대해 간단히 설명하자면, 첫번째 while문에서 dirname을 복사하고,

if문을 통해 '/'을 어이 붙여준다. 그런 뒤 filename을 그 뒤에 이어 붙여주어서

절대Path를 반환하는 함수이다.


예를 들어 함수를 호출할 때,

dirname이 /etc이고 filename이 Consolekit이라면

함수를 통해 반환되는 path는 /etc/Consolekit 이라는 path가 만들어 진다.

이 path를 통해 다시 디렉토리탐색 함수의 인자로 넣어주면 반복적인 동작을 통해

하위 디렉토리까지 전부 탐색 출력하는 프로그램을 만들 수 있다.


ReadPathAndFilenameCpy처럼 ls -al 명령어 1단계 이후 새롭게 추가 된 함수가 있는데

ExtenMem 함수와 ReadString이라는 함수가 있다. 

ExtenMem함수는 위에 설명했듯 realloc을 통해 메모리를 재 확장하는 함수이고,

ReadString함수는 처음 디렉토리 path를 고정버퍼가 아닌 동적 할당을 통해 메모리 손실을 없애고자 만든 함수이다. 

함수는 동작원리는 ReadPathAndFilenameCpy와 비슷하니 이해하기가 쉬울 것이다.


작성한 프로그램 실행사진을 살펴보겠다.


명령어를 입력하면, 아래와 같이 하위디렉토리가 출력 되는 것을 볼 수 있다.

아래 작성한 코드를 다운 받을 수 있도록 해 두었습니다.

궁금하신 점이나, 문의가 있으시면 댓글 혹은 메일 주시면 답변 드리겠습니다.


위 코드는 제가 작성한 코드로 프로그램 코딩 및 정보 교환을 목적으로 

공유하니, 상업적인 용도로 사용하지 말아주셨으면 좋겠습니다.


그리고 저 또한 부족한 점이 많으니 좀 더 개선 될 수 있는 방향을 제시해 주신다면,

개선해 나가도록 노력하겠습니다. 감사합니다.


자세한 사항은 파일에 주석 처리 하도록 하겠습니다.



※ 다운로드 file

hw2.c

list.c

list.h

user.h



ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-2

IT/프로그래밍 과제



2013/05/05 - [Programming/프로그래밍 과제] - ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1


지난번 포스팅에서 터미널에 ls -alR 을 쳐서 출력 결과를 살펴보았었다.

오늘은 동작에 관한 알고리즘을 생각해 볼 것이다.


1차 ls 명령어 구현에서는 단일 Linked List를 사용해서 ls명령어를 구현했었는데,

이번 하위디렉토리 출력도 같은 자료구조를 사용해서 구현할 것이다.


우선 지난 번 ls명령어 구현 동작을 살펴보면,

연결된 리스트 들을 관리하는 List가 있고, 

List에는 head, tail이 각각 Linked List들의  맨 앞과 뒤를 연결하고 있는 자료구조 형태이다. 

그리고 각각의 Listed List들에는 파일의 정보가 담겨있는 구조체 포인터를 가지고 있다.


ls -alR 명렁어는 파일 출력 순서대로 하위 디렉토리를 출력하는데,

이에 따른 알고리즘은 생각해 보면 간단하다.


처음 입력 받은 디렉토리 path값에 함수의 인자로 하위디렉토리 path를 인자로 넘겨주면 또 다시 위와 같은 출력을 할 수 있을 것이다. 


간단히 예를 들어 그림으로 보자면,

처음 입력 받았던 /etc를 자료구조에 모두 저장 한 뒤, 파일 이름순으로 정렬 후

연결된 리스트들의 맨 처음 부터 디렉토리인지 검사 한 뒤에


순차적인 검사를 통해 파일이 디렉토리이면 그 파일의 절대Path를 디렉토리 자료를 저장 정렬 출력하는 함수의 인자로 넘겨주면 위 그림과 같이 동작 할 수 있을 것이다. 

(자주 형광색이 디렉토리를 검사하고 다시 함수를 호출해서 가는 선이다)


그렇다면 우리가 원했던 재귀적인 동작으로 ls -alR 명령어를 구현 할 수 있다!!

생각보다 간단하다고 생각되지 않는가?


알고리즘과 동작 방법만 본다면 간단하다는 생각이 들 것이다. 

디렉토리 판별구문과 디렉토리Path를 넘겨주기만 한다면 재귀적으로 동작하여,

하위 디렉토리들을 전부 출력할 수 있을 테니 말이다.


하지만, 파일을 판별하는 것과 Path를 넘겨주는 부분에 신경써야할 부분이 있다.

실제로 이 부분이 생각지 못한 복병이 숨어있어 시간이 꽤 지체 되었었다.


다음 포스팅에서 ls -alR 하위디렉토리 정보까지 출력하는 데 

필요한 구문과 방법 및 코딩에 대해 알아 보도록 하자.




ls 명령어 구현 2단계, ls -alR 구현, 디렉토리 정보 출력-1

IT/프로그래밍 과제


ls 명령어는 옵션에 따라서 다양한 출력 방법으로 파일 정보를 출력하는데, 

이번 구현에 필요한 옵션은 지난번 -al 옵션에 -R 옵션을 붙인 것이다.


-a 숨김파일 표시

-l 파일의 자세한 정보

-R 하위디렉토리 파일 표시


우선 ls -alR이 어떤 방식으로 표현되는지 보기 위해 터미널에 "ls -alR"를 쳐 보았다.



ls 명령어에 -alR옵션을 주니, 


숨김파일표시, 파일 자세한 정보 표시가 하위디렉토리까지 표시되었다.

정렬에 대한 옵션은 주지 않아 파일 이름순으로 정렬되어 출력이 되었고,

이름순으로 정렬된 디렉토리 내용이 출력되었다.


(직접 터미널에 ls -alR을 쳐보시기 바랍니다.)


또 한가지 이번 구현에 따른 Mission이 주어졌는데,

ls 명령어 구현 2단계 Mission은 재귀적인 동작으로 ls 명령어를 동작하는 것이다.

즉, 자기자신의 함수를 호출하는 방식으로 동작하도록 코딩을 하는 것이다.


얼핏보면 재귀적이란 것에 대해 익숙한 사람이라면

간단해 보일 것 같은 문제일 것 같다.


구현에 있어, 생각만큼 간단하진 않았는데,

그 이유가 자잘한 오류가 많았다. 

차근차근 살펴보며 ls 명령어를 구현해 보기로 한다.


Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 code

IT/프로그래밍 과제


구현한 ls 명령어는 정확히 Linux/Unix에서 ls -al옵션을 구현한 것이다.

-a의 옵션은 숨긴파일도 표시하는 옵션이고, -l 옵션은 파일의 상세정보를 보는 옵션이다.


아래 코드는 스크린샷으로 공개하며,

첨부파일에 코드를 업로드를 할 것입니다.


필요하신분은 가져가서 쓰시되, 상업용으로 사용하지 말아주셨으면 좋겠습니다.

프로그래밍 공부를 하시는 분들게 좋은 자료가 되었으면 좋겠습니다.

자료를 퍼가실때 출처와 댓글에 퍼간다는 댓글 남겨주시는 센스 부탁드립니다.


이 코드는 제가 직접 과제를 진행하며 작성한 코드이며 ls 명령어의 정확한 답이 아님을 말씀드립니다.

코드에 대해 잘못된 부분이나 지적 사항등을 남겨주시면, 오히려 제가 더 감사하겠습니다.


궁금한점 있으시면 댓글 or 메일 주시면 답변 드리겠습니다.


 ※다운로드

Homework1.c

list.c

list.h

user.h






※파일 설명


파일은 Homework.c user.h list.c list.h 4가지 입니다.


사용한 자료구조는 단일 링크드 리스트이고, 정렬 방법은 버블정렬 입니다.


list.c list.h는 링크드 리스트 관련 함수 소스와 헤더파일로 mastering algorithm with c 책의 소스입니다.

링크드 리스트 관련 함수는 따로 사진은 올리지 안겠습니다.


user.h는 헤더파일들을 #include하고, 여러 #define 매크로들과 파일정보를 저장할 구조체 선언과

구현한 함수들이 선언되어 있습니다.


Homework.c파일은 메인 함수와 여러 함수들의 code가 있는 파일입니다.


1. user.h 파일


2. Homework.c 파일



 이전 ls 명령어 구현, 포스팅 보기

2013/04/28 - [Programming/프로그래밍 과제] - Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -2


2013/04/27 - [Programming/프로그래밍 과제] - Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -1








Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -2

IT/프로그래밍 과제


메인 함수를 작성하며 디렉토리를 열기 위해서 필요한 path를 입력 받아야 했기 때문에,

scanf를 통해서 입력 받았고, 필요한 배열의 크기는 char형 크기 100만큼 선언하였다.


그리고, ls -al /etc 에서 나오는 합계가 처음에는 파일 갯수 인지 알고 갯수를 구하는 함수를 만들었는데,

일치하지 않았다. 그래서, 파일 크기인 것이라 생각하고 임의적으로

디렉토리를 정해서, 크기를 합하였더니 또 다시 일치하지 않았다.


터미널에서 ls -al /usr을 쳐보면 


5번째 출력 정보에 파일 크기인데, 크기가 워낙 차이가 났다. 


왜 그런것인지 고민해보다가, 단위 때문일까 합계에 /1024로 나누어 주니

total의 크기와 같아 지는 것을 볼 수 있었다.


그런데!!, 일치 하지 않는 디렉토리를 볼 수 있었는데

내가 생각했던 파일 크기와는 다른 부분이 있는 것 같았다. 


아직 그 원인을 찾지는 못했지만, 

total부분을 구현하는데, 크기말고 파일의 블럭으로 계산을 하면 일치하는 것을 볼 수 있었다.



그리고 메인에서 DirSeek라는 디렉토리 함수를 만들어,

프로그램에서 파일 정보를찾고 읽고 출력하는 함수를 만들었다.


디렉토리를 open하는 것은 opendir함수를 사용했고,

파일 정보를 읽어오는 것은 readdir함수lstat함수를 사용했다.

(위 함수에 관 것은 Learn IT, C언어 부분에 포스팅 하도록 하겠다.)


원하는 대로, 생각한대로 코딩이 되었고 정상 작동 했다면 이미 과제는 끝났겠지만,

역시나 그렇지 않았고, 문제가 발생했다.


결론부터 얘기하자면, lstat함수에서 발생을 했는데

출력에서 모두 같은 정보만 출력하다가 segmantaion fault 오류가 나는 것이었다.


원인은 lstat에서 에러를 발생해 파일 정보를 얻어오지 못했는데, 

이것을 모르고 한참 해맸다. 그리고 lstat인자에 Path를 넘겨주기 위해,

따로 char * 변수를 선언해 입력받은 Path와 dirent 구조체에 d_name에 저장되어 있는 이름을

strcpy함수와 strcat함수를 이용해 절대 Path를 만들어 주어 넘겨주었다.


즉, 이런 식으로 말이다.

중간에 "/"들어가는 이유는 절대path를 만들어 주기 위해서 넣어주었고 실제로 없으면,

작동하지 않는다.


그리고 파일 정보를 저장할 구조체를 선언한뒤,

lstat함수의 성공시 stat이란 구조체에 저장된 정보들을 구조체에 저장토록 했다.


구조체를 보면,

필요한 정보들을 저장 할 수 있도록 하였다.


ls명령어를 구현함에 있어서 큰 문제중 하나였던 것은 

출력시, 각 항목의 길이에 맞춰서 정렬이 되는 것이었다.


먼저 ls -al /etc를 터미널에 쳐보면,

항목마다 가지런히 정렬되어 출력되는 모습을 볼 수 있다.


내가 만든 ls 명령어 프로그램 코딩을 완성하고 세그멘테이션 폴트 오류도 수정 한 뒤,  컴파일  한 뒤

실행하여 보았더니 이게...

내가 원하는 대로 정렬과 출력이 되었지만, 무엇인가 모양이 이상하다.

바로 출력 정렬이 안되었던 것이다. 이때까지 출력정렬을 하는 법을 자세히 몰랐기에

다시 printf함수를 공부하게 되었다.


그리고 각 파일의 항목마다 가장 큰 값으로 정렬된다는 것을 깨닫고,

항목마다 큰 값을 구해 출력정렬을 하는 함수를 따로 만들어 사용하였다.


그 결과 원하는 정렬로 출력하는 모습을 볼 수 있었고, 

ls -al /etc와 같은 결과를 출력하는 프로그램을 만들 수 있었다.

다음 포스팅에서 구현한 코드와 실행사진을 올리도록 하겠다.


포스팅에서 정렬과 자료구조에 대해 나오지 않았는데, Learn IT카테고리에서 정리해 포스팅 하도록 하겠다.


※혹시나 궁금한 점이 있으신 분은 댓글 or 메일 문의 주시면 답변드리겠습니다.




※ 이전 포스팅 보기


2013/04/27 - [Programming/프로그래밍 과제] - Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -1

 




Linux/Ubuntu, ls 명령어 구현 1단계, 디렉토리 파일 정보 출력 -1

IT/프로그래밍 과제



프로그래밍 과제 1, 

- ls 명령어 구현 디렉토리 파일 정보 출력


프로그래밍 과제1은 터미널에 ls -al /etc를 써넣었을 때와 동일하게 출력하는 과제다.

다른 부분은 전부 같아야하며, 단 출력시 색상은 출력부분은 구현하지 않아도 된다.


먼저 사용 OS, ubuntu terminator에서 ls -al /etc를 쳐보았다.



원래대로 라면 출력되는 정보가 뭔지도 몰랐을 텐데, 

4학년 여름방학 때 받은 교육 탓에 출력되는 정보가 뭔지 알게 되었다.


앞에서 부터 파일 권한, 하드링크 수, 유저명, 그룹명, 크기, 날짜, 시간, 파일 이름, 링크일시 원본 위치 순이였다.

이 과제를 수행하려면 필요한 것이 무엇인지 생각했다.


- 우선 파일 정보를 읽어오려면 디렉토리 open을 해야했고, 그리고 정보들을 저장할 자료구조가 필요했다.

- 그리고 파일 명을 보니 정렬이 되어 있어 sort함수가 필요했다.


그렇게 크게 3가지로 생각하고 함수 구현을 시작 했다.

자료구조는 내가 알고 있던 기본이 되는 단일 Linked list를 구현하기로 했고, 

정렬은 Bubble sort를 사용하기로 했다.


필요한 함수들과 동작 방법을 생각하며 main부터 차근히 코딩을 하기 시작했다.


Continue..



Linux/Ubuntu, 프로그래밍 과제와 네트워크 책

IT/프로그래밍 과제



과제와 책을 받다.


회사에 입사 후, 수습 3개월이란 기간 동안 무엇을 하는 것일까!? 하는 생각이 들었지만,

첫 날, 컴퓨터 조립과 셋팅을 마친 뒤, 나와 동기들에게 주어진 것은 프로그래밍 과제와 네트워크 책이였다.

네트워크 책은 무기로 사용해도 될 만큼 두꺼웠고, 프로그래밍 과제는 어디서 부터 시작해야하는지 막막했다.


프로그래밍 과제는 앞으로 1단계에서 5단계까지 될 것이고, 마치 학교 자료구조와 알고리즘 시간에

기본을 만들고 기능추가와 프로그램을 확장해 가는 방식이었는데, 흡사한 진행 방식이다. 


그리고, Linux를 다룸에 있어서 4학년 여름 방학 때 서버관리 교육을 받은 것들이

회사에서 적응하는 데 많은 도움을 주었다.

간단한 Linux 명령어와 Unix의 명령어들 사용법 같은 것들이, 앞으로 사용할 일이 없을지 알았는데 의외로 

사용하게 되어 교육 받길 잘 했다는 생각이 들었다.


앞으로 과제 및 개발에 있어서 되도록 많은 기록을 하고 

내가 받은 정보들이나 내가 알게 된 것들을 공유하도록 노력해야지.