본문으로 건너뛰기

Linux와 터미널 기초

계산과학의 작업 환경은 대부분 Linux 터미널이다. SIESTA·VASP 같은 DFT 코드는 GUI 없이 셸에서 실행되고, 계산 서버 접속·로그 감시·입력 수정·결과 회수까지 전부 셸 명령으로 이뤄진다. 이 장은 이 튜토리얼을 따라가는 데 필요한 최소한의 셸 지식을 실전 예제(input.fdf, siesta.out, OUTCAR 등 실제 다루게 될 파일)로 정리한다. 이미 터미널에 익숙하다면 마지막의 자주 쓰는 조합 표만 훑고 넘어가도 된다.

디렉토리 탐색

명령역할
pwd현재 디렉토리 경로 출력
ls파일 목록 (-l 상세, -lh 사람이 읽는 용량, -ltr 최근 수정 순)
cd 경로디렉토리 이동 (cd .. 상위, cd ~ 홈, cd - 직전 위치)
pwd # /home/user/work/ch01-siesta-scf
ls -ltr # 방금 계산이 만든 파일이 목록 맨 아래에 온다
cd ../ch02-bands # 형제 디렉토리로 이동

계산 디렉토리에서 ls -ltr은 특히 유용하다 — 가장 최근에 갱신된 파일이 마지막 줄에 오므로, 계산이 지금 무엇을 쓰고 있는지 바로 보인다.

파일 조작

명령역할
mkdir -p 경로디렉토리 생성 (-p는 중간 경로까지 한 번에)
cp 원본 대상복사 (-r 디렉토리 통째)
mv 원본 대상이동 또는 이름 변경
rm 파일삭제 (-r 디렉토리)
mkdir -p scan/c_5.16 # 계산 케이스 디렉토리 생성
cp input.fdf input.fdf.bak # 수정 전 백업
mv siesta.out siesta.out.old # 재실행 전 이전 로그 보존
rm은 복구할 수 없다

Linux에는 휴지통이 없다. rm으로 지운 파일은 되돌릴 수 없으며, 특히 rm -rf 디렉토리는 확인 없이 트리 전체를 지운다. 며칠 걸린 계산 결과를 명령 한 줄로 잃을 수 있으므로, 삭제 대신 mv old_run/ _archive/처럼 보관 디렉토리로 옮기는 습관이 안전하다. 와일드카드 삭제(rm *.out)는 실행 전에 같은 패턴으로 ls *.out을 먼저 쳐서 대상 목록을 확인한다.

파일 내용 확인

명령역할
cat 파일전체 출력 — 짧은 파일(입력 파일 확인)용
less 파일페이지 단위 열람 — 긴 로그용. /문자열로 검색, G 끝으로, q 종료
head -n 20 파일앞 20줄
tail -n 20 파일뒤 20줄
tail -f 파일파일 끝을 실시간 추적 — 돌고 있는 계산 로그 감시
cat input.fdf # 제출 직전 입력 최종 확인
tail -f siesta.out # SCF 반복이 찍히는 것을 실시간으로 본다 (Ctrl-C로 종료)

tail -f는 계산이 정상 진행 중인지 확인하는 가장 기본적인 방법이다. 출력이 몇 분째 멈춰 있다면 무언가 잘못되었을 가능성이 크다.

검색 — grep

grep은 파일에서 패턴이 있는 줄을 뽑는다. 수천 줄에 달하는 계산 로그에서 원하는 수치·경고를 찾는 핵심 도구다.

grep -i "total energy" siesta.out # 대소문자 무시(-i)하고 에너지 라인 검색
grep "SCF cycle converged" siesta.out # 수렴 메시지 존재 확인
grep -in "error" siesta.out # 에러 검색, 줄 번호(-n)까지 표시
grep -c "scf:" siesta.out # SCF 반복 횟수 세기(-c)
grep -A 6 "TOTAL-FORCE" OUTCAR # 매칭 줄과 그 아래 6줄(-A)까지 — VASP 힘 블록
grep -r "MeshCutoff" scan/ # 디렉토리 전체(-r)에서 검색

자주 쓰는 옵션 — -i 대소문자 무시, -n 줄 번호, -c 개수, -A N/-B N 매칭 줄 아래/위 N줄 포함, -r 재귀, -v 매칭 안 되는 줄만.

