이 장의 예제는 ORCA 가이드의 물 분자 계산 두 개를 쓴다.
~/proj/h2o-sp에는 B3LYP/def2-SVP 단일점 계산이, ~/proj/h2o-opt에는 구조 최적화와 진동수 계산이 들어 있다.
cat과 less
cat은 파일 내용을 화면에 한꺼번에 쏟는다. 입력 파일처럼 짧은 파일을 볼 때 쓴다.
$ cd ~/proj/h2o-sp
$ cat water.inp
# Single-point energy - water, B3LYP/def2-SVP
! B3LYP def2-SVP
* xyz 0 1
O 0.000000 0.000000 0.119262
H 0.000000 0.763239 -0.477047
H 0.000000 -0.763239 -0.477047
*
출력 파일은 사정이 다르다. 이 단일점 계산의 water.out도 981줄이라 cat으로 열면 앞부분이 순식간에 지나간다.
긴 파일은 less로 한 화면씩 본다.
$ less water.out
| 키 (less 안에서) | 하는 일 |
|---|---|
Space / b | 한 화면 앞으로 / 뒤로 |
↑ ↓ | 한 줄씩 |
g / G | 파일 처음 / 끝 |
/단어 + Enter | 아래로 검색. n은 다음, N은 이전 결과 |
?단어 + Enter | 위로 검색 |
q | 나가기 |
ORCA 출력에서 G로 끝으로 간 다음 ?FINAL SINGLE로 위쪽을 검색하면 마지막 에너지로 바로 간다.
less는 파일을 읽기만 하므로 실수로 내용을 바꿀 걱정이 없다.
head, tail, wc
head는 앞의 몇 줄, tail은 뒤의 몇 줄을 보여 준다. -n으로 줄 수를 정한다(기본 10줄).
$ tail -n 2 water.out
****ORCA TERMINATED NORMALLY****
TOTAL RUN TIME: 0 days 0 hours 0 minutes 2 seconds 657 msec
$ wc -l water.out ../h2o-opt/water.out
981 water.out
3623 ../h2o-opt/water.out
4604 total
ORCA는 정상 종료하면 끝에 ORCA TERMINATED NORMALLY를 찍는다. 계산이 끝났는지 볼 때 가장 먼저 tail을 친다.
wc -l은 줄 수를 센다. 출력 파일 길이가 다른 계산보다 유난히 짧으면 중간에 죽었을 가능성이 크다.
돌아가는 계산 지켜보기
tail -f는 파일 끝을 보여 준 뒤 종료하지 않고 기다리다가, 새 줄이 쓰이면 바로 화면에 붙인다.
계산이 SCF를 몇 번째 돌고 있는지 실시간으로 볼 수 있다. Ctrl+C로 빠져나오며, 계산 자체는 멈추지 않는다.
$ tail -f water.out
grep으로 줄 찾기
grep '패턴' 파일은 패턴이 들어 있는 줄만 출력한다. 출력 파일에서 숫자 하나를 찾을 때 less보다 훨씬 빠르다.
공백이 든 패턴은 따옴표로 감싼다.
$ grep 'FINAL SINGLE POINT ENERGY' water.out
FINAL SINGLE POINT ENERGY -76.321274411145
$ grep 'FINAL SINGLE POINT ENERGY' ../h2o-opt/water.out
FINAL SINGLE POINT ENERGY -76.426286364586
FINAL SINGLE POINT ENERGY -76.426353431114
FINAL SINGLE POINT ENERGY -76.426364583348
FINAL SINGLE POINT ENERGY -76.426366351564
FINAL SINGLE POINT ENERGY -76.426369457144
구조 최적화는 매 단계 에너지를 찍으므로 여러 줄이 나온다. 에너지가 조금씩 내려가는 것이 보이고, 마지막 줄이 최적화된 구조의 에너지다 (단위는 Hartree).
| 옵션 | 하는 일 |
|---|---|
-i | 대소문자 무시 |
-n | 줄 번호 함께 출력 |
-c | 맞는 줄 수만 출력 |
-l | 맞는 줄이 있는 파일 이름만 출력 |
-r | 디렉터리 안을 재귀적으로 검색 |
-v | 맞지 않는 줄만 출력 |
$ grep -n 'TERMINATED NORMALLY' water.out
980: ****ORCA TERMINATED NORMALLY****
$ grep -c 'GEOMETRY OPTIMIZATION CYCLE' ../h2o-opt/water.out
4
$ grep -l 'TERMINATED NORMALLY' ~/proj/*/water.out
/home/kim/proj/h2o-opt/water.out
/home/kim/proj/h2o-sp/water.out
마지막 명령은 정상 종료한 계산의 목록이다. 계산이 수십 개일 때 이 한 줄로 실패한 것을 추려 낼 수 있다.
정규 표현식, sed, awk로 숫자만 뽑는 법은 셸 가이드의
grep · sed · awk와 출력 파일에서 값 뽑기에 있다.
diff로 비교하기
두 파일에서 다른 줄만 보여 준다. 입력 파일 두 개가 어디서 다른지 확인할 때 쓴다.
$ diff ~/proj/h2o-sp/water.inp ~/proj/h2o-opt/water.inp
1,2c1,2
< # Single-point energy - water, B3LYP/def2-SVP
< ! B3LYP def2-SVP
---
> # Geometry optimization + frequencies + thermochemistry - water
> ! B3LYP D4 def2-TZVP TightOpt Freq
1,2c1,2는 첫 파일의 1~2행이 둘째 파일의 1~2행으로 바뀌었다(change)는 뜻이다. <는 첫 파일, >는 둘째 파일의 줄이다.
좌표는 같고 방법과 기저만 다르다는 것을 한눈에 알 수 있다. 아무것도 출력되지 않으면 두 파일이 똑같다.
리다이렉션과 파이프
명령의 출력은 기본적으로 화면으로 간다. 이것을 파일로 돌리거나 다른 명령의 입력으로 넘길 수 있다. 출력에는 정상 출력(stdout)과 오류 메시지(stderr) 두 갈래가 있다.
| 기호 | 하는 일 |
|---|---|
cmd > file | 출력을 파일에 쓴다. 파일이 있으면 내용을 지우고 새로 쓴다. |
cmd >> file | 파일 끝에 덧붙인다. |
cmd 2> file | 오류 메시지만 파일로 |
cmd > file 2>&1 | 정상 출력과 오류를 같은 파일로 |
cmd1 | cmd2 | 파이프. 앞 명령의 출력을 뒤 명령의 입력으로 |
$ grep 'FINAL SINGLE POINT ENERGY' ../h2o-opt/water.out | tail -n 1
FINAL SINGLE POINT ENERGY -76.426369457144
$ echo '# first line' > notes.txt
$ echo '# second line' >> notes.txt
$ cat notes.txt
# first line
# second line
$ ls water.inp nothing.out > list.txt 2>&1
$ cat list.txt
ls: cannot access 'nothing.out': No such file or directory
water.inp
계산 프로그램을 돌릴 때도 같은 기호를 쓴다. ORCA는 결과를 화면(stdout)에 쓰므로 orca water.inp > water.out처럼 파일로 받는다.
orca water.inp > water.out을 다시 실행하면 이전 water.out은 사라진다. 며칠 걸린 계산의 출력도 마찬가지다.
다시 돌리기 전에 옛 출력의 이름을 바꿔 두거나 새 디렉터리에서 돌린다.
set -o noclobber를 켜 두면 >가 기존 파일을 덮어쓰려 할 때 오류를 낸다.
nano
터미널 안에서 쓰는 편집기 중 가장 쉽다. nano water.inp로 열고, 화살표로 움직이며 그냥 타이핑한다.
화면 아래에 단축키가 나오는데 ^는 Ctrl이라는 뜻이다.
| 키 | 하는 일 |
|---|---|
Ctrl+O, Enter | 저장 |
Ctrl+X | 나가기 (저장 안 했으면 물어본다) |
Ctrl+W | 검색 |
Ctrl+K / Ctrl+U | 줄 잘라내기 / 붙여넣기 |
vim에서 살아남기
클러스터에 따라 nano가 없고 vim만 있기도 하고, git commit 같은 명령이 vim을 띄우기도 한다.
vim은 모드가 있어서 처음 열었을 때는 타이핑이 글자 입력이 아니라 명령으로 해석된다. 최소한 이것만 알면 된다.
| 키 | 하는 일 |
|---|---|
i | 입력 모드로 들어가기. 화면 아래에 -- INSERT --가 보이면 글자를 칠 수 있다. |
Esc | 입력 모드에서 나오기. 뭔가 이상하면 일단 Esc를 누른다. |
:wq + Enter | 저장하고 나가기 |
:q! + Enter | 저장하지 않고 나가기 |
/단어 + Enter | 검색 (less와 같음) |
u | 되돌리기 |
로컬에서 긴 파일을 편집할 때는 VS Code 같은 그래픽 편집기가 편하다. VS Code의 Remote 확장을 쓰면 WSL이나 클러스터의 파일도 직접 연다 (10장).
Windows 줄 끝 문자
Linux는 줄 끝에 LF 문자 하나를 쓰고, Windows는 CR+LF 두 개를 쓴다. Windows 메모장 등에서 만든 파일을 클러스터로 옮기면
줄마다 보이지 않는 CR(\r)이 붙어 있다. 이것 때문에 스크립트가 이상한 오류를 낸다.
$ ./run.sh
bash: ./run.sh: /bin/bash^M: bad interpreter: No such file or directory
$ bash run.sh
run.sh: line 2: cd: $'/home/kim/proj/h2o-opt\r': No such file or directory
done
^M과 \r이 CR이다. 디렉터리는 분명히 있는데 없다고 한다면 이것부터 의심한다.
계산 프로그램도 입력 파일의 CR 때문에 키워드나 파일 이름을 잘못 읽을 수 있다. file로 확인하고 dos2unix로 고친다.
$ file run.sh water.inp
run.sh: Bourne-Again shell script, ASCII text executable, with CRLF line terminators
water.inp: ASCII text, with CRLF line terminators
$ cat -A water.inp
! B3LYP def2-SVP^M$
* xyzfile 0 1 water.xyz^M$
# 고치기 (sudo apt install dos2unix)
$ dos2unix run.sh water.inp
dos2unix: converting file run.sh to Unix format...
dos2unix: converting file water.inp to Unix format...
$ file run.sh water.inp
run.sh: Bourne-Again shell script, ASCII text executable
water.inp: ASCII text
cat -A는 보이지 않는 문자를 드러낸다. 줄 끝의 $가 LF, 그 앞의 ^M이 CR이다.
클러스터에 dos2unix가 없으면 sed -i 's/\r$//' run.sh로 같은 일을 한다. VS Code나 Notepad++를 쓰면 오른쪽 아래 상태 표시줄에서 줄 끝을 LF로 바꿔 저장할 수 있다.