디렉터리 구조

Linux에는 C 드라이브, D 드라이브 같은 구분이 없다. 모든 파일이 /(루트)에서 시작하는 나무 하나에 매달려 있다. 폴더는 보통 디렉터리라고 부른다.

경로내용
/맨 꼭대기. 모든 경로가 여기서 시작한다.
/home/kim사용자 kim의 홈 디렉터리. 자기 파일은 여기 둔다. ~로 줄여 쓴다.
/usr/bin, /binls, grep 같은 프로그램 실행 파일
/etc시스템 설정 파일
/tmp임시 파일. 재부팅하면 지워질 수 있다.
/mnt/cWSL에서 보이는 Windows C 드라이브

/와 ~를 헷갈리기 쉽다. /는 시스템 전체의 뿌리이고, 일반 사용자는 거기에 파일을 만들 수 없다. ~는 내 홈이다. 클러스터에서는 홈 말고도 용량이 큰 작업용 디렉터리(scratch 등)를 따로 주는 경우가 많은데, 경로와 용량 한도는 클러스터마다 다르니 사이트 문서를 확인한다(09장).

절대 경로와 상대 경로

절대 경로는 /로 시작하는 전체 주소다. 어디서 쓰든 같은 곳을 가리킨다. 상대 경로는 지금 있는 디렉터리를 기준으로 한 주소다.

표기뜻예
/로 시작절대 경로/home/kim/proj/h2o-opt/water.inp
~홈 디렉터리~/proj/h2o-opt
.현재 디렉터리./run.sh
..한 단계 위 디렉터리../h2o-sp/water.out
그 외현재 디렉터리 기준 상대 경로h2o-opt/water.inp

~/proj/h2o-opt에 있을 때 water.inp, ./water.inp, ~/proj/h2o-opt/water.inp는 모두 같은 파일이다. 작업 스크립트 안에서는 어디서 실행될지 모르니 절대 경로를 쓰는 편이 안전하다.

이동하고 둘러보기

cd(change directory)로 디렉터리를 옮기고, pwd로 현재 위치를 확인한다.

$ cd ~/proj
$ pwd
/home/kim/proj
$ ls
h2o-opt  h2o-sp
$ cd h2o-opt
$ cd ../h2o-sp
$ pwd
/home/kim/proj/h2o-sp
$ cd
$ pwd
/home/kim
$ cd -
/home/kim/proj/h2o-sp

인자 없이 cd만 치면 홈으로 가고, cd -는 바로 전에 있던 디렉터리로 돌아간다.

ls 옵션

ls -l은 한 줄에 파일 하나씩 권한, 크기, 수정 시각을 보여 준다. 옵션은 -la처럼 붙여 쓸 수 있다.

$ ls -la ~/proj/h2o-sp
total 60
drwxr-xr-x 2 kim kim  4096 Sep 28 18:12 .
drwxr-xr-x 4 kim kim  4096 Sep 28 18:12 ..
-rw-r--r-- 1 kim kim   186 Sep 28 18:12 water.inp
-rw-r--r-- 1 kim kim 48678 Sep 28 18:12 water.out
옵션하는 일
-l자세히 (권한, 소유자, 크기, 시각). 각 열의 뜻은 04장에서 다룬다.
-a숨김 파일까지 모두
-h크기를 167K, 2.1G처럼 읽기 쉽게 (-l과 함께)
-t최근에 수정된 순서로 정렬
-r정렬 순서 뒤집기. ls -ltr이면 가장 최근 파일이 맨 아래에 온다.

숨김 파일

이름이 .으로 시작하는 파일은 ls에 나오지 않는다. 설정 파일이 대부분 이렇게 숨어 있다.

$ cd
$ ls
proj
$ ls -a
.  ..  .bash_history  .bashrc  .cache  .profile  .ssh  proj

.bashrc는 05장, .ssh는 06장에서 다시 나온다.

Tab 자동 완성

파일 이름을 몇 글자 치고 Tab을 누르면 셸이 나머지를 채운다. 후보가 여러 개면 한 번 더 눌러 목록을 본다. cd ~/proj/h2까지 치고 Tab을 두 번 누르면 h2o-opt/와 h2o-sp/가 나온다. 오타가 줄고, 완성이 안 되면 경로가 틀렸다는 뜻이라 확인용으로도 쓸 만하다.

만들기, 복사, 이동, 삭제