스트림과 리다이렉트

모든 프로그램은 세 개의 스트림을 갖는다 — 표준 입력(stdin), 표준 출력(stdout), 표준 에러(stderr). 이 튜토리얼의 실행 명령이 정확히 이 구조다.

siesta < input.fdf > siesta.out
  • < input.fdf — 파일을 stdin으로 연결한다. SIESTA는 입력을 stdin으로 읽는 관례를 따른다.
  • > siesta.out — stdout을 파일로 보낸다(기존 내용은 덮어쓴다). >>는 덮어쓰지 않고 뒤에 이어 붙인다.
  • stderr는 위 명령에서 여전히 화면으로 나온다. 에러까지 같은 파일에 남기려면 2>&1을 붙인다 — "스트림 2번(stderr)을 1번(stdout)이 가는 곳으로 합쳐라"는 뜻이다.
mpirun -np 4 siesta < input.fdf > siesta.out 2>&1

MPI 실행이나 배치 잡에서는 라이브러리 에러·메모리 부족 메시지가 stderr로만 나오는 경우가 많으므로 2>&1을 붙이는 것이 안전하다.

파이프

|는 앞 명령의 stdout을 뒤 명령의 stdin으로 넘긴다. 작은 명령을 조립해 한 줄 분석을 만든다.

grep "scf:" siesta.out | wc -l # SCF 반복 줄 수 세기 (wc -l = 줄 개수)
grep "E0=" OSZICAR | tail -n 1 # VASP 마지막 이온 스텝 에너지만
grep "Total =" scan/*/siesta.out | sort # 스캔 결과를 케이스명 순으로 정렬

wc -l(줄 수), sort(정렬, -g는 수치 크기순), uniq(중복 제거)가 파이프의 단골 조각이다.

sed — 한 줄 치환

sed는 스트림 편집기다. 입력 파라미터 하나를 바꾼 사본을 만들 때 편집기를 열 필요가 없다.

sed 's/300. Ry/400. Ry/' input.fdf > input_400.fdf # 치환한 사본 생성
sed -i.bak 's/300. Ry/400. Ry/' input.fdf # 제자리 수정, 원본은 .bak으로 백업
diff input.fdf.bak input.fdf # 바뀐 줄만 확인

s/찾을것/바꿀것/ 문법이 기본이고, 줄 끝에 g를 붙이면 한 줄 안의 모든 매칭을 바꾼다. sed -i로 파일을 수정했다면 diff로 의도한 줄만 바뀌었는지 반드시 확인한다 — 패턴이 예상 밖의 줄에도 매칭되는 사고가 흔하다.

셸 변수와 for 루프 — 격자상수 스캔

변수는 이름=값(등호 양옆 공백 없음)으로 정의하고 $이름으로 참조한다. for 루프와 결합하면 파라미터 스캔을 자동화할 수 있다. 챕터 01input.fdf에서 cell 길이 5.160000을 자리표시자 __C__로 바꾼 template.fdf를 준비했다고 하자(원자 좌표는 Fractional로 바꿔 두면 cell과 함께 자동으로 스케일된다).

scan.sh
#!/bin/bash
# cell 길이 c 스캔 — template.fdf의 __C__ 를 실제 값으로 치환해 실행
for c in 5.00 5.08 5.16 5.24 5.32; do
dir=c_${c}
mkdir -p ${dir}
sed "s/__C__/${c}/" template.fdf > ${dir}/input.fdf
cp C.psml ${dir}/
(cd ${dir} && siesta < input.fdf > siesta.out)
echo "c = ${c} done"
done

괄호 ( ... )는 서브셸이라 안에서 cd해도 루프가 도는 위치는 바뀌지 않는다. 스캔이 끝나면 결과를 한 줄로 수확한다.

grep "Total =" c_*/siesta.out

아카이브와 전송 — tar, scp, rsync

tar czf ch01_results.tar.gz ch01-siesta-scf/ # 디렉토리를 압축 아카이브로 (c=생성, z=gzip, f=파일명)
tar xzf ch01_results.tar.gz # 풀기 (x=추출)
scp ch01_results.tar.gz user@server:~/work/ # 원격 서버로 복사
rsync -avz user@server:~/work/ch01/ ./ch01/ # 원격 디렉토리 동기화 회수

