파일시스템 관련

mkdir / cp ln / mv / rm / find grep

이제 드디어, 마침내, 명령어 훑어보기를 시작하자! 하루에 뭘 이렇게 많이 봐야되는지 어쩌고 하는 불만은 가지지 않았으면 한다. 또 어떤 명령어에 대해 추가적인 설명이 필요하면 알아서 command --help 내지 man, info 명령을 활용하길. lscd도 사실 이 분류에 속하겠지만 여기서 다시 설명을 하진 않겠다.

파일시스템에 관한 명령어들
$ mkdir [dir] - 새 디렉토리 만들기

디렉토리를 새로 만드는 명령이다. 한 가지 주의할 것은; "한글로 된 이름은 가능하면 만들지 말라!" 파일이름과 디렉토리 이름은 (천재지변이 있지 않는 한) 가능하면 어떤 소프트웨어에서도 인식이 되도록 알파벳숫자, 그리고 _ 문자와 - 문자의 적절한 조합으로 만들자. [11]

뿐만 아니라, 파일이나 디렉토리의 이름에 공백문자(스페이스바나 탭키를 눌러서 표현하는)를 포함하지 않는 습관을 들이자. 예를들어 my favorite photomy_favorite_photo로 표현하는게 바람직하다.

$ cp [source] [new] - 파일 및 디렉토리 복사

보인 것처럼, sourcenew로 복사한다. 만약 new가 디렉토리라면 그 디렉토리 아래에 source라는 이름 그대로 새 파일을 만든다.

source가 디렉토리일 때는 cp -r source new, 즉 -r 옵션을 붙여준다(recursive). 이때 만약 new가 이미 존재하는 디렉토리라면 앞서와 마찬가지로 source라는 이름의 새 디렉토리를 new 디렉토리 아래에 만들게 된다.

$ cp /usr/include/math.h ~/prog/my_math.h  # math.h를 홈의 prog 디렉토리에 새 이름으로 복사
$ cp -r /etc/X11 .                      # X11 디렉토리 전체를 현재 위치에 복사
$ cp -rf ~jedi/prog* /tmp               # jedi의 홈에서 prog로 시작하는 모든 것을 /tmp에 강제로 복사

-rf 옵션은 디렉토리라는 의미와 강제로라는 의미를 모두 가지고 있다. 강제 옵션은 같은 이름의 파일이나 디렉토리가 있어도 덮어써 버린다(force).

$ ln [target] [name] - 파일 및 디렉토리 링크

어떤 파일(디렉토리)에 또다른 이름을 붙여두고, 각자의 취향이나 그 날의 기분에 따라 아무 것이나 선택해 그 파일(디렉토리)에 접근할 수 있도록 한다. 단순히 ln target name이라고 하면 "하드 링크"를, 그리고 ln -s target name이라고 하면 "심볼릭 링크"를 생성한다.

  • 하드 링크 (hard links, a.k.a simply links) - 하드 링크된 targetname은 완전히 똑같은 하드디스크 영역이다. 다르게 말해, 원래 하나의 경로 이름을 가지고 있는 하드디스크의 데이터 조각이 하나의 이름을 더 가지게 된다는 것이다. 데이터 조각과 경로명에 대한 또다른 잔소리가 곧 mv 명령에서도 이어질 것이다.

  • 심볼릭 링크 (symbolic links, a.k.a symlinks) - 이것이 보통 '바로 가기(단축 아이콘)' 정도로 인식되어 있다. target을 심볼릭 링크하고 있는 name은 새롭게 생성되는 별도의 파일이며 그 내용은 바로 target의 경로명이다. 따라서 링크되는 파일의 데이터 크기는 심볼릭 링크 파일의 크기와는 아무 상관 없다. 하드링크와 심볼릭 링크를 이해하기 위해 아래를 참고하자.

$ ls -l
-rw-rw-r--    1 jedi     jedi            43  3월 21  2002 readme.txt
drwxr-xr-x    3 jedi     jedi          4096  6월 15  2002 Documents
$ ln readme.txt readyou.txt              # 하드 링크
$ ln -s Documents doc ; ls -l            # 심볼릭 링크
-rw-rw-r--  2 jedi  jedi    43  3월 21  2002 readme.txt
-rw-rw-r--  2 jedi  jedi    43  3월 21  2002 readyou.txt
drwxr-xr-x  3 jedi  jedi  4096  6월 15  2002 Documents
lrwxrwxrwx  1 jedi  jedi    10  8월 20 12:18 doc -> Documents/

(오늘은 2002/08/20) 먼저 두 링크 파일의 생성 날짜를 보자. 하드 링크된 경우 readme.txt 파일과 readyou.txt 둘의 생성 날짜가 같다. 새로운 파일이 생성된 게 아니라 3월 21일에 생성된 readme.txt 파일이 단지 하나의 이름을 더 가지게 된 것일 뿐이므로; 하지만 심볼릭 링크인 doc 파일은 오늘 12시 18분에 생성된 새로운 파일이다.

파일의 크기를 보아도 재미있는 사실을 알 수 있다. 하드 링크는 몇 번 강조했듯이 아무런 차이가 있을 수 없지만; 심볼릭 링크의 크기인 10은 - 자기가 가리키고 있는 대상인 Documents 디렉토리의 '이름에 쓰인 글자 갯수'다.