명령하는 일
mkdir dir디렉터리 만들기
mkdir -p a/b/c중간 디렉터리까지 한꺼번에. 이미 있어도 오류를 내지 않는다.
cp src dst파일 복사
cp -r src dst디렉터리를 통째로 복사
mv src dst이동. 같은 디렉터리 안에서 쓰면 이름 바꾸기가 된다.
rm file파일 삭제
rm -r dir디렉터리와 그 안의 모든 것 삭제
rmdir dir빈 디렉터리만 삭제
$ cd ~/proj
$ mkdir ch4-conf/conf01
mkdir: cannot create directory ‘ch4-conf/conf01’: No such file or directory
$ mkdir -p ch4-conf/conf01 ch4-conf/conf02
$ cp h2o-sp h2o-sp-copy
cp: -r not specified; omitting directory 'h2o-sp'
$ cp -r h2o-sp h2o-sp-copy
$ mv h2o-sp-copy h2o-sp-old
$ rmdir h2o-sp-old
rmdir: failed to remove 'h2o-sp-old': Directory not empty
$ rm -r h2o-sp-old

계산을 조금 바꿔 다시 돌릴 때는 기존 디렉터리를 cp -r로 복사하고 입력 파일만 고치는 식으로 많이 쓴다. 이때 출력 파일까지 딸려 오니, 새 디렉터리에서 옛 .out이나 .gbw를 지우고 시작한다.

rm에는 휴지통이 없다

rm으로 지운 파일은 되살릴 방법이 사실상 없다. cp와 mv도 같은 이름의 파일이 있으면 묻지 않고 덮어쓴다. rm -r을 칠 때는 경로를 한 번 더 읽고, 와일드카드를 쓸 때는 먼저 ls로 무엇이 걸리는지 본다. rm -i, cp -i, mv -i는 파일마다 확인을 묻는다. 클러스터 scratch 디렉터리는 백업이 없는 곳이 많다.

와일드카드

파일 이름 자리에 특수 문자를 쓰면 셸이 맞는 파일 이름들로 바꿔 넣는다. 명령이 실행되기 전에 셸이 펼치는 것이라 ls, cp, rm, grep 어디에나 쓸 수 있다.

패턴뜻예
*아무 글자 0개 이상*.xyz: 모든 xyz 파일
?아무 글자 정확히 1개conf0?.xyz: conf01 ~ conf09
[12]괄호 안 글자 중 하나conf0[12].*: conf01, conf02
[0-9]범위 안 글자 하나conf[0-9][0-9].out
$ ls
conf01.out  conf01.xyz  conf02.out  conf02.xyz  conf03.xyz  conf10.xyz
$ ls *.xyz
conf01.xyz  conf02.xyz  conf03.xyz  conf10.xyz
$ ls conf0?.xyz
conf01.xyz  conf02.xyz  conf03.xyz
$ ls conf0[12].*
conf01.out  conf01.xyz  conf02.out  conf02.xyz
$ ls *.log
ls: cannot access '*.log': No such file or directory

conf0?.xyz에 conf10.xyz는 걸리지 않는다. 맞는 파일이 하나도 없으면 bash는 패턴을 그대로 넘기고, ls는 *.log라는 이름의 파일을 찾다가 실패한다.

파일 이름 규칙

셸은 공백으로 인자를 나눈다. 그래서 이름에 공백이 있으면 한 파일이 두 개로 읽힌다. 아래에서 rm은 my water.xyz가 아니라 my와 water.xyz를 지우려 했고, 엉뚱하게 water.xyz를 지웠다.

$ ls
my water.xyz  water.xyz
$ rm my water.xyz
rm: cannot remove 'my': No such file or directory
$ ls
my water.xyz

공백이 든 이름은 따옴표로 감싸거나("my water.xyz") 공백 앞에 역슬래시를 붙인다(my\ water.xyz). Tab 완성은 역슬래시를 알아서 넣어 준다. 하지만 애초에 공백 없는 이름을 쓰는 편이 낫다. 영문자, 숫자, -, _, .만 쓰면 어떤 프로그램에서도 문제가 없다. 한글 이름이나 괄호, &가 들어간 이름도 계산 프로그램과 스크립트에서 말썽을 일으킨다.

계산 디렉터리 정리하기

ORCA, xtb, QE는 모두 현재 디렉터리에 중간 파일을 많이 쓴다. 계산 하나에 디렉터리 하나를 주면 서로 덮어쓸 일이 없고, 나중에 어떤 입력으로 어떤 출력이 나왔는지 헷갈리지 않는다. 예를 들면 이렇게 정리한다.

proj
├── ch4-conf
│   ├── conf01
│   │   └── ch4.inp
│   └── conf02
│       └── ch4.inp
├── h2o-freq
│   └── water.inp
├── h2o-opt
│   ├── run.pbs
│   ├── water.inp
│   └── water.xyz
├── notes
│   └── log.md
├── scripts
│   └── get-energy.sh
└── structures
    ├── methane.xyz
    └── water.xyz

9 directories, 10 files

이 그림은 tree proj로 그렸다(sudo apt install tree). 디렉터리 이름에 분자와 계산 종류를 넣고, 같은 방식으로 이름을 붙이면 나중에 */water.out 같은 와일드카드로 한꺼번에 다루기 쉽다. 그런 반복 작업을 스크립트로 묶는 법은 셸 스크립팅 가이드에서 다룬다.