소개
이 실습에서는 리눅스 명령줄 환경에서 파일과 디렉토리를 관리하는 데 필요한 핵심 기술을 배웁니다. mkdir과 rm을 사용하여 복잡한 디렉토리 구조를 생성하고 삭제하는 방법은 물론, cp와 mv를 사용하여 파일과 디렉토리를 복사하고 이동하는 실무 경험을 쌓게 됩니다.
더 나아가, 이 실습에서는 파일 링크에 대해 심도 있게 다룹니다. ln 명령어를 사용하여 심볼릭 (소프트) 링크와 하드 링크를 모두 생성해 보고, 파일 시스템의 근간이 되는 아이노드 (inode) 개념을 분석하며, 원본 파일이 수정될 때 각 링크 유형이 어떻게 다르게 반응하는지 관찰합니다. 이를 통해 리눅스 파일 시스템이 데이터를 조직하고 참조하는 방식에 대해 깊이 있게 이해할 수 있습니다.
mkdir, rmdir, rm 을 이용한 디렉토리 구조 생성 및 삭제
이 단계에서는 디렉토리를 생성하고 삭제하는 방법을 배웁니다. 파일을 계층적인 디렉토리 구조로 정리하는 것은 리눅스에서 가장 기본이 되는 작업입니다. 디렉토리를 만들 때는 mkdir, 비어 있는 디렉토리를 삭제할 때는 rmdir, 디렉토리와 그 안의 모든 내용을 삭제할 때는 rm 명령어를 사용합니다. 모든 명령어는 기본 디렉토리인 ~/project에서 실행됩니다.
먼저, 간단한 디렉토리를 만들어 보겠습니다. mkdir 명령어는 "make directory"의 약자입니다.
터미널에서 다음 명령어를 실행하여 cars라는 이름의 디렉토리를 생성합니다.
mkdir cars
디렉토리가 생성되었는지 확인하려면 ls -ld 명령어를 사용합니다. -l 옵션은 상세 정보를 보여주는 긴 목록 형식을 제공하며, -d 옵션은 디렉토리 내부 내용이 아닌 디렉토리 항목 자체를 표시합니다.
ls -ld cars
cars 디렉토리가 생성되었음을 확인하는 다음과 유사한 출력이 표시되어야 합니다. 권한 문자열 시작 부분의 d는 이것이 디렉토리임을 나타냅니다.
drwxr-xr-x 2 labex labex 4096 May 20 10:30 cars
이제 이 디렉토리를 삭제해 보겠습니다. rmdir 명령어는 비어 있는 디렉토리를 삭제할 때 사용합니다.
rmdir cars
ls -ld 명령어를 다시 실행하여 삭제되었는지 확인합니다.
ls -ld cars
이번에는 디렉토리가 더 이상 존재하지 않기 때문에 오류 메시지가 나타납니다. 이는 rmdir이 성공적으로 수행되었음을 의미합니다.
ls: cannot access 'cars': No such file or directory
rmdir 명령어는 비어 있는 디렉토리에서만 작동합니다. 그렇다면 중첩된 디렉토리 구조가 있는 경우는 어떨까요? pastry/pies/cakes라는 디렉토리 구조를 만들어 보겠습니다. 필요한 경우 상위 디렉토리까지 한꺼번에 생성하려면 mkdir에 -p(parents) 옵션을 사용해야 합니다.
다음 명령어를 실행합니다.
mkdir -p pastry/pies/cakes
방금 생성한 전체 디렉토리 구조를 확인하려면 ls 명령어에 -l(상세 정보) 및 -R(재귀적 표시) 옵션을 함께 사용합니다.
ls -lR pastry
출력 결과에 pastry 디렉토리와 그 하위 디렉토리인 pies, cakes가 표시됩니다.
pastry:
total 4
drwxr-xr-x 3 labex labex 4096 May 20 10:35 pies
pastry/pies:
total 4
drwxr-xr-x 2 labex labex 4096 May 20 10:35 cakes
pastry/pies/cakes:
total 0
이제 rmdir을 사용하여 pastry 디렉토리를 삭제해 보겠습니다.
rmdir pastry
왜 이 명령어가 실패했을까요? 터미널에 다음과 같은 오류 메시지가 표시됩니다.
rmdir: failed to remove 'pastry': Directory not empty
이는 rmdir이 비어 있는 디렉토리만 삭제할 수 있는데, pastry 안에는 pies라는 하위 디렉토리가 들어 있기 때문입니다.
디렉토리와 그 안의 모든 내용 (하위 디렉토리 및 파일 포함) 을 삭제하려면 rm 명령어에 -r(recursive, 재귀적) 옵션을 사용해야 합니다. 이 명령어는 데이터를 영구적으로 삭제할 수 있으므로 사용 시 매우 주의해야 합니다.
rm -r pastry
성공적으로 실행되면 아무런 출력도 나오지 않습니다. ls -ld pastry를 다시 실행하여 pastry 디렉토리가 완전히 삭제되었는지 확인할 수 있으며, "No such file or directory" 오류가 발생해야 정상입니다.
ls -ld pastry
vi 와 ln -s 를 이용한 파일 및 심볼릭 링크 생성
이 단계에서는 vi 텍스트 편집기를 사용하여 파일을 생성한 다음, 해당 파일에 대한 심볼릭 링크를 만들어 봅니다. 심볼릭 링크 (symlink 또는 soft link 라고도 함) 는 다른 파일이나 디렉토리를 가리키는 특수한 유형의 파일입니다. 다른 운영 체제의 '바로 가기'와 유사한 개념입니다.
먼저, vi를 사용하여 filea라는 간단한 텍스트 파일을 만들어 보겠습니다. vi는 강력한 화면 중심의 텍스트 편집기입니다. 크게 명령 모드 (Command mode) 와 입력 모드 (Insert mode) 라는 두 가지 모드가 있습니다. 시작 시에는 키 입력을 명령으로 해석하는 명령 모드 상태입니다. 텍스트를 입력하려면 입력 모드로 전환해야 합니다.
- 터미널의
~/project경로에서vi를 실행하여filea파일을 생성합니다.
vi filea
- 이제 터미널에
vi편집기 화면이 나타납니다. 입력을 시작하려면i키를 한 번 누릅니다. 화면 하단에-- INSERT --라는 문구가 표시될 것입니다. - 다음 텍스트를 입력합니다.
This is filea.
- 파일을 저장하고
vi를 종료하려면 먼저Esc키를 눌러 명령 모드로 돌아가야 합니다. 그런 다음ZZ(Shift 키를 누른 상태에서 Z 를 두 번 입력) 를 입력합니다. 이 명령은 파일을 저장하고 편집기를 종료합니다.
이제 다시 명령 프롬프트로 돌아왔으므로, 파일이 생성되었고 내용이 올바른지 확인해 보겠습니다.
먼저 파일을 목록에서 확인합니다.
ls filea
출력 결과는 단순히 파일 이름이어야 합니다.
filea
다음으로 cat 명령어를 사용하여 내용을 출력합니다.
cat filea
출력 결과는 방금 입력한 텍스트와 일치해야 합니다.
This is filea.
이제 심볼릭 링크를 만들어 보겠습니다. 원본 파일인 filea를 가리키는 fileb라는 이름의 링크를 생성합니다. 명령어 형식은 ln -s <원본_파일> <대상_링크>입니다.
ln -s filea fileb
결과를 확인하기 위해 ls -il 명령어를 사용합니다. -i 옵션은 파일 시스템에서 파일이나 디렉토리를 식별하는 고유 번호인 아이노드 (inode) 번호를 보여줍니다.
ls -il file[ab]
출력 내용을 주의 깊게 살펴보세요.
131075 -rw-r--r-- 1 labex labex 14 May 20 10:40 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
몇 가지 핵심 사항을 확인할 수 있습니다.
- 파일 유형:
filea의 권한 문자열은 일반 파일을 나타내는-로 시작합니다. 반면fileb는 심볼릭 링크를 나타내는l로 시작합니다. - 링크 포인터: 출력 결과에
fileb -> filea라고 명확히 표시됩니다. - 아이노드 번호: 첫 번째 열을 보십시오.
filea와fileb의 아이노드 번호가 서로 다릅니다. 그 이유는 심볼릭 링크가 대상 파일의 경로를 저장하고 있는 별개의 파일이기 때문입니다. 링크 자체가 독립적인 파일이므로 고유한 아이노드를 할당받습니다.
마지막으로 링크를 통해 내용을 읽을 수 있는지 확인해 봅니다.
cat fileb
출력 결과는 filea의 내용과 동일합니다.
This is filea.
이는 예상된 동작입니다. 심볼릭 링크에 대해 cat과 같은 작업을 수행하면 시스템은 자동으로 링크를 따라 원본 파일로 이동하여 해당 작업을 수행합니다.
ln 과 아이노드를 이용한 하드 링크 생성 및 분석
이 단계에서는 하드 링크를 생성하고, 이전에 만든 심볼릭 링크와 어떻게 다른지 알아봅니다. 파일 이름을 가리키는 포인터인 심볼릭 링크와 달리, 하드 링크는 파일 자체에 대한 또 다른 이름입니다. 두 이름 모두 디스크 상의 동일한 데이터를 직접 가리키며, 이 데이터는 **아이노드 (inode)**라는 고유 번호로 식별됩니다.
~/project 디렉토리에서 이전 단계의 filea와 fileb 파일을 계속 사용하겠습니다.
먼저, filea와 동일한 아이노드를 가리키는 filec라는 하드 링크를 생성합니다. 이를 위해 -s 옵션 없이 ln 명령어를 사용합니다.
ln filea filec
이제 원본 filea, 심볼릭 링크 fileb, 그리고 새로 만든 하드 링크 filec 세 파일의 내용을 모두 확인해 봅니다.
cat filea
cat fileb
cat filec
예상대로 동일한 내용이 세 번 출력되는 것을 볼 수 있습니다.
This is filea.
This is filea.
This is filea.
진짜 차이점은 파일 속성을 검사할 때 명확해집니다. 다시 ls -il 명령어를 사용하여 세 파일의 아이노드 번호와 기타 상세 정보를 확인합니다.
ls -il file[a-c]
출력 결과는 다음과 유사할 것입니다. 첫 번째와 두 번째 열에 주목하십시오.
131075 -rw-r--r-- 2 labex labex 14 May 20 10:40 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
131075 -rw-r--r-- 2 labex labex 14 May 20 10:40 filec
이 출력을 분석해 보겠습니다.
- 아이노드 번호 (1 열):
filea와filec가 완전히 동일한 아이노드 번호(예:131075) 를 가지고 있음을 알 수 있습니다. 이것이 하드 링크의 결정적인 특징입니다. 이들은 서로 다른 파일이 아니라, 디스크 상의 동일한 파일 데이터를 가리키는 두 개의 서로 다른 이름일 뿐입니다. 반면 심볼릭 링크인fileb는 자신만의 고유한 아이노드를 가집니다. - 링크 카운트 (2 열):
filea와filec의 숫자를 보십시오. 이제2로 표시됩니다. 이 숫자는 하드 링크 카운트로, 이 단일 아이노드를 가리키는 이름 (하드 링크) 이 몇 개인지를 추적합니다.filec를 생성했을 때 이 아이노드의 링크 카운트가 1 에서 2 로 증가한 것입니다. - 파일 유형 (권한의 첫 글자):
filec는filea와 마찬가지로 일반 파일 (권한이-로 시작) 로 표시됩니다.fileb(l로 시작) 와 같은 특수한 링크 유형이 아닙니다.
원본 파일 수정 후 링크 동작 관찰
이 단계에서는 원본 파일이 삭제되었다가 다시 생성될 때 심볼릭 링크와 하드 링크가 어떻게 다르게 동작하는지 관찰합니다. 이를 통해 각 링크 유형의 작동 방식을 확실히 이해할 수 있습니다. ~/project 디렉토리의 filea, fileb, filec를 계속 사용합니다.
먼저, 원본 파일인 filea를 삭제합니다.
rm filea
이제 세 파일의 상태를 확인해 보겠습니다. ls -l 명령어를 사용합니다. filea는 더 이상 존재하지 않으므로 오류가 발생할 것이며, 이는 정상입니다.
ls -l file[a-c]
출력 결과에서 중요한 사실을 알 수 있습니다.
ls: cannot access 'filea': No such file or directory
lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
-rw-r--r-- 1 labex labex 14 May 20 10:40 filec
- 심볼릭 링크
fileb: 링크가 "깨졌습니다 (broken)". 여전히filea라는 이름을 가리키고 있지만, 그 이름에 해당하는 파일이 더 이상 존재하지 않기 때문입니다. 많은 터미널에서 깨진 상태를 나타내기 위해fileb파일 이름을 빨간색으로 표시합니다.cat fileb를 시도하면 오류가 발생합니다. - 하드 링크
filec:filec파일은 전혀 영향을 받지 않았습니다. 링크 카운트 (두 번째 열) 가 2 에서 1 로 감소했을 뿐, 파일과 그 데이터는 여전히 온전합니다. 이는filea를 삭제한 것이 아이노드를 가리키는 이름 중 하나만 제거한 것이기 때문입니다. 데이터는 링크 카운트가 0 이 될 때까지 삭제되지 않습니다. 내용을 확인하여 이를 증명할 수 있습니다.
cat filec
출력 결과는 여전히 원래의 내용입니다.
This is filea.
이제 filea를 다시 만들되, 다른 내용을 넣어 보겠습니다. vi를 사용하여 filea라는 새 파일을 생성합니다.
vi실행:vi fileai를 눌러 입력 모드 진입.- 새 내용 입력:
This is the new filea. Esc를 눌러 명령 모드로 돌아온 후ZZ를 입력하여 저장 및 종료.
새로운 filea가 생성된 상태에서 ls -il로 세 파일을 다시 검사합니다.
ls -il file[a-c]
출력 결과는 새로운 상황을 보여줍니다.
131080 -rw-r--r-- 1 labex labex 20 May 20 11:05 filea
131076 lrwxrwxrwx 1 labex labex 5 May 20 10:41 fileb -> filea
131075 -rw-r--r-- 1 labex labex 14 May 20 10:40 filec
- 새로운
filea: 새로운filea파일이 존재하지만, 아이노드 번호 (예:131080) 가filec의 아이노드 (예:131075) 와 다릅니다. 이것은 우연히 예전 파일과 이름만 같을 뿐인 완전히 새로운 파일입니다. - 심볼릭 링크
fileb: 링크가 더 이상 깨져 있지 않습니다! 자동으로filea라는 이름을 가진 새 파일을 가리키게 되었습니다. - 하드 링크
filec:filec는 변함이 없습니다. 여전히 원래의 아이노드를 가리키고 있으며 원래 데이터를 유지하고 있습니다.
마지막으로 세 파일의 내용을 확인하여 결과를 비교해 봅니다.
cat filea
cat fileb
cat filec
출력 결과는 그 차이를 명확히 보여줍니다.
This is the new filea.
This is the new filea.
This is filea.
심볼릭 링크 fileb는 이름을 따라 새 파일로 연결된 반면, 하드 링크 filec는 원래 데이터와의 연결을 유지했습니다.
cp 와 mv 를 이용한 파일 복사 및 이동
마지막 단계에서는 파일 관리에 필수적인 cp(복사) 와 mv(이동) 명령어를 사용하는 방법을 배웁니다. cp 명령어는 파일이나 디렉토리의 복제본을 생성하고, mv 명령어는 파일/디렉토리의 이름을 바꾸거나 다른 위치로 이동시킵니다.
먼저 깨끗한 작업 공간을 만들기 위해 이전 단계의 파일들을 정리하겠습니다. 모든 명령어는 ~/project 디렉토리에서 실행합니다.
rm filea fileb filec
cp로 파일 복사하기
cp 명령어는 파일의 독립적인 새 복사본을 생성합니다. 새 파일은 자신만의 아이노드를 갖게 됩니다.
- 먼저
touch명령어를 사용하여 작업할 간단한 파일을 만듭니다.touch는 파일이 존재하지 않으면 빈 파일을 생성합니다.
touch source_file
- 이제 아이노드 번호 (첫 번째 열) 에 주의하며 파일 속성을 확인합니다.
ls -i source_file
출력 결과에 이 파일의 고유한 아이노드 번호가 표시됩니다.
131081 source_file
- 다음으로
source_file을copied_file이라는 새 파일로 복사합니다.
cp source_file copied_file
- 이제 두 파일의 속성을 모두 나열해 봅니다.
ls -i source_file copied_file
두 파일이 서로 다른 아이노드 번호를 가진 별개의 파일임을 확인할 수 있습니다.
131082 copied_file
131081 source_file
mv로 파일 이동 및 이름 변경하기
mv 명령어는 다재다능합니다. 대상이 동일한 디렉토리 내의 새 파일 이름이면 파일 이름을 바꿉니다. 대상이 디렉토리이면 파일을 그 안으로 이동시킵니다. 동일한 파일 시스템 내에서 이름을 바꾸거나 이동할 때는 아이노드 번호가 변하지 않습니다. 명령어는 단순히 파일의 이름이나 위치 포인터만 업데이트합니다.
source_file의 이름을renamed_file로 바꿔 보겠습니다.
mv source_file renamed_file
- 새로 이름이 바뀐 파일의 아이노드를 확인합니다.
ls -i renamed_file
아이노드 번호 (예: 131081) 가 원래의 source_file과 동일하다는 것을 알 수 있습니다. 파일 자체는 변하지 않았고 이름만 바뀌었기 때문입니다.
131081 renamed_file
- 이제 이 파일을 이동해 보겠습니다. 먼저 대상 디렉토리를 만듭니다.
mkdir move_destination
renamed_file을move_destination디렉토리 안으로 이동시킵니다.
mv renamed_file move_destination/
- 파일이 디렉토리 안에 있는지 확인하고 아이노드를 다시 체크합니다.
ls -i move_destination/renamed_file
아이노드 번호가 그대로 유지되는 것을 통해 파일이 복사된 것이 아니라 이동되었음을 확인할 수 있습니다.
131081 move_destination/renamed_file
덮어쓰기 처리
기본적으로 많은 시스템에서 실수로 기존 파일을 덮어쓰는 것을 방지하기 위해 cp를 cp -i로 별칭 (alias) 을 설정해 둡니다. -i는 "interactive(대화형)"를 의미합니다.
copied_file을move_destination디렉토리 안에 있는 파일 위로 복사해 보겠습니다.
cp -i copied_file move_destination/renamed_file
-i옵션 때문에 확인 메시지가 나타납니다.
cp: overwrite 'move_destination/renamed_file'?
덮어쓰기를 승인하려면 y를 입력하고 Enter 를 누릅니다. 취소하려면 n을 입력하면 됩니다.
요약
이 실습에서는 리눅스 환경에서 파일과 디렉토리를 관리하기 위한 기본 명령어들을 배웠습니다. mkdir을 사용하여 디렉토리 구조를 생성하고 (상위 디렉토리 생성을 위한 -p 옵션 포함), 비어 있는 디렉토리는 rmdir로, 내용이 있는 디렉토리는 rm으로 삭제하는 연습을 했습니다. 또한 vi 편집기를 사용하여 파일을 생성하고 파일 링크의 개념을 익혔습니다.
실습의 핵심은 두 가지 유형의 링크, 즉 ln -s를 이용한 심볼릭 (소프트) 링크와 ln을 이용한 하드 링크를 생성하고 분석하는 것이었습니다. 아이노드를 검사하고 원본 파일이 수정되거나 삭제될 때 각 링크가 어떻게 반응하는지 살펴봄으로써 두 링크의 주요 차이점을 확인했습니다. 마지막으로 cp 명령어로 독립적인 파일 복사본을 만들고, mv 명령어로 파일과 디렉토리의 위치를 옮기거나 이름을 바꾸는 방법을 실습하며 필수적인 파일 관리 작업 전반을 마무리했습니다.



