1. Vi/Vim

모드 (Mode)

모드진입용도
NormalEsc이동, 삭제, 복사, 붙여넣기, 명령 조합
Inserti, a, o텍스트 입력
Visualv, V, Ctrl+v텍스트 범위 선택
Command-line:, /, ?Ex 명령, 검색

이동 (Normal Mode)

기본 이동:
  h ← 왼쪽     j ↓ 아래     k ↑ 위     l → 오른쪽

단어 이동:
  w  - 다음 단어 시작으로
  b  - 이전 단어 시작으로
  e  - 현재/다음 단어 끝으로
  W/B/E - 공백 기준 단어 이동 (구두점 무시)

행 내 이동:
  0  - 행 맨 앞 (첫 번째 컬럼)
  ^  - 행의 첫 비공백 문자
  $  - 행 맨 끝
  f{char} - 현재 행에서 다음 {char}로 이동
  F{char} - 현재 행에서 이전 {char}로 이동
  t{char} - {char} 직전으로 이동

파일 내 이동:
  gg       - 파일 맨 처음
  G        - 파일 맨 끝
  {숫자}G  - 특정 행으로 이동 (예: 50G → 50번째 줄)
  :{숫자}  - 특정 행으로 이동 (예: :50)

화면 이동:
  Ctrl+d  - 반 페이지 아래
  Ctrl+u  - 반 페이지 위
  Ctrl+f  - 한 페이지 아래
  Ctrl+b  - 한 페이지 위
  H       - 화면 상단으로
  M       - 화면 중간으로
  L       - 화면 하단으로
  zz      - 현재 행을 화면 중앙으로
  zt      - 현재 행을 화면 상단으로
  zb      - 현재 행을 화면 하단으로

기타:
  %       - 매칭되는 괄호로 이동 ({}, (), [])
  *       - 커서 아래 단어 다음 출현 위치
  #       - 커서 아래 단어 이전 출현 위치

편집 (Normal Mode)

Insert 모드 진입:
  i  - 커서 앞에 입력
  a  - 커서 뒤에 입력
  I  - 행 맨 앞에 입력
  A  - 행 맨 뒤에 입력
  o  - 아래에 새 줄 삽입 후 입력
  O  - 위에 새 줄 삽입 후 입력

삭제:
  x     - 커서 위 문자 삭제
  X     - 커서 앞 문자 삭제 (Backspace와 유사)
  dd    - 현재 행 삭제 (잘라내기)
  3dd   - 3행 삭제
  dw    - 단어 삭제
  d$    - 커서부터 행 끝까지 삭제
  d0    - 커서부터 행 처음까지 삭제
  D     - d$와 동일

복사/붙여넣기:
  yy    - 현재 행 복사 (yank)
  3yy   - 3행 복사
  yw    - 단어 복사
  y$    - 커서부터 행 끝까지 복사
  p     - 커서 뒤에 붙여넣기
  P     - 커서 앞에 붙여넣기

실행 취소/다시 실행:
  u       - Undo
  Ctrl+r  - Redo

변경 (change - 삭제 후 Insert 모드 진입):
  cw    - 단어 변경 (커서부터 단어 끝까지 삭제 후 Insert)
  cc    - 행 전체 변경
  C     - 커서부터 행 끝까지 변경
  ciw   - 단어 전체 변경 (커서 위치 무관)
  ci"   - 따옴표 안의 내용 변경
  ci(   - 괄호 안의 내용 변경
  ci{   - 중괄호 안의 내용 변경
  ci[   - 대괄호 안의 내용 변경
  ca"   - 따옴표 포함하여 변경

삭제도 동일한 패턴:
  diw   - 단어 전체 삭제
  di"   - 따옴표 안의 내용 삭제
  di(   - 괄호 안의 내용 삭제
  da{   - 중괄호 포함하여 삭제

반복:
  .     - 마지막 편집 명령 반복 (매우 유용!)

텍스트 오브젝트 정리

i (inner) - 내부만 선택/조작
a (around) - 주변 구분자 포함

iw / aw  - 단어
is / as  - 문장
ip / ap  - 단락
i" / a"  - 큰따옴표
i' / a'  - 작은따옴표
i( / a(  - 소괄호 (ib / ab 동일)
i{ / a{  - 중괄호 (iB / aB 동일)
i[ / a[  - 대괄호
i< / a<  - 꺾쇠괄호
it / at  - HTML/XML 태그

검색 및 치환

검색:
  /pattern    - 정방향 검색 (Enter로 실행)
  ?pattern    - 역방향 검색
  n           - 다음 검색 결과
  N           - 이전 검색 결과
  *           - 커서 아래 단어를 정방향 검색
  #           - 커서 아래 단어를 역방향 검색

검색 하이라이트 끄기:
  :noh        - 또는 :nohlsearch

치환 (substitute):
  :s/old/new/           - 현재 행의 첫 번째만 치환
  :s/old/new/g          - 현재 행의 모든 매칭 치환
  :%s/old/new/g         - 파일 전체에서 치환
  :%s/old/new/gc        - 전체 치환 + 확인 (y/n/a/q)
  :10,20s/old/new/g     - 10~20행 범위에서 치환
  :'<,'>s/old/new/g     - Visual 모드로 선택한 범위에서 치환

치환 플래그:
  g  - global (행 내 모든 매칭)
  c  - confirm (확인)
  i  - case insensitive
  I  - case sensitive

정규표현식 사용:
  :%s/\v(\w+)/"\1"/g      - \v (very magic) 모드로 정규표현식 사용
  :%s/^\s\+//g             - 행 앞 공백 제거
  :%s/\s\+$//g             - 행 끝 공백 제거

멀티파일 편집

# 파일 열기/전환
:e filename        # 파일 열기
:e!                # 현재 파일 변경사항 버리고 다시 열기
 
# 버퍼 (열린 파일 목록)
:ls                # 버퍼 목록
:bn                # 다음 버퍼
:bp                # 이전 버퍼
:b3                # 3번 버퍼로 이동
:bd                # 현재 버퍼 삭제 (닫기)
 
# 화면 분할
:split filename    # 수평 분할 (또는 :sp)
:vsplit filename   # 수직 분할 (또는 :vsp)
Ctrl+w h/j/k/l    # 분할된 창 간 이동 (방향키도 가능)
Ctrl+w w           # 다음 창으로 이동
Ctrl+w =           # 모든 창 크기 균등
Ctrl+w +/-         # 현재 창 크기 조절
Ctrl+w q           # 현재 창 닫기
 
#
:tabnew filename   # 새 탭
:tabn / :tabp      # 다음/이전 탭 (gt / gT)
 
# 저장/종료
:w                 # 저장
:q                 # 종료
:wq                # 저장 후 종료
:x                 # :wq와 동일 (변경사항 있을 때만 저장)
ZZ                 # :x와 동일
:q!                # 저장하지 않고 종료
:qa                # 모든 창/탭 종료
:wa                # 모든 파일 저장
:wqa               # 모든 파일 저장 후 종료

설정

" 명령 모드에서 일시적 설정
:set nu            " 행 번호 표시
:set nonu          " 행 번호 숨기기
:set rnu           " 상대 행 번호
:set hlsearch      " 검색 하이라이트
:set incsearch     " 입력 중 실시간 검색
:set ignorecase    " 검색 시 대소문자 무시
:set smartcase     " 대문자 포함 시 대소문자 구분
:syntax on         " 문법 하이라이팅
:set tabstop=4     " 탭 너비
:set expandtab     " 탭을 스페이스로
:set shiftwidth=4  " 자동 들여쓰기 너비
:set autoindent    " 자동 들여쓰기
:set paste         " 붙여넣기 모드 (자동 들여쓰기 비활성화)
:set nopaste       " 붙여넣기 모드 해제

~/.vimrc 기본 설정 예시:

" 기본 설정
set nocompatible       " Vi 호환 모드 비활성화
syntax on              " 문법 하이라이팅
set number             " 행 번호
set relativenumber     " 상대 행 번호
set cursorline         " 현재 행 하이라이트
 
" 검색
set hlsearch           " 검색 하이라이트
set incsearch          " 실시간 검색
set ignorecase         " 대소문자 무시
set smartcase          " 대문자 포함 시 구분
 
" 들여쓰기
set tabstop=4          " 탭 너비
set shiftwidth=4       " 자동 들여쓰기 너비
set expandtab          " 탭 → 스페이스
set autoindent         " 자동 들여쓰기
set smartindent        " 스마트 들여쓰기
 
" 표시
set showmatch          " 괄호 매칭 표시
set showcmd            " 명령 표시
set wildmenu           " 명령줄 탭 완성
set laststatus=2       " 항상 상태줄 표시
set scrolloff=5        " 커서 위아래 5줄 여유
 
" 인코딩
set encoding=utf-8
set fileencoding=utf-8
 
" 기타
set mouse=a            " 마우스 사용
set clipboard=unnamedplus  " 시스템 클립보드 연동
set backspace=indent,eol,start  " Backspace 정상 동작

실전 고급 기능

매크로 (반복 작업 자동화):
  qa         - a 레지스터에 매크로 녹화 시작
  (작업 수행)
  q          - 녹화 종료
  @a         - a 매크로 실행
  10@a       - a 매크로 10번 실행
  @@         - 마지막 매크로 재실행

마크 (위치 북마크):
  ma         - 현재 위치를 a 마크로 저장
  'a         - a 마크 행으로 이동
  `a         - a 마크 정확한 위치로 이동
  :marks     - 모든 마크 목록

레지스터 (다중 클립보드):
  "ayy       - 현재 행을 a 레지스터에 복사
  "ap        - a 레지스터 내용 붙여넣기
  "Ayy       - a 레지스터에 추가 (append)
  :reg       - 레지스터 목록
  "+yy       - 시스템 클립보드에 복사
  "+p        - 시스템 클립보드에서 붙여넣기
  "0p        - 마지막 yank 내용 붙여넣기 (삭제와 구분)

비주얼 블록 모드 (Ctrl+v):
  Ctrl+v     - 비주얼 블록 모드 진입
  (j/k로 행 선택)
  I          - 선택 영역 앞에 텍스트 삽입 (Esc로 적용)
  A          - 선택 영역 뒤에 텍스트 삽입
  d          - 선택 영역 삭제
  c          - 선택 영역 변경
  r{char}    - 선택 영역을 {char}로 교체

  # 예: 여러 줄 주석 추가
  # 1) Ctrl+v로 블록 선택
  # 2) j/k로 범위 지정
  # 3) I 누르고 # 입력
  # 4) Esc → 모든 선택 행에 적용

들여쓰기:
  >>         - 현재 행 들여쓰기
  <<         - 현재 행 내어쓰기
  >5>        - 5행 들여쓰기
  ='         - Visual 모드 선택 후 = 으로 자동 정렬

2. SSH 심화

키 생성

# Ed25519 (추천 - 짧고, 빠르고, 안전)
ssh-keygen -t ed25519 -C "your_email@example.com"
 
# RSA (호환성 필요 시)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
 
# 옵션:
# -t  타입 (ed25519, rsa, ecdsa)
# -b  비트 수 (RSA에서 사용, 최소 2048, 권장 4096)
# -C  주석 (식별용)
# -f  파일 경로 지정
 
# 생성되는 파일:
# ~/.ssh/id_ed25519      - 개인키 (절대 공유 금지!)
# ~/.ssh/id_ed25519.pub  - 공개키 (서버에 등록)

키 기반 인증 설정

# 1. 공개키를 서버에 복사
ssh-copy-id user@server
# 또는 수동:
cat ~/.ssh/id_ed25519.pub | ssh user@server 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
 
# 2. 서버측 파일: ~/.ssh/authorized_keys
# 한 줄에 하나의 공개키
 
# 3. 퍼미션 (반드시 지켜야 함! 틀리면 인증 실패)
chmod 700 ~/.ssh                    # 디렉토리
chmod 600 ~/.ssh/authorized_keys    # 인증키 파일
chmod 600 ~/.ssh/id_ed25519         # 개인키
chmod 644 ~/.ssh/id_ed25519.pub     # 공개키
chmod 644 ~/.ssh/known_hosts        # known hosts
chmod 600 ~/.ssh/config             # SSH 설정 파일

SSH 설정 파일: ~/.ssh/config

# 기본 구조
Host myserver
    HostName 192.168.1.100
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_work
 
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github
 
Host staging
    HostName staging.example.com
    User admin
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ForwardAgent yes
 
# 와일드카드 사용
Host *.example.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_work
 
# 점프 호스트 (bastion을 통한 접속)
Host internal-server
    HostName 10.0.1.50
    User deploy
    ProxyJump bastion
 
Host bastion
    HostName bastion.example.com
    User admin
    Port 2222
 
# 사용:
# ssh myserver       → ssh -p 2222 deploy@192.168.1.100 과 동일
# ssh staging
# ssh internal-server  → bastion을 거쳐 내부 서버에 접속

포트 포워딩

# 로컬 포워딩 (-L): 로컬 포트 → 원격 포트
# 로컬의 8080으로 접근하면 원격 서버를 통해 remote-db:3306에 연결
ssh -L 8080:remote-db:3306 user@server
# 이후 localhost:8080으로 DB 접속 가능
 
# 로컬 포워딩 실전: 원격 서버의 웹앱에 접근
ssh -L 3000:localhost:3000 user@server
# 원격 서버의 localhost:3000이 로컬 localhost:3000으로 포워딩
 
# 리모트 포워딩 (-R): 원격 포트 → 로컬 포트
# 원격 서버의 8080을 통해 내 로컬 3000에 접근 가능
ssh -R 8080:localhost:3000 user@server
 
# SOCKS 프록시 (-D): 동적 포워딩
ssh -D 1080 user@server
# 브라우저에서 SOCKS5 프록시로 localhost:1080 설정
# 모든 트래픽이 원격 서버를 통해 나감
 
# 백그라운드 포트 포워딩 (세션 없이)
ssh -fNL 8080:localhost:3000 user@server
# -f: 백그라운드
# -N: 원격 명령 실행 안 함

ssh-agent

# ssh-agent 시작
eval "$(ssh-agent -s)"
 
# 키 추가
ssh-add ~/.ssh/id_ed25519
 
# 등록된 키 목록
ssh-add -l
 
# 모든 키 제거
ssh-add -D

sshd_config - SSH 서버 설정

# 파일: /etc/ssh/sshd_config
 
# 포트 변경 (보안)
Port 2222
 
# Root 로그인 제한
PermitRootLogin no              # 금지 (권장)
PermitRootLogin prohibit-password  # 키 인증만 허용
 
# 비밀번호 인증 비활성화 (키 인증만 사용)
PasswordAuthentication no
 
# 빈 비밀번호 금지
PermitEmptyPasswords no
 
# 공개키 인증 활성화
PubkeyAuthentication yes
 
# 접속 허용 사용자/그룹 제한
AllowUsers deploy admin
AllowGroups sshusers
 
# 최대 인증 시도 횟수
MaxAuthTries 3
 
# 접속 시간 제한
LoginGraceTime 60
 
# 설정 변경 후 재시작
sudo systemctl restart sshd

3. 파일 전송

scp - 안전한 원격 복사

# 로컬 → 원격
scp file.txt user@server:/home/user/
 
# 원격 → 로컬
scp user@server:/home/user/file.txt ./
 
# 디렉토리 복사 (-r: recursive)
scp -r ./mydir user@server:/home/user/
 
# 포트 지정 (-P: 대문자 주의)
scp -P 2222 file.txt user@server:/home/user/
 
# 진행률 표시 (기본 활성화)
scp -v file.txt user@server:~/
 
# SSH config 활용
scp file.txt myserver:/home/deploy/

rsync - 고급 동기화 도구

scp보다 효율적. 변경된 부분만 전송(delta transfer)하며 다양한 옵션을 지원한다.

# 기본 동기화 (로컬 → 원격)
rsync -avz ./mydir/ user@server:/home/user/mydir/
 
# 옵션 설명:
# -a (archive) = -rlptgoD (재귀, 심볼릭링크, 퍼미션, 시간, 그룹, 소유자, 디바이스)
# -v (verbose)  - 상세 출력
# -z (compress) - 전송 시 압축
# -P (progress + partial) - 진행률 표시 + 중단 시 재개 가능
 
# 원격 → 로컬
rsync -avz user@server:/home/user/mydir/ ./mydir/
 
# 삭제 동기화 (소스에 없는 파일은 대상에서도 삭제)
rsync -avz --delete ./mydir/ user@server:/home/user/mydir/
 
# 특정 파일 제외
rsync -avz --exclude='*.log' --exclude='.git' ./mydir/ user@server:~/mydir/
 
# 제외 패턴 파일 사용
rsync -avz --exclude-from='exclude.txt' ./mydir/ user@server:~/mydir/
 
# 드라이런 (실제 전송 안 함, 미리 확인)
rsync -avzn ./mydir/ user@server:~/mydir/
 
# SSH 포트 지정
rsync -avz -e 'ssh -p 2222' ./mydir/ user@server:~/mydir/
 
# 대역폭 제한 (500KB/s)
rsync -avz --bwlimit=500 ./mydir/ user@server:~/mydir/

rsync 트레일링 슬래시 주의:

# 슬래시 있음: 디렉토리 내용물을 동기화
rsync -avz mydir/ server:~/dest/
# 결과: dest/ 안에 mydir의 파일들이 직접 들어감
 
# 슬래시 없음: 디렉토리 자체를 동기화
rsync -avz mydir server:~/dest/
# 결과: dest/mydir/ 이 생성됨

4. 터미널 멀티플렉서

tmux

SSH 연결이 끊어져도 세션이 유지되는 터미널 관리 도구.

핵심 개념

tmux 서버
└── 세션 (Session) - 작업 단위
    ├── 윈도우 (Window) - 탭과 유사
    │   ├── 페인 (Pane) - 화면 분할
    │   └── 페인 (Pane)
    └── 윈도우 (Window)
        └── 페인 (Pane)

세션 관리

# 새 세션 생성
tmux
tmux new-session -s mysession    # 이름 지정
 
# 세션에서 분리 (detach) - 세션은 백그라운드에서 계속 실행
# Ctrl+b d
 
# 세션 목록
tmux ls
tmux list-sessions
 
# 세션 재접속 (attach)
tmux attach -t mysession
tmux a -t mysession           # 축약
tmux a                        # 마지막 세션에 접속
 
# 세션 종료
tmux kill-session -t mysession
# 또는 세션 내에서 exit

키바인딩 (접두사: Ctrl+b)

모든 tmux 명령은 Ctrl+b 를 먼저 누른 후 키를 입력한다.

세션:
  Ctrl+b d       - 세션 분리 (detach)
  Ctrl+b s       - 세션 목록 (선택 가능)
  Ctrl+b $       - 세션 이름 변경

윈도우 (탭):
  Ctrl+b c       - 새 윈도우 생성
  Ctrl+b n       - 다음 윈도우
  Ctrl+b p       - 이전 윈도우
  Ctrl+b 0-9     - N번 윈도우로 이동
  Ctrl+b w       - 윈도우 목록 (선택 가능)
  Ctrl+b ,       - 윈도우 이름 변경
  Ctrl+b &       - 현재 윈도우 종료 (확인)

페인 (화면 분할):
  Ctrl+b %       - 수직 분할
  Ctrl+b "       - 수평 분할
  Ctrl+b 방향키   - 페인 간 이동
  Ctrl+b o       - 다음 페인으로 이동
  Ctrl+b z       - 현재 페인 전체화면 토글 (zoom)
  Ctrl+b x       - 현재 페인 종료 (확인)
  Ctrl+b {       - 페인 위치 앞으로 이동
  Ctrl+b }       - 페인 위치 뒤로 이동
  Ctrl+b Space   - 페인 레이아웃 전환
  Ctrl+b Ctrl+방향키  - 페인 크기 조절

스크롤/복사:
  Ctrl+b [       - 스크롤/복사 모드 진입 (q로 나가기)
                   방향키, PgUp/PgDn, /로 검색 가능

tmux 설정 (~/.tmux.conf)

# 접두사를 Ctrl+a로 변경 (screen 스타일)
# set -g prefix C-a
# unbind C-b
 
# 마우스 사용
set -g mouse on
 
# 256 컬러 지원
set -g default-terminal "screen-256color"
 
# 히스토리 크기
set -g history-limit 10000
 
# 윈도우 번호 1부터 시작
set -g base-index 1
setw -g pane-base-index 1
 
# 설정 리로드: Ctrl+b 후
# :source-file ~/.tmux.conf

screen - 기본 비교

# screen은 tmux의 전신. 대부분의 경우 tmux가 더 유연하지만, screen이 기본 설치된 서버도 있다.
 
# 새 세션
screen
screen -S mysession
 
# 분리 (detach)
# Ctrl+a d
 
# 재접속
screen -r mysession
 
# 세션 목록
screen -ls
 
# 화면 분할
# Ctrl+a |    수직 분할
# Ctrl+a S    수평 분할
# Ctrl+a Tab  페인 이동
 
# tmux vs screen 주요 차이:
# tmux: 수직/수평 분할 자유, 스크립팅 강력, 상태바 커스텀 용이
# screen: 오래된 서버에 기본 설치, 직렬 콘솔 연결 지원

5. 기타 유용한 도구

jq - JSON 처리

# 보기 좋게 출력 (pretty print)
echo '{"name":"kim","age":25}' | jq .
 
# 특정 필드 추출
echo '{"name":"kim","age":25}' | jq '.name'
# "kim"
 
# 따옴표 제거 (-r: raw output)
echo '{"name":"kim","age":25}' | jq -r '.name'
# kim
 
# 배열 요소 접근
echo '[1,2,3]' | jq '.[0]'
# 1
 
# 배열 순회
echo '[{"name":"a"},{"name":"b"}]' | jq '.[].name'
# "a"
# "b"
 
# 조건 필터
echo '[{"name":"a","age":20},{"name":"b","age":30}]' | jq '.[] | select(.age > 25)'
 
# 새 객체 생성
echo '{"first":"Kim","last":"Minsoo"}' | jq '{fullname: (.first + " " + .last)}'
 
# 파일에서 읽기
jq '.users[].email' data.json
 
# 실전: API 응답 파싱
curl -s https://api.example.com/users | jq '.data[] | {id, name, email}'

xargs - 표준 입력을 명령 인수로 변환

# 기본 사용: 파일 목록을 인수로 전달
find . -name "*.log" | xargs rm
 
# 공백/특수문자 안전 처리 (-0 + find의 -print0)
find . -name "*.log" -print0 | xargs -0 rm
 
# 한 번에 하나씩 실행 (-n 1)
echo "a b c" | xargs -n 1 echo
 
# 병렬 실행 (-P: parallel)
find . -name "*.jpg" -print0 | xargs -0 -P 4 -I {} convert {} -resize 50% resized/{}
 
# 플레이스홀더 (-I {})
ls *.txt | xargs -I {} cp {} /backup/{}.bak
 
# 확인 후 실행 (-p)
find . -name "*.tmp" | xargs -p rm
 
# 실전: grep 결과의 파일에서 치환
grep -rl "old_text" . | xargs sed -i 's/old_text/new_text/g'

tee - 표준 출력을 파일과 화면에 동시 출력

# 명령 출력을 파일에도 저장
ls -la | tee output.txt
 
# 기존 파일에 추가 (-a: append)
echo "new line" | tee -a logfile.txt
 
# 여러 파일에 동시에
echo "data" | tee file1.txt file2.txt
 
# sudo와 함께 사용 (리다이렉션에 sudo 적용)
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
# 참고: sudo echo ... > /etc/file 은 동작하지 않음 (>가 현재 쉘 권한)
 
# 파이프라인 중간에 로깅
cat data.txt | tee /tmp/debug.log | sort | uniq

watch - 주기적 명령 실행

# 2초마다 실행 (기본)
watch df -h
 
# 0.5초마다 실행
watch -n 0.5 'ss -tuln'
 
# 변경 부분 하이라이트
watch -d free -h
 
# 제목줄 숨기기
watch -t date

time - 명령 실행 시간 측정

time ls -R /usr
# real    0m1.234s    ← 총 경과 시간 (벽시계)
# user    0m0.456s    ← 사용자 공간 CPU 시간
# sys     0m0.123s    ← 커널 공간 CPU 시간
 
# real >> user + sys → I/O 대기가 많음
# user가 큼 → CPU 집약 작업
# sys가 큼 → 시스템 콜이 많음
 
# 여러 명령 측정
time (sleep 1 && echo "done")

history - 명령 히스토리

# 히스토리 목록 출력
history
history 20        # 최근 20개
 
# 히스토리에서 실행
!100              # 100번 명령 재실행
!!                # 직전 명령 재실행
!ssh              # ssh로 시작하는 마지막 명령 재실행
!?pattern         # pattern을 포함하는 마지막 명령 재실행
 
# 히스토리 검색 (매우 유용)
Ctrl+r            # 역방향 검색 (입력하면서 검색)
Ctrl+r 반복       # 다음 결과
Ctrl+g            # 검색 취소
 
# 히스토리 치환
^old^new          # 직전 명령의 old를 new로 바꿔 실행
# 예: cat /etc/passws → ^passws^passwd → cat /etc/passwd
 
# 히스토리 설정 (~/.bashrc)
export HISTSIZE=10000         # 메모리 히스토리 크기
export HISTFILESIZE=20000     # 파일 히스토리 크기
export HISTCONTROL=ignoredups:ignorespace  # 중복, 공백 시작 명령 제외
export HISTTIMEFORMAT="%F %T "  # 타임스탬프 추가
export HISTIGNORE="ls:cd:pwd:exit:clear"  # 특정 명령 제외
 
# 히스토리 파일
cat ~/.bash_history
 
# 히스토리 삭제
history -c        # 메모리 히스토리 삭제
history -w        # 파일에 저장

fc - 히스토리 편집 및 재실행

# 직전 명령을 에디터에서 편집 후 실행
fc
 
# 특정 범위 히스토리를 에디터에서 편집
fc 100 110
 
# 직전 명령의 문자열 치환 후 실행
fc -s old=new
 
# 히스토리 목록 (history와 유사)
fc -l
fc -l -20         # 최근 20개