이 장의 명령은 모두 노트북에서 실행한다. 원격 쪽 경로는 호스트:경로로 쓰고,
호스트 자리에는 06장에서 만든 별명 vanda를 쓴다. 별명이 없다면
e0123456@vanda.nus.edu.sg:경로로 풀어 쓰면 된다.
scp
scp는 cp의 원격판이다. 형식은 scp 원본 대상이고, 둘 중 한쪽에 호스트가 붙는다.
# 올리기: 노트북 → 클러스터
$ scp h2o.inp h2o.xyz vanda:~/proj/h2o-opt/
# 받기: 클러스터 → 현재 디렉터리(.)
$ scp vanda:~/proj/h2o-opt/h2o.out .
# 디렉터리째 받기
$ scp -r vanda:~/proj/h2o-opt .
원격 경로의 ~는 클러스터의 홈 디렉터리다. 콜론(:)을 빠뜨리면 vanda라는 이름의 로컬 파일로
복사되니 주의한다. 파일 몇 개를 한 번 옮기는 데는 scp로 충분하다.
rsync
rsync는 양쪽을 비교해서 없거나 바뀐 파일만 보낸다. 계산이 돌아가는 동안 출력을 여러 번 받아 볼 때,
전송이 중간에 끊겨 다시 시작할 때 차이가 크다. 대부분의 클러스터에 깔려 있고, macOS와 WSL에도 기본으로 있거나 바로 설치된다.
$ rsync -avhP vanda:~/proj/h2o-opt/ ~/proj/h2o-opt/
| 옵션 | 뜻 |
|---|---|
-a | archive. 하위 디렉터리까지, 권한과 수정 시각을 유지하며 복사 |
-v | 옮기는 파일 이름을 보여 준다 |
-h | 크기를 2.00M처럼 읽기 쉽게 |
-P | 진행률 표시, 끊긴 파일은 이어 받기 |
-n, --dry-run | 실제로 옮기지 않고 무엇을 옮길지만 보여 준다 |
같은 명령을 두 번 실행하면 두 번째는 바뀐 것이 없어서 거의 즉시 끝난다.
sending incremental file list
sent 233 bytes received 14 bytes 494.00 bytes/sec
total size is 600.17K speedup is 2,429.83
끝의 슬래시
rsync에서 가장 헷갈리는 부분이다. 원본 경로 끝에 /가 있느냐에 따라 결과가 다르다.
아래는 같은 디렉터리를 슬래시 없이, 그리고 슬래시를 붙여 복사한 실제 결과다.
$ rsync -avh proj/h2o-opt a/
sending incremental file list
h2o-opt/
h2o-opt/h2o.gbw
h2o-opt/h2o.inp
h2o-opt/h2o.out
...
$ rsync -avh proj/h2o-opt/ b/
sending incremental file list
h2o.gbw
h2o.inp
h2o.out
...
$ tree a b
a
└── h2o-opt
├── h2o.gbw
├── h2o.inp
...
b
├── h2o.gbw
├── h2o.inp
...
슬래시가 없으면 디렉터리 자체(a/h2o-opt/)가 복사되고, 있으면 디렉터리의 내용물이 대상에 바로 풀린다.
대상 쪽 슬래시는 결과에 영향이 없다. 헷갈리면 양쪽에 슬래시를 붙이고 대상 디렉터리 이름을 원본과 같게 쓰는 습관을 들인다.
rsync -avh 원본/ 대상/은 "원본의 내용을 대상에 맞춰라"로 읽힌다.
--delete를 붙이면 원본에 없는 파일을 대상에서 지운다. 슬래시를 잘못 붙인 채 쓰면 엉뚱한 디렉터리가 비워질 수 있다.
쓸 때는 반드시 -n으로 먼저 돌려 목록을 확인한다.
필요한 파일만 받기
계산 디렉터리 여러 개에서 .out과 .xyz만 받고 싶을 때가 많다. --include와 --exclude를 조합한다.
규칙은 앞에서부터 차례로 적용되고, 처음 맞는 규칙이 이긴다.
$ rsync -avh --dry-run --include='*/' --include='*.out' --include='*.xyz' --exclude='*' \
vanda:~/proj/ ~/proj/
sending incremental file list
created directory /home/kim/proj
./
h2o-opt/
h2o-opt/h2o.out
h2o-opt/h2o.xyz
h2o-opt/h2o_trj.xyz
nh3-opt/
nh3-opt/nh3.out
nh3-opt/nh3.xyz
nh3-opt/nh3_trj.xyz
sent 264 bytes received 69 bytes 666.00 bytes/sec
total size is 600.17K speedup is 1,802.31 (DRY RUN)
--include='*/'는 하위 디렉터리 안으로 들어가게 하고, 두 패턴에 맞는 파일은 받고, --exclude='*'가 나머지를 모두 뺀다.
순서를 바꿔 --exclude='*'를 앞에 두면 아무것도 받지 않는다. 패턴은 작은따옴표로 감싸야 셸이 먼저 펼치지 않는다.
목록이 맞으면 --dry-run을 빼고 다시 실행한다.
반대로 큰 파일 몇 종류만 빼고 다 받을 때는 --exclude만 쓴다.
$ rsync -avhP --exclude='*.gbw' --exclude='*.tmp' vanda:~/proj/h2o-opt/ ~/proj/h2o-opt/
무엇을 옮기지 않을까
계산 프로그램은 결과 외에도 큰 중간 파일을 남긴다. ORCA의 .gbw(파동함수)와 .tmp, Quantum ESPRESSO의
outdir 안 파동함수 파일, LAMMPS의 대용량 덤프 파일이 그렇다. 몇 GB씩 되기도 하고, 분석에는 대개 필요 없다.
필요한 것은 보통 출력 텍스트(.out, log.lammps)와 구조(.xyz)다.
옮기기 전에 클러스터에서 크기부터 본다. du -sh는 디렉터리별 용량을 알려 준다.
$ du -sh proj/*
7.0M proj/h2o-opt
7.0M proj/nh3-opt
.gbw는 다음 계산의 초기 추정으로 쓸 수 있으니, 받지 않더라도 클러스터에서는 계산이 완전히 끝날 때까지 지우지 않는 편이 안전하다.
작은 파일이 많을 때: tar
파일 수천 개를 하나씩 보내면 파일마다 드는 오버헤드 때문에 느리다. 클러스터에서 tar로 한 파일로 묶고 압축해서 받은 뒤 푼다.
# 클러스터에서: 큰 중간 파일은 빼고 묶기
$ tar czf h2o-opt.tar.gz --exclude='*.gbw' --exclude='*.tmp' h2o-opt
$ tar tzf h2o-opt.tar.gz
h2o-opt/
h2o-opt/h2o_trj.xyz
h2o-opt/h2o.out
h2o-opt/h2o.inp
h2o-opt/h2o.xyz
# 노트북에서: 받고 풀기
$ rsync -avhP vanda:~/proj/h2o-opt.tar.gz .
$ tar xzf h2o-opt.tar.gz
c는 만들기, t는 목록 보기, x는 풀기, z는 gzip 압축, f는 뒤에 파일 이름이 온다는 뜻이다.
풀기 전에 tar tzf로 안을 보면 현재 디렉터리에 파일이 흩어지는 일을 막을 수 있다. 출력 텍스트는 압축이 잘 되는 편이다.
GUI 프로그램
파일을 끌어다 놓는 쪽이 편하다면 SFTP 클라이언트를 쓴다. 모두 ssh 위에서 동작하므로 같은 계정과 키로 접속한다.
| 프로그램 | 운영체제 | 비고 |
|---|---|---|
| WinSCP | Windows | PuTTY 형식 키(.ppk)로 변환해서 쓰기도 한다 |
| FileZilla | Windows, macOS, Linux | 프로토콜을 SFTP로 고른다 |
| Cyberduck | Windows, macOS | ~/.ssh/config의 별명을 읽는다 |
GUI로는 필터링과 이어 받기가 번거롭다. 계산 디렉터리 여러 개를 정기적으로 받는다면 rsync 명령 한 줄을 스크립트로 저장해 두는 편이 낫다 (셸 스크립팅 가이드).