rsync는 이미 받은 파일을 건너뛰고 바뀐 부분만 전송하므로, 큰 계산 디렉토리를 반복해서 회수할 때 scp보다 낫다. -avz는 아카이브 모드(-a)+전송 목록 출력(-v)+압축 전송(-z)이다. 경로 끝의 / 유무에 따라 "디렉토리 안의 내용"인지 "디렉토리 자체"인지가 달라지므로 처음에는 -n(dry-run)으로 대상 목록을 먼저 확인하는 것이 안전하다.

ssh — 원격 계산 서버

ssh user@server.example.edu # 원격 셸 접속
ssh user@server.example.edu "ls work" # 접속 없이 원격 명령 한 줄 실행

~/.ssh/config에 호스트 별칭·키 설정을 등록해 두면 ssh myserver처럼 짧게 쓸 수 있다. 계정·호스트·인증 방식은 기관마다 다르므로 소속 기관의 안내를 따른다.

로그아웃해도 계산 유지 — nohup과 tmux

ssh 세션에서 그냥 실행한 계산은 접속이 끊기면 함께 종료된다. 두 가지 해법이 있다.

nohup mpirun -np 4 siesta < input.fdf > siesta.out 2>&1 &

nohup은 접속 종료 신호를 무시하게 하고, 끝의 &는 백그라운드로 보낸다. 로그아웃 후 다시 접속해 tail -f siesta.out으로 진행을 확인하면 된다.

tmux는 터미널 세션 자체를 서버에 남겨 두는 도구다.

tmux new -s calc # calc라는 이름의 세션 생성
# (세션 안에서 계산 실행)
# Ctrl-b 누른 뒤 d — 세션을 붙여 둔 채 빠져나오기(detach)
tmux attach -t calc # 재접속 후 세션 복귀

실행 중인 계산을 여러 개 띄워 두고 오가며 확인할 수 있어, 대화형으로 작업하는 계산 서버에서는 tmux 쪽이 편하다. 다만 정식 클러스터에서는 이 방식 대신 배치 스케줄러로 잡을 제출한다 — 챕터 12에서 다룬다.

실행 권한 — chmod +x

셸 스크립트는 실행 권한이 있어야 ./스크립트로 실행할 수 있다.

chmod +x scan.sh
./scan.sh

권한 없이 실행하면 "Permission denied"가 나온다. bash scan.sh처럼 인터프리터를 직접 불러도 되지만, 스크립트 첫 줄의 #!/bin/bash(shebang)와 실행 권한을 갖춰 두는 쪽이 표준 관례다.

자주 쓰는 조합

상황한 줄 명령
돌고 있는 계산 로그 실시간 확인tail -f siesta.out
SCF가 몇 번 돌았는지grep -c "scf:" siesta.out
SCF 수렴 여부 확인grep "SCF cycle converged" siesta.out
SIESTA 최종 에너지grep "Total =" siesta.out
VASP 마지막 이온 스텝 에너지grep "E0=" OSZICAR | tail -n 1
VASP 힘 블록 확인grep -A 6 "TOTAL-FORCE" OUTCAR
로그에서 에러·경고 찾기grep -in "error" siesta.out
최근에 갱신된 파일 확인ls -ltr
파라미터 스캔 결과 수확grep "Total =" c_*/siesta.out
입력 파라미터 한 줄 치환(백업 포함)sed -i.bak 's/300. Ry/400. Ry/' input.fdf
수정 확인diff input.fdf.bak input.fdf
결과 디렉토리 압축tar czf results.tar.gz ch01-siesta-scf/
서버에서 결과 회수rsync -avz user@server:~/work/ch01/ ./ch01/
로그아웃해도 계산 유지nohup mpirun -np 4 siesta < input.fdf > siesta.out 2>&1 &
디렉토리 용량 확인du -sh */

이 표의 명령이 손에 익으면 튜토리얼 본편에서 셸 때문에 막히는 일은 없다. 다음으로 SIESTA란 무엇인가에서 이 튜토리얼의 주력 코드를 개관한다.