포스가 강한 사람이라면 이 ls -l의 결과에서 두 번째 열, 즉 |2 2 3 1>[12]에서 좀 이상한 점을 찾을 수 있을 것이다. readme.txt의 원래 값은 1이었는데 readyou.txt가 하드 링크한 후 둘 다 그 값이 2로 되었다! 이것을 이해하는 건 어렵지도 않다 - 그 부분의 숫자는 바로 어떤 파일의 하드 링크 갯수를 의미하기 때문이다.[13]

$ mv [old] [new] - 파일 및 디렉토리 이름바꿈

불행히도 MS-DOS 환경에서의 이름바꿈 명령어와 이동 명령어를 기억하고 있지는 않길 바란다. 왜냐하면 두 명령이 디스크 공간에서 실제로 같은 일을 하기 때문이다. GNU/Linux 시스템에서 "이동"과 "이름바꿈"은 한 가지 명령, mv만으로 모두 처리될 수 있다.

GNU/Linux든 MS-Windows든, 같은 하드디스크 파티션(분할영역, partitions) 내에서 "이동" 명령을 내리면 파일의 크기에 관계없이 금방 명령이 처리된다. 하드디스크의 다른 곳으로 파일을 옮기는 것이 아니라 -- 같은 파티션 내에서는 -- 단지 그 파일의 절대경로만 살짝 바꾸는, 다시말해 "이름을 바꾸는" 것에 불과하다. 하드디스크의 다른 영역으로 "옮겨가는" 경우는 다른 파티션으로 이동시킬 때다. 이 말이 혼란스럽다면 한 가지 결정적인 힌트를 주겠다; 어떤 운영체제에서든지, 디렉토리(폴더)의 구조란 하드디스크에 저장된 데이터를 "논리적"으로 구성한 것일 뿐 결코 "물리적"인 배치가 아니다!

같은 디렉토리의 파일이 디스크의 반대쪽에?

하드디스크의 어떤 영역을 차지하고 있는 데이터 조각이 바로 파일이고, 그 파일은 자신의 경로(다른 영역과 구분되는)를 유지하고 있으며, 시스템은 그 경로를 파악해서 논리적인 디렉토리를 구성하는 것이다. 하드디스크의 완전히 다른 영역에 자리잡은 데이터 조각도 같은 같은 경로값을 가지고 있다면 파일 시스템에서는 같은 디렉토리에 있는 것처럼 보인다.

mv 동작은 cp와 유사하다. 즉 주어진 대상이 모두 파일일 때는 기대한 것처럼 new라는 이름의 파일로 바뀌고, mv old.txt dir/와 같은 경우에는 old.txtdir/ 디렉토리로 이동하며(이것도 사실 실제로 이동하는 것이 아니라 그 파일의 경로값이 바뀌는 것임), mv dir1/ dir2/ 명령을 하면 디렉토리의 이름이 바뀌거나 혹은 '이미 존재하는 dir2/' 밑으로 dir1/이 이동한다.

$ rm [file] - 파일 및 디렉토리 삭제

일반 파일을 지울 때는 특별한 옵션없이 사용하고, 지울 대상에 디렉토리가 포함되었다면 rm -r dir/, 즉 -r 옵션과 함께 명령한다. 지울 때마다 제정신인지(?) 확인하는 옵션은 -i, 잔소리말고 조용히 지워버리라고 명시하기 위해 -f 옵션을 이용한다.

$ find [start_path] [expression] - 파일 찾기

파일이나 디렉토리를 찾는 명령이다. start_path 옵션은 검색을 시작할 디렉토리를, 그리고 expression은 검색의 기준을 나타낸다. 웹게시판에서의 검색과 비슷하다. 예를들어 현재 디렉토리 아래에서 my_doc.txt라는 이름의 파일을 찾으려면 find . -name my_doc.txt라고 한다. 또 다른 예로 /etc 디렉토리 아래에서 http로 시작되는 이름의 모든 파일을 찾으려면 find /etc -name http*라고 하면 된다.

여기까지만 보면 단지 이름만으로 검색하는 간단한 명령 같지만, man find 명령을 해보면 머리가 아파올 정도로 다양한 검색조건이 있음을 알 수 있을 것이다. 자주 이용하게 될 몇 가지만 살펴보면 다음과 같다.

$ find /tmp -user yoda                    # /tmp에서 yoda 소유의 파일 검색
$ find ~ -newer abc.d                   # 자신의 홈에서 abc.d 보다 더 최근에 수정된 파일 검색
$ find ~yoda -perm 700 -amin 60         # yoda의 홈에서 소유권 700, 60분 이내에 접근된 파일 검색

소유권(퍼미션, permissions)이 무엇인지는 곧(오늘 안으로) 소개될 것이다. 그리고 나머지 다양한 검색조건은 필요할 때 매뉴얼을 참고하자.



[11] 이 원칙은 - 문자를 제외한다면 일반적인 프로그래밍 언어에서의 원칙(변수와 함수, 클래스 이름)과 마찬가지다.

[12] Dirac에 의한 열 벡터(column vectors) 표기다 :-)

[13] 그런데 디렉토리의 하드 링크 갯수는 무엇을 의미할까? 각자 연구해 보길! [힌트] 표시되는 숫자는 그 디렉토리 안에 들어있는 디렉토리의 갯수 + 2