입사 첫 달, 선배가 Nginx 설정을 바꾸라고 했습니다. SSH로 서버에 접속해 vim /etc/nginx/nginx.conf를 쳤습니다. 파일이 열렸습니다. 그런데 커서는 움직이는데 글자를 치면 알 수 없는 동작이 실행됩니다. 15분 동안 파일을 망가뜨리다가 결국 터미널을 강제 종료했습니다. 나중에 알고 보니 vim의 Normal 모드였습니다.
"vim을 못 나가서"가 검색어 밈이 된 데는 이유가 있습니다. vim은 직관에 반하지만, 어떤 서버에도 설치되어 있는 유일한 편집기입니다. 열고 → 수정하고 → 저장하고 → 나오는 4단계만 익히면 더 이상 겁낼 필요 없습니다.
텍스트 편집 기초 — vim과 nano
- 1nano를 열고 파일을 수정하고 저장·종료할 수 있다
- 2vim의 모드 시스템(Normal / Insert / Command)을 이해하고 텍스트를 입력할 수 있다
- 3vim에서 저장(:wq), 강제 종료(:q!), 실행 취소(u)를 사용할 수 있다
- 4자주 쓰는 vim 단축키(검색, 줄 삭제, 복사/붙여넣기)를 활용할 수 있다
- 5root 소유 설정 파일을 sudo로 안전하게 편집할 수 있다
vim --version | head -1VIM - Vi IMproved 버전 정보가 출력되면 준비 완료
nano --versionGNU nano 버전이 출력되면 준비 완료 (없으면 sudo apt install nano)
echo 'Hello Linux' > ~/practice.txt편집 실습에 사용할 파일입니다
nano — 처음이라면 nano부터
확대
vim을 처음 접하면 열자마자 나가는 방법을 몰라서 강제 종료하는 경험을 한 번씩 합니다. 설정 파일을 빨리 수정해야 하는 상황에서 편집기 조작법에 시간을 쓰는 건 비효율적입니다. nano는 학습 비용 없이 바로 쓸 수 있는 편집기입니다. 화면 하단에 단축키가 항상 표시되어 외울 필요가 없고, 일반 텍스트 편집기처럼 바로 입력할 수 있습니다.
# 파일 열기 (없으면 새 파일 생성)
nano ~/practice.txt
# root 권한 필요한 파일
sudo nano /etc/hosts
nano 필수 단축키 (^는 Ctrl):
| 단축키 | 기능 |
|---|---|
Ctrl+O | 저장 (Write Out) |
Ctrl+X | 종료 (저장 여부 확인) |
Ctrl+K | 현재 줄 잘라내기 |
Ctrl+U | 붙여넣기 |
Ctrl+W | 검색 |
Ctrl+\ | 검색 후 치환 |
저장 후 종료 흐름: Ctrl+O → Enter → Ctrl+X
vim 모드 시스템 — 이것만 이해하면 됩니다
vim이 갑자기 서버에서 유일한 편집기일 때가 있습니다. Alpine 기반 Docker 컨테이너, 최소 설치 이미지, 구형 서버 — 이런 환경엔 nano가 없습니다. vim을 못 쓰면 파일을 열고 나서 종료도 못 하는 상황이 됩니다. vim이 다른 편집기와 가장 다른 점은 '모드'입니다. 이 개념만 이해하면 vim이 왜 그렇게 동작하는지 납득이 가고, 처음 보는 키 입력에도 당황하지 않게 됩니다.
vim은 Normal 모드로 시작합니다. 텍스트 입력 전에 반드시 Insert 모드로 전환해야 합니다.
확대
처음에는 이 4가지만 기억하면 충분합니다:
| 상황 | 누를 키 |
|---|---|
| 텍스트 입력하고 싶다 | i (insert) |
| 입력 그만하고 명령 쓰고 싶다 | ESC |
| 저장하고 나가고 싶다 | ESC → :wq → Enter |
| 저장 없이 나가고 싶다 | ESC → :q! → Enter |
vim 자주 쓰는 단축키 — Normal 모드
확대
처음에는 이동(hjkl)과 삭제(dd), 취소(u)만 알면 설정 파일 수정 수준은 문제없습니다. 검색과 치환은 반복 작업이 생길 때 익혀도 늦지 않습니다.
기본 이동
h j k l ← ↓ ↑ →
0 / $ 줄 맨 앞 / 맨 끝
gg / G 파일 맨 위 / 맨 아래
:42 42번 줄로 이동
편집
dd 현재 줄 삭제 (잘라내기)
yy 현재 줄 복사
p 붙여넣기 (커서 아래)
u 실행 취소 (undo)
Ctrl+R 다시 실행 (redo)
검색 & 치환
/단어 아래 방향으로 검색 (n으로 다음)
:%s/old/new/g 파일 전체 치환
nano를 열고 텍스트를 추가한 뒤 저장하고 종료하는 전체 흐름을 연습합니다.
# 실습 파일 열기
nano ~/practice.txt
파일이 열리면:
- 커서가 있는 위치에서 바로 타이핑합니다
- 새 줄에
Server: ubuntu-lab을 추가합니다 Ctrl+O→ Enter 로 저장합니다Ctrl+X로 종료합니다
# 저장됐는지 확인
cat ~/practice.txt
Hello Linux
Server: ubuntu-lab
nano ~/practice.txt- 먼저 화면 하단 2줄을 확인 — "^G Help ^O Write ^X Exit" 형식의 단축키 안내가 보이면 nano가 정상 실행된 것. 이 안내가 없으면 다른 편집기(vi/vim)가 열린 것
- Ctrl+O 입력 후 화면 하단에 "File Name to Write: ~/practice.txt" 프롬프트가 나타나고 Enter 를 눌렀을 때 "[ Wrote N lines ]" 메시지가 표시되어야 정상 저장 — 메시지 없이 그냥 넘어가면 저장이 안 된 것
- cat ~/practice.txt 결과에서 방금 추가한 줄이 마지막에 보이면 저장 성공 — 줄이 없으면 Ctrl+O 없이 Ctrl+X 로만 종료한 것(저장 여부 묻는 프롬프트에서 "N"을 눌렀을 가능성)
vim을 열고 → Insert 모드 진입 → 텍스트 입력 → Normal 모드 복귀 → 저장 종료 흐름을 직접 경험합니다.
vim ~/practice.txt
파일이 열리면 (Normal 모드 상태):
G를 눌러 파일 맨 아래로 이동합니다o를 눌러 새 줄을 만들고 Insert 모드로 진입합니다Edited by vim을 입력합니다ESC를 눌러 Normal 모드로 복귀합니다:wq를 입력하고 Enter 를 눌러 저장 종료합니다
# 결과 확인
cat ~/practice.txt
Hello Linux
Server: ubuntu-lab
Edited by vim
vim ~/practice.txt- 먼저 화면 맨 아래를 확인 — "-- INSERT --" 가 표시되면 입력 가능한 Insert 모드, 아무 표시가 없으면 Normal 모드. 모드 확인 없이 타이핑하다가 예상치 못한 동작이 실행되는 경우 대부분 Normal 모드인 채로 입력한 것
- :wq 입력 전 반드시 ESC 를 눌러 "-- INSERT --" 표시가 사라졌는지 확인 — 표시가 남아있는 상태에서 ":wq" 를 타이핑하면 문서에 ":wq" 문자열이 삽입됨. ESC 후 화면 아래에 ":" 가 입력되어야 Command 모드 진입
- 저장 후 cat ~/practice.txt 에서 "Edited by vim" 줄이 마지막에 보이고 줄 수가 3개이면 정상 완료 — 줄이 없으면 :q! 로 저장 없이 나간 것. 실수 시 다시 vim 열고 G → o → 입력 → ESC → :wq 반복
실무에서 가장 자주 편집하는 설정 파일 중 하나인 /etc/hosts에 항목을 추가합니다.
# 현재 내용 먼저 확인
cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 myserver
::1 localhost ip6-localhost
# nano로 열기 (sudo 필수 — root 소유 파일)
sudo nano /etc/hosts
파일 맨 아래에 다음 줄을 추가합니다:
192.168.1.10 db-server
Ctrl+O → Enter → Ctrl+X 로 저장 후 종료합니다.
# 추가됐는지 확인
grep db-server /etc/hosts
192.168.1.10 db-server
sudo nano /etc/hosts- 먼저 nano 상단 타이틀 바에 표시된 파일명이 "/etc/hosts" 이고 sudo로 열었는지 확인 — sudo 없이 열면 수정은 가능하지만 Ctrl+O 저장 시 "Error writing /etc/hosts: Permission denied" 가 뜸
- grep db-server /etc/hosts 결과에서 "192.168.1.10 db-server" 줄이 정확히 출력되어야 정상 — 공백이 탭인지 스페이스인지는 무관하지만 IP와 호스트명 순서가 바뀌어 있으면 이름 해석 실패
- 실습 완료 후 ping db-server -c 1 을 실행하면 192.168.1.10 으로 PING 시도가 가고 응답이 없어도 IP 해석이 된 것 — "ping: db-server: Name or service not known" 이 나오면 /etc/hosts 저장이 안 된 것
상황: vim /etc/nginx/nginx.conf 로 파일을 열고 수정한 뒤 :wq 로 저장하려는데 위 오류가 납니다. 분명히 수정이 됐는데 저장이 안 됩니다.
원인: sudo 없이 root 소유 파일을 열었기 때문입니다. vim은 파일을 열 수는 있지만 쓰기 권한이 없어 저장을 거부합니다.
진단:
# 파일 소유자 확인
ls -la /etc/nginx/nginx.conf
-rw-r--r-- 1 root root 1490 Sep 15 10:23 /etc/nginx/nginx.conf
소유자가 root 이고 현재 사용자가 일반 사용자이면 쓰기 권한이 없습니다.
해결:
# 방법 1: 이미 수정한 내용 그대로 sudo로 저장 (닫지 않아도 됨)
# Normal 모드에서 실행:
:w !sudo tee %
# 비밀번호 입력 후 저장 완료 → :q! 로 종료
# 방법 2 (권장): 처음부터 sudo로 열기
# 현재 vim을 :q! 로 닫고 재실행
sudo vim /etc/nginx/nginx.conf
상황: vim을 열었는데 화면이 이상하거나, 키를 눌러도 반응이 없거나, ^M 같은 이상한 문자가 입력됩니다. 또는 vim 세션 안에서 완전히 멈춘 것 같습니다.
원인: 가장 흔한 원인 두 가지입니다. 첫째, Ctrl+S 를 눌러 터미널 출력이 일시 정지된 상태. 둘째, 현재 모드를 모르는 채로 키를 눌러 예상치 못한 동작이 실행된 상태.
진단:
# 터미널 입력이 아예 안 된다면 먼저 Ctrl+Q 시도
# (Ctrl+S = 터미널 출력 정지, Ctrl+Q = 재개)
# vim 화면에서 현재 모드 확인
# 하단에 -- INSERT -- 가 보이면 Insert 모드
# 아무 표시 없으면 Normal 모드
# : 로 시작하는 입력창이 보이면 Command 모드
해결:
# 1. ESC 를 2~3번 눌러 Normal 모드로 확실히 복귀
# 2. 수정 내용을 살리고 싶으면:
:wq
# 3. 수정 내용을 포기하고 나가고 싶으면:
:q!
# 4. 아무것도 안 된다면 먼저 현재 사용자의 vim PID만 확인합니다.
# ps -u "$USER" -o pid,comm,args | grep '[v]im'
# 정말 필요한 경우 확인한 단일 PID에만 `kill <확인한-PID>`를 실행합니다.
# pgrep 결과 전체 종료·killall은 다른 편집 세션까지 끊을 수 있어 사용하지 않습니다.
심화 — 저장 전에 세션이 죽으면 편집은 어디로 가나
심화: vim은 편집 내용을 어떻게 지키나 — 스왑 파일(.swp)의 정체
vim으로 파일을 열면 vim은 원본을 곧바로 고치지 않습니다. 내용을 메모리 버퍼로 읽어 들여 거기서 편집하고, 동시에 스왑 파일이라는 숨김 파일에 변경분을 계속 기록합니다. 이 구조를 알면 세션이 끊겨도 편집이 사라지지 않는 이유와, 다음 날 뜨는 낯선 경고의 정체를 함께 이해할 수 있습니다.
- 스왑 파일이란: 원본과 같은 디렉토리에
.파일명.swp(예:.nginx.conf.swp) 형태의 숨김 파일로 생깁니다. vim은 편집하는 동안 여기에 변경을 계속 써 둡니다. - 목적은 크래시 복구: SSH가 끊기거나 서버 전원이 나가도, 스왑 파일에 남은 기록으로 미저장 편집을 되살릴 수 있습니다. 저장을 못 하고 죽어도 완전히 날아가지 않는 이유가 이것입니다.
- 정상 종료 시 사라진다:
:wq나:q로 제대로 나가면 스왑 파일은 더 필요 없으므로 vim이 자동으로 지웁니다. 그래서 평소엔 이 파일을 볼 일이 없습니다. - 동시 편집 감지에도 쓰인다: 같은 파일을 다른 사람이 이미 열어 스왑 파일이 존재하면, vim은 새로 여는 사람에게 경고해 두 명이 모르고 같은 파일을 덮어쓰는 사고를 막아 줍니다.
- 한계·함정: 스왑은 원본과 같은 위치에 생기므로 그 디렉토리에 쓰기 권한이 없으면 스왑 생성 실패 경고가 뜹니다. 또 비정상 종료로 남은 '고아' 스왑 파일은 자동으로 청소되지 않아, 다음에 그 파일을 열 때 사람이 판단해 처리해야 합니다.
# 숨김 스왑 파일 확인 (원본과 같은 디렉토리)
ls -a /etc/nginx/ | grep swp
# .nginx.conf.swp ← 지난 세션이 비정상 종료돼 남은 흔적
정리하면 스왑 파일은 vim이 조용히 켜 두는 자동 안전망이고, 남아 있는 스왑 파일은 '지난번에 곱게 못 나갔다'는 기록입니다.
상황: 어제 sudo vim /etc/nginx/nginx.conf로 설정을 고치던 중 Wi-Fi가 끊겨 SSH 세션이 통째로 죽었습니다. 오늘 다시 같은 파일을 열자 편집 화면 대신 E325 경고와 스왑 파일이 발견됐다는 안내, 그리고 [O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort 선택지가 뜹니다.
원인: 어제 vim이 :wq로 정상 종료되지 못해 스왑 파일(.nginx.conf.swp)이 지워지지 않고 남았습니다. vim은 파일을 열 때 스왑 파일을 발견하면 두 가지 중 하나로 봅니다 — 지난 세션이 비정상 종료됐거나, 다른 누군가가 지금 그 파일을 편집 중이거나. 둘 다 그냥 덮어쓰면 위험하므로 사용자에게 판단을 넘깁니다.
진단:
# 정말 다른 세션이 편집 중인지 먼저 확인 (고아 스왑인지 구분)
ps aux | grep '[v]im.*nginx.conf'
# 스왑 파일의 수정 시각으로 언제 중단됐는지 가늠
ls -la /etc/nginx/.nginx.conf.swp
실행 중인 vim이 없으면 어제 끊긴 세션이 남긴 '고아' 스왑 파일입니다. 실행 중인 vim이 있으면 다른 사람이 편집 중이므로 함부로 저장하면 안 됩니다.
해결:
# 미저장 편집을 살리는 경우: 프롬프트에서 R 입력
# → 버퍼에 어제 내용이 복구됨. 원본과 비교해 이상 없으면 :wq 로 저장
# 저장까지 끝났으면 남은 스왑 파일을 직접 삭제 (자동으로 안 지워질 수 있음)
sudo rm /etc/nginx/.nginx.conf.swp
복구할 내용이 없다고 판단되면 프롬프트에서 D로 스왑을 지우고 깨끗하게 다시 편집합니다. 반대로 다른 세션이 실제로 편집 중이었다면 O(Read-Only)로 열어 충돌을 피하세요. 핵심은 스왑 파일을 무작정 지우기 전에 '고아인지 활성인지'를 먼저 가리는 것입니다.
편집기는 "도구"이고 진짜 실력은 편집한 설정이 맞는지 검증하는 습관입니다. 다음 모듈에서는 파일·디렉터리 권한(rwx, 소유자/그룹)을 다뤄, 방금 편집한 설정 파일을 "누가 읽고 쓸 수 있는지"까지 통제하는 법을 배웁니다.
큰 파일을 vi/vim으로 빠르게 훑기 — gg·G·/검색·읽기 전용
편집기를 여는 이유는 고치려고보다 빠르게 훑고 검색하려고일 때가 더 많습니다. vi/vim의 이동·검색 키를 알면 수천 줄짜리 설정·로그에서도 원하는 지점으로 즉시 점프할 수 있고, 이 키들은 뒤에서 로그를 볼 때 쓰는 less 페이저에서도 거의 그대로 통합니다.
- 맨 위·맨 아래:
gg(첫 줄) /G(마지막 줄). 로그는 끝이 최신이라 열자마자G로 내려가는 습관이 좋습니다. - 줄 번호로 점프:
:42처럼:줄번호. 에러 메시지가 "line 42"를 가리키면 바로 그 줄로 갑니다.:set number(짧게:set nu)로 줄 번호를 켜 둡니다. - 검색:
/에러패턴입력 후 Enter →n(다음 매치) /N(이전 매치). 위 방향 검색은?패턴. - 페이지 이동:
Ctrl+f(한 화면 아래) /Ctrl+b(한 화면 위), 반 화면은Ctrl+d/Ctrl+u. - 실수 편집 방지: 볼 목적이면
vim -R 파일또는view 파일로 읽기 전용으로 엽니다. 프로덕션 설정을 무심코 고쳐 저장하는 사고를 막습니다.
핵심은 gg·G·/·n이 vi·vim·less에서 공통이라는 점입니다. 한 번 익히면 편집기든 페이저든 같은 손놀림으로 파일을 넘나듭니다.
명령어·단축키 빠른 참조
서버에 항상 있는 기본 편집기는 vi입니다. 대부분의 리눅스에서 vi는 vim(vi improved)으로 연결돼 있어 아래 명령이 그대로 통하고, nano는 더 쉬운 대안입니다. 이 모듈에서 다룬 것만 모았습니다.
| 명령어/단축키 | 편집기 | 용도 |
|---|---|---|
vi 파일 / vim 파일 | vi·vim | 파일 열기 (대개 vi는 vim 심볼릭 링크) |
vim -R / view 파일 | vi·vim | 읽기 전용으로 열기(대용량 로그 조회·실수 편집 방지) |
i / o | vi·vim | 입력(Insert) 모드 진입 — 커서 앞 / 아랫줄에 새 줄 |
Esc | vi·vim | 입력 모드에서 명령(Normal) 모드로 빠져나오기 |
gg / G | vi·vim | 파일 맨 위 / 맨 아래로 이동(로그는 G로 최신부터) |
:N (예: :42) | vi·vim | N번째 줄로 점프(:set nu로 줄 번호 표시) |
/패턴 → n / N | vi·vim | 아래로 검색 후 다음 / 이전 매치로 이동(위로는 ?패턴) |
Ctrl+f / Ctrl+b | vi·vim | 한 화면 아래 / 위로(페이지 넘김) |
:w / :wq | vi·vim | 저장 / 저장 후 종료 |
:q! | vi·vim | 저장하지 않고 강제 종료(편집 취소) |
dd / u | vi·vim | 현재 줄 삭제 / 직전 편집 실행 취소(undo) |
:%s/old/new/g | vi·vim | 파일 전체에서 old를 new로 일괄 치환 |
nano 파일 | nano | 쉬운 편집기로 열기 |
Ctrl+O / Ctrl+X | nano | 저장(Write Out) / 종료 |
Ctrl+W / Ctrl+K | nano | 검색 / 현재 줄 잘라내기 |
관련 모듈로 더 깊이:
- 원격 리눅스 서버 안전 접속과 절대 무너지지 않는 기본 명령어 — 편집기를 띄우는 셸 기본기와 명령 입력 흐름
- chmod/chown으로 파일 읽기·쓰기·실행 권한 완벽 제어 — 편집한 설정 파일을 누가 읽고 쓸 수 있는지 통제하는 법
- grep/awk/sed로 거대한 로그 파일에서 원하는 행 찾기 — vim 없이 grep·sed로 파일을 비대화식으로 수정하는 법
다음 모듈에서는 사용자와 그룹 관리 — useradd, usermod, sudo 권한 설정으로 서버 접근 제어를 다룹니다.