본문으로 건너뛰기
Previous
Next
개발자를 위한 리눅스·맥 명령어 실전 가이드 | 네트워크·파일·프로세스·디버깅

개발자를 위한 리눅스·맥 명령어 실전 가이드 | 네트워크·파일·프로세스·디버깅

개발자를 위한 리눅스·맥 명령어 실전 가이드 | 네트워크·파일·프로세스·디버깅

이 글의 핵심

개발 현장에서 매일 쓰는 리눅스·맥 터미널 명령어를 실전 예제로 정리합니다. 네트워크 디버깅, 파일 조작, 프로세스 관리, 로그 분석까지 복사해서 바로 쓸 수 있는 치트시트입니다.

들어가며

“서버가 응답이 없어요”, “로그 어디서 보죠?”, “포트가 이미 사용 중이래요” — 개발하다 보면 터미널 명령어로 문제를 빠르게 해결해야 할 때가 많습니다. 이 글은 개발 현장에서 실제로 자주 쓰는 리눅스·맥 명령어실전 예제로 정리한 치트시트입니다. 복사해서 바로 쓸 수 있도록 구성했습니다. 대상 독자:

  • 백엔드·DevOps 개발자
  • 서버 배포·디버깅하는 프론트엔드 개발자
  • 리눅스 터미널 입문자 이 글을 읽으면:
  • 네트워크 문제를 빠르게 진단할 수 있습니다.
  • 로그 파일에서 에러를 찾을 수 있습니다.
  • 프로세스·포트·디스크를 관리할 수 있습니다.

실전 경험에서 배운 교훈

이 기술을 실무 프로젝트에 처음 도입했을 때, 공식 문서만으로는 알 수 없었던 많은 함정들이 있었습니다. 특히 프로덕션 환경에서 발생하는 엣지 케이스들은 로컬 개발 환경에서는 재현조차 되지 않았죠.

가장 어려웠던 점은 성능 최적화였습니다. 처음엔 “동작만 하면 되겠지”라고 생각했지만, 실제 사용자 트래픽이 몰리면서 병목 지점들이 하나씩 드러났습니다. 특히 데이터베이스 쿼리 최적화, 캐싱 전략, 에러 핸들링 구조 등은 여러 번의 장애를 겪으면서 개선해 나갔습니다.

이 글에서는 그런 시행착오를 통해 얻은 실전 노하우와, “이렇게 하면 안 된다”는 교훈들을 함께 정리했습니다. 특히 트러블슈팅 섹션은 실제 장애 대응 경험을 바탕으로 작성했으니, 비슷한 문제를 마주했을 때 참고하시면 도움이 될 것입니다.

1. 디렉토리 탐색 및 파일 관리

기본 탐색

# 현재 디렉토리 확인
pwd
# 디렉토리 이동
cd /var/log
cd ~              # 홈 디렉토리
cd -              # 이전 디렉토리
cd ...            # 상위 디렉토리
# 디렉토리 내용 보기
ls                # 기본
ls -la            # 숨김 파일 포함, 상세 정보
ls -lh            # 사람이 읽기 쉬운 크기 (KB, MB)
ls -lt            # 최신 파일 먼저
ls -lS            # 큰 파일 먼저
ls -R             # 하위 디렉토리까지 재귀
# 트리 구조로 보기
tree              # 전체 트리
tree -L 2         # 2단계까지만
tree -d           # 디렉토리만
tree -I 'node_modules|.git'  # 제외

디렉토리 생성 및 삭제

# 디렉토리 생성
mkdir mydir
mkdir -p parent/child/grandchild  # 중간 디렉토리 자동 생성
# 디렉토리 삭제
rmdir mydir       # 빈 디렉토리만
rm -r mydir       # 내용 포함 삭제
rm -rf mydir      # 강제 삭제 (주의!)
# 안전한 삭제 (확인 후 삭제)
rm -ri mydir      # 각 파일마다 확인

파일 복사 및 이동

# 파일 복사
cp file.txt backup.txt
cp -r src/ dest/              # 디렉토리 복사
cp -p file.txt backup.txt     # 권한·타임스탬프 유지
cp -u src/* dest/             # 최신 파일만 복사
# 파일 이동 (이름 변경)
mv old.txt new.txt
mv file.txt /path/to/dest/
mv *.log logs/                # 여러 파일 이동
# 심볼릭 링크
ln -s /path/to/original link_name
ls -l link_name               # 링크 확인

파일 찾기 - find의 강력한 기능

find 명령어 내부 동작:

find의 파일 시스템 탐색 메커니즘:

1. 기본 동작:
   find /var/log -name "*.log"
   
   내부 처리:

   opendir("/var/log") → 디렉토리 핸들 얻기

   readdir() 반복:
   - d_name (파일명)
   - d_type (파일 타입: DT_REG, DT_DIR, DT_LNK)

   각 파일마다:
   - 이름 패턴 매칭 ("*.log"와 비교)
   - 조건 평가 (-type, -size, -mtime 등)
   - 매칭 시 출력 또는 -exec 실행

   디렉토리면 재귀:
   - opendir("/var/log/subdir")
   - 같은 과정 반복

   closedir()

2. 메타데이터 접근:
   stat() 시스템 콜로 파일 정보 조회:
   
   find . -size +100M

   각 파일마다 stat(filename, &statbuf)

   statbuf.st_size 확인 (바이트 단위)

   100MB = 100 * 1024 * 1024 = 104857600 bytes
   if (st_size > 104857600) → 매칭
   
   find . -mtime -7

   stat()로 st_mtime (수정 시간) 조회

   현재 시간 - st_mtime < 7일?
   
   find . -perm 777

   st_mode & 0777 == 0777?

3. -exec 내부 동작:
   find . -name "*.log" -exec rm {} \;
   
   각 매칭 파일마다:

   fork() → 자식 프로세스 생성

   execve("/bin/rm", ["rm", "file.log"], environ)

   wait() → 자식 종료 대기

   다음 파일 처리
   
   성능 차이:
   -exec ... \;  : 파일마다 fork/exec (느림)
   -exec ... +   : 한 번에 여러 파일 (빠름)
   
   예:
   -exec rm {} \;  : rm file1; rm file2; rm file3;
   -exec rm {} +   : rm file1 file2 file3

4. 최적화:
   find는 파일 시스템 순회가 비용 높음
   
   대안:
   - locate: DB 기반 (빠르지만 최신 아님)
     updatedb로 DB 갱신 필요
   
   - fd (modern find):
     더 빠른 알고리즘, 병렬 처리
     .gitignore 자동 인식
   
   - 파일 개수 많을 때:
     find + xargs 조합 (버퍼링)
     find . -name "*.log" | xargs rm

파일 시스템 API 흐름:
User: find . -name "*.log"

Kernel: sys_openat("/path") → inode 읽기

Kernel: sys_getdents64() → directory entries

find: 각 entry 필터링 (이름, 타입, 크기)

find: 재귀 시 sys_openat(subdir)

Output: 매칭된 경로 출력
# 이름으로 찾기
find . -name "*.log"          # 현재 디렉토리부터 재귀 검색
find /var -name "error.log"   # 특정 경로에서 검색
find . -iname "*.TXT"         # 대소문자 무시 (-iname)

# 타입으로 찾기
find . -type f                # 파일만 (regular file)
find . -type d                # 디렉토리만 (directory)
find . -type l                # 심볼릭 링크만 (link)
find . -type f -empty         # 빈 파일만

# 크기로 찾기
find . -size +100M            # 100MB 이상
find . -size -1k              # 1KB 이하
find /tmp -size +1G -delete   # 1GB 이상 파일 삭제
# 크기 단위: c(byte), k(KB), M(MB), G(GB)

# 시간으로 찾기 (디버깅에 유용)
find . -mtime -7              # 최근 7일 이내 수정 (Modified)
find . -mtime +30             # 30일 이상 수정 안 됨
find . -atime -1              # 최근 1일 이내 접근 (Accessed)
find . -ctime -1              # 최근 1일 이내 메타데이터 변경 (Changed)
find . -mmin -60              # 최근 60분 이내 (분 단위)

# 권한으로 찾기 (보안)
find . -perm 777              # 정확히 777 권한
find . -perm -644             # 최소 644 권한 이상
find / -perm /u+s,g+s         # SUID/SGID 비트가 설정된 파일 (보안 위험)

# 찾아서 실행 (자동화)
find . -name "*.tmp" -delete
# -exec: 각 파일마다 명령어 실행
find . -name "*.js" -exec grep "TODO" {} \;
# {}: 찾은 파일명으로 대체
# \;: -exec의 끝 (세미콜론 이스케이프)

find . -type f -exec chmod 644 {} \;
# 모든 파일을 644로 변경

# -exec vs -exec ... +
find . -name "*.log" -exec rm {} \;       # 파일마다 rm 실행 (느림)
find . -name "*.log" -exec rm {} +        # 여러 파일을 한 번에 (빠름)
# rm file1 file2 file3 ... (한 번의 rm 호출)

# 복잡한 조건 (AND, OR, NOT)
find . \( -name "*.log" -or -name "*.txt" \) -size +1M
# .log 또는 .txt이면서 1MB 이상

find . -name "*.js" -not -path "*/node_modules/*"
# .js 파일 중 node_modules 제외

# 실전 예제: 오래된 로그 파일 압축 및 삭제
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;
find /var/log -name "*.gz" -mtime +90 -delete

2. 파일 내용 보기 및 검색

파일 내용 출력

# 전체 내용
cat file.txt
cat file1.txt file2.txt       # 여러 파일 연결
# 줄 번호 포함
cat -n file.txt
nl file.txt
# 처음 N줄
head file.txt                 # 기본 10줄
head -n 20 file.txt           # 20줄
head -c 100 file.txt          # 처음 100바이트
# 마지막 N줄
tail file.txt                 # 기본 10줄
tail -n 50 file.txt           # 50줄
tail -f /var/log/app.log      # 실시간 모니터링 (로그)
tail -f -n 100 app.log        # 최근 100줄부터 실시간
# 페이지 단위로 보기
less file.txt                 # 스크롤 가능 (q로 종료)
more file.txt                 # 한 페이지씩

grep: 텍스트 검색

grep 내부 패턴 매칭 메커니즘:

grep의 문자열 검색 알고리즘:

1. 기본 동작:
   grep "error" app.log
   
   처리 흐름:

   open("app.log", O_RDONLY)

   read() 반복 (버퍼 단위, 보통 4KB~8KB):
   - 버퍼에 데이터 읽기
   - 줄 단위로 분리 (\n 기준)

   각 줄마다:
   - 패턴 매칭 (Boyer-Moore 또는 KMP 알고리즘)
   - 매칭 시: write(STDOUT, line, len)

   close()

2. 패턴 매칭 알고리즘:
   
   Boyer-Moore (대부분의 grep 구현):
   
   패턴: "error"
   텍스트: "This is an error message"
   
   단계:
   1. 패턴 끝부터 비교
      "error" vs "This "
      's' != 'r' → 패턴에 's' 없음
      → 5칸 건너뛰기 (패턴 길이)
   
   2. 다음 위치에서 비교
      "error" vs "s an "
      ' ' != 'r' → 계속
   
   3. 매칭 발견
      "error" vs "error"
      → 전체 매칭!
   
   시간 복잡도:
   - 최선: O(n/m) (n: 텍스트 길이, m: 패턴 길이)
   - 평균: O(n)
   - 최악: O(nm) (드물음)
   
   vs 단순 검색: O(nm) 항상

3. 정규표현식 (regex):
   grep -E "error|warning" app.log
   
   NFA (Non-deterministic Finite Automaton):
   
   패턴: error|warning

   정규식 파싱 → NFA 생성

   상태 머신:
   
   State 0 (시작)

     e → State 1 (error 경로)
     w → State 6 (warning 경로)
   
   State 1
     ↓ r
   State 2
     ↓ r
   State 3
     ↓ o
   State 4
     ↓ r
   State 5 (accept)
   
   State 6
     ↓ a
   State 7
     ↓ r
   State 8
     ↓ n
   ...
   
   매칭 과정 (Backtracking):
   - 각 문자마다 상태 전이
   - | (OR)에서 분기
   - 매칭 실패 시 백트래킹
   
   성능:
   - 단순 패턴: 빠름
   - 복잡한 패턴 (.*.*, (a+)+b): 지수 시간 (Catastrophic Backtracking)
   
   대안:
   - ripgrep (rg): 더 빠른 구현
   - egrep: grep -E와 동일

4. 최적화 기법:
   
   grep -F "error" app.log
   (-F: Fixed string, 정규식 아님)

   Boyer-Moore 사용
   정규식 엔진 우회
   → 훨씬 빠름
   
   grep -r "pattern" /
   (재귀 검색)

   opendir() + readdir() 반복
   각 파일마다 grep
   병렬화 없음 (순차)
   
   대안: ripgrep
   - 병렬 파일 처리
   - .gitignore 인식
   - UTF-8 최적화

5. 메모리 효율:
   
   대용량 파일 (10GB):

   mmap() 또는 버퍼 읽기
   - 전체 파일 로드 안 함
   - 4KB~8KB 버퍼 재사용
   - 줄 단위 처리
   
   grep -c "error" huge.log

   매칭 카운트만 유지
   매칭 줄 출력 안 함
   → 메모리 절약

내부 시스템 콜 흐름:
User: grep "error" app.log

Kernel: sys_open("app.log") → fd

Loop:
  Kernel: sys_read(fd, buffer, 4096)
  grep: Boyer-Moore 검색
  grep: 매칭 시 write(1, line, len)

Kernel: sys_close(fd)
# 기본 검색
grep "error" app.log
grep -i "error" app.log       # 대소문자 무시
grep -v "debug" app.log       # 제외 (debug 없는 줄)
grep -n "error" app.log       # 줄 번호 포함
grep -c "error" app.log       # 매칭 줄 개수
# 여러 파일 검색
grep "TODO" *.js
grep -r "import" src/         # 재귀 검색
grep -l "error" *.log         # 파일명만 출력
# 정규표현식
grep "^Error" app.log         # Error로 시작
grep "failed$" app.log        # failed로 끝남
grep "error\|warning" app.log # OR 검색
grep -E "error|warning" app.log  # 확장 정규식
# 컨텍스트 포함
grep -A 5 "error" app.log     # 매칭 후 5줄
grep -B 3 "error" app.log     # 매칭 전 3줄
grep -C 2 "error" app.log     # 전후 2줄
# 실전 예제
grep -i "exception" *.log | grep -v "test"  # 파이프 조합

awk: 텍스트 처리

# 특정 컬럼 출력
awk '{print $1}' file.txt     # 첫 번째 컬럼
awk '{print $1, $3}' file.txt # 1, 3번째 컬럼
ps aux | awk '{print $2, $11}' # PID와 명령어
# 조건 필터
awk '$3 > 100' file.txt       # 3번째 컬럼이 100 이상
awk '/error/ {print $0}' app.log  # error 포함 줄
# 합계 계산
awk '{sum += $1} END {print sum}' numbers.txt
du -sh */ | awk '{sum += $1} END {print sum}'
# 구분자 변경
awk -F: '{print $1}' /etc/passwd  # : 구분자
awk -F',' '{print $2}' data.csv   # CSV
# 실전 예제: 메모리 사용량 상위 5개
ps aux | awk '{print $4, $11}' | sort -rn | head -5
# 로그에서 응답 시간 평균
awk '/response_time/ {sum += $5; count++} END {print sum/count}' app.log

sed: 텍스트 치환

# 기본 치환
sed 's/old/new/' file.txt     # 첫 번째만
sed 's/old/new/g' file.txt    # 모두
sed -i 's/old/new/g' file.txt # 파일 직접 수정 (리눅스)
sed -i ' 's/old/new/g' file.txt  # 맥
# 특정 줄만
sed '3s/old/new/' file.txt    # 3번째 줄만
sed '1,5s/old/new/' file.txt  # 1~5번째 줄
# 줄 삭제
sed '3d' file.txt             # 3번째 줄 삭제
sed '/pattern/d' file.txt     # 패턴 매칭 줄 삭제
# 실전 예제: 설정 파일 수정
sed -i 's/DEBUG=true/DEBUG=false/g' .env
sed -i 's/localhost/0.0.0.0/g' config.yaml

3. 네트워크 디버깅

IP 및 네트워크 인터페이스 확인

# IP 주소 확인
ifconfig                      # 맥, 구형 리눅스
ip addr show                  # 최신 리눅스
ip a                          # 축약형
# 특정 인터페이스만
ifconfig en0                  # 맥
ip addr show eth0             # 리눅스
# 외부 IP 확인
curl ifconfig.me
curl ipinfo.io/ip
dig +short myip.opendns.com @resolver1.opendns.com
# 라우팅 테이블
route -n                      # 리눅스
netstat -rn                   # 맥
ip route show                 # 리눅스

포트 및 연결 확인 - 실전 디버깅

# 열린 포트 확인
netstat -tuln                 # 리눅스 (TCP/UDP, listening, numeric)
# -t: TCP만
# -u: UDP만
# -l: listening (LISTEN 상태) 만
# -n: 숫자로 표시 (DNS 조회 안 함, 빠름)

netstat -an | grep LISTEN     # 맥 (BSD 버전)
# -a: all (모든 소켓)
# -n: 숫자로 표시

lsof -i -P -n                 # 모든 네트워크 연결
# -i: internet 소켓만
# -P: 포트를 숫자로 (80 대신 http 표시 방지)
# -n: IP를 숫자로 (DNS 조회 안 함)

lsof -i :8080                 # 특정 포트
# 출력:
# COMMAND  PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
# node    1234  user   12u  IPv4  0x123  0t0     TCP *:8080 (LISTEN)

# 프로세스별 포트 확인
lsof -i -P -n | grep LISTEN
sudo lsof -iTCP -sTCP:LISTEN -n -P
# -s: 상태 필터 (LISTEN, ESTABLISHED, CLOSE_WAIT 등)

# 특정 프로세스의 포트
lsof -p 1234                  # PID 1234의 모든 파일 디스크립터
lsof -c node                  # node로 시작하는 모든 프로세스
lsof -c node -a -i            # node 프로세스의 네트워크 연결만
# -a: AND 연산

# 포트 사용 중인 프로세스 죽이기 (자주 쓰는 패턴)
lsof -ti:8080 | xargs kill
# -t: PID만 출력
# xargs: 파이프로 받은 PID를 kill 인자로 전달

lsof -ti:8080 | xargs kill -9  # 강제 종료 (SIGKILL)
# kill -9: 프로세스가 즉시 종료 (정리 작업 불가)
# 주의: 데이터 손실 가능

# 한 줄로 해결 (더 간단)
kill $(lsof -ti:8080)          # 서브셸 사용

# ss (최신 리눅스, netstat 대체) - 더 빠르고 강력
ss -tuln                      # 열린 포트
# netstat보다 10-100배 빠름 (커널에서 직접 읽기)

ss -tunp                      # 프로세스 포함 (root 필요)
# 출력:
# tcp LISTEN 0 128 *:8080 *:* users:(("node",pid=1234,fd=12))

ss -s                         # 통계
# 전체 TCP/UDP 연결 수, 상태별 통계

# 실전 예제: ESTABLISHED 연결 수 확인
ss -tan state established | wc -l
# -t: TCP
# -a: all
# -n: 숫자
# state established: ESTABLISHED 상태만

# 특정 포트의 모든 연결
ss -tan 'sport = :8080'       # 소스 포트 8080
ss -tan 'dport = :80'         # 목적지 포트 80

# TIME_WAIT 상태 확인 (포트 고갈 진단)
ss -tan state time-wait | wc -l
# 수천 개면 문제 (Keep-Alive 사용 권장)

실전 시나리오:

# 시나리오 1: "포트가 이미 사용 중입니다" 에러
# → 어떤 프로세스가 포트를 쓰고 있는지 확인
lsof -i :3000
# 출력:
# COMMAND  PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
# node    5678  user   10u  IPv4  0x123  0t0     TCP *:3000 (LISTEN)
# → PID 5678 (node)가 사용 중
# 종료:
kill 5678

# 시나리오 2: 서버가 응답 없음
# → 포트가 LISTEN 상태인지 확인
netstat -an | grep 8080
# tcp4  0  0  *.8080  *.*  LISTEN  ← 정상
# (아무 출력 없음)  ← 서버가 시작 안 됨

# 시나리오 3: 너무 많은 연결로 서버 부하
# → ESTABLISHED 연결 수 확인
ss -s
# TCP: 5000 (estab 4500, closed 100, orphaned 0, timewait 400)
# → 4500개 활성 연결 (너무 많음)
# 연결 제한 또는 스케일 아웃 필요

연결 테스트

# 핑 테스트
ping google.com
ping -c 4 8.8.8.8             # 4번만
# 포트 연결 테스트
telnet example.com 80
nc -zv example.com 80         # netcat
curl -I https://example.com   # HTTP 헤더만
# 경로 추적
traceroute google.com
traceroute -n google.com      # IP만 (DNS 생략)
mtr google.com                # 실시간 traceroute
# DNS 조회
nslookup example.com
dig example.com
dig example.com +short        # IP만
host example.com

curl: HTTP 요청 - API 테스트의 핵심 도구

# GET 요청 (기본)
curl https://api.example.com/users
# 출력: JSON 또는 HTML 응답 본문

curl -i https://example.com   # 헤더 포함 (include headers)
# HTTP/1.1 200 OK
# Content-Type: application/json
# ...
# {"data": "..."}

curl -v https://example.com   # 상세 정보 (verbose)
# > GET / HTTP/1.1  ← 요청 헤더
# < HTTP/1.1 200 OK  ← 응답 헤더
# SSL 핸드셰이크, 리다이렉트 등 모든 과정 출력

curl -I https://example.com   # HEAD 요청 (헤더만)
# 응답 본문 없이 헤더만 받음 (빠름)

# POST 요청 (API 호출)
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John","email":"[email protected]"}'
# -X: HTTP 메서드 지정 (POST, PUT, DELETE 등)
# -H: 헤더 추가
# -d: 데이터 (자동으로 POST로 전환)

# 파일에서 데이터 읽기
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d @data.json
# @: 파일에서 읽기

# 파일 업로드 (multipart/form-data)
curl -F "[email protected]" https://api.example.com/upload
# -F: form data
# @: 파일 경로

curl -F "[email protected]" -F "title=MyPhoto" https://api.example.com/upload
# 여러 필드 전송

# 인증 (Authentication)
curl -u user:pass https://api.example.com
# Basic 인증 (Base64 인코딩됨)

curl -H "Authorization: Bearer TOKEN" https://api.example.com
# Bearer 토큰 (JWT 등)

curl -H "Authorization: Bearer $(cat token.txt)" https://api.example.com
# 파일에서 토큰 읽기

# 쿠키 사용
curl -b "session_id=abc123" https://example.com
# -b: 쿠키 전송

curl -c cookies.txt https://example.com
# -c: 응답 쿠키 저장

curl -b cookies.txt -c cookies.txt https://example.com
# 쿠키 읽고 저장 (세션 유지)

# 응답 저장
curl -o output.html https://example.com
# -o: 지정한 파일명으로 저장

curl -O https://example.com/file.zip  # 원본 파일명으로 저장
# -O: 대문자 O, URL의 마지막 부분을 파일명으로

# 타임아웃 설정 (프로덕션 필수)
curl --connect-timeout 5 https://example.com
# 연결 타임아웃 5초

curl --max-time 10 https://example.com
# 전체 작업 타임아웃 10초

curl --connect-timeout 5 --max-time 30 https://example.com
# 연결 5초, 전체 30초

# 리다이렉트 따라가기
curl -L https://example.com
# -L: 301, 302 리다이렉트 자동 따라감

# SSL 인증서 무시 (테스트 환경만!)
curl -k https://self-signed.example.com
# -k: insecure, 인증서 검증 안 함 (위험!)

# 프록시 사용
curl -x http://proxy.example.com:8080 https://api.example.com
# -x: 프록시 서버

# 속도 측정 (-w: write-out)
curl -X POST http://localhost:3000/api/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"secret"}' \
  -w "\nStatus: %{http_code}\nTime: %{time_total}s\n"
# %{http_code}: HTTP 상태 코드
# %{time_total}: 전체 소요 시간
# %{time_connect}: 연결 시간
# %{size_download}: 다운로드 크기

# 더 상세한 측정
curl -w @curl-format.txt -o /dev/null -s https://example.com
# curl-format.txt:
#     time_namelookup:  %{time_namelookup}s\n
#     time_connect:     %{time_connect}s\n
#     time_appconnect:  %{time_appconnect}s\n
#     time_pretransfer: %{time_pretransfer}s\n
#     time_redirect:    %{time_redirect}s\n
#     time_starttransfer: %{time_starttransfer}s\n
#     time_total:       %{time_total}s\n

# 병렬 요청 (부하 테스트 간단 버전)
for i in {1..100}; do
  curl -s https://api.example.com/health &
done
wait
# 100개 요청 동시 전송

# JSON 응답 파싱 (jq 필요)
curl -s https://api.example.com/users | jq '.[] | .name'
# -s: silent (진행률 숨김)
# jq: JSON 파서

실전 시나리오:

# 시나리오 1: API가 느림, 어느 단계가 문제인지 확인
curl -w "DNS: %{time_namelookup}s, Connect: %{time_connect}s, Total: %{time_total}s\n" \
  -o /dev/null -s https://slow-api.com
# 출력:
# DNS: 0.05s, Connect: 0.5s, Total: 5.2s
# → 네트워크 연결이 느림 (0.5s)

# 시나리오 2: API 응답 검증 (CI/CD)
response=$(curl -s -w "%{http_code}" https://api.example.com/health -o response.txt)
if [ "$response" == "200" ]; then
  echo "✅ API is healthy"
else
  echo "❌ API failed: $response"
  exit 1
fi

# 시나리오 3: API 부하 테스트 (간단 버전)
for i in {1..1000}; do
  (curl -s -w "%{time_total}\n" https://api.example.com -o /dev/null &)
done | awk '{sum += $1; count++} END {print "Avg:", sum/count, "s"}'
# 1000개 요청의 평균 응답 시간 측정

wget: 파일 다운로드

# 파일 다운로드
wget https://example.com/file.zip
wget -O custom_name.zip https://example.com/file.zip
# 재시도 및 백그라운드
wget -c https://example.com/large.iso  # 이어받기
wget -b https://example.com/file.zip   # 백그라운드
# 여러 파일
wget -i urls.txt              # 파일에서 URL 읽기
# 웹사이트 전체 다운로드
wget -r -np -k https://example.com/docs/

4. 프로세스 관리

프로세스 확인

# 모든 프로세스
ps aux                        # BSD 스타일
ps -ef                        # System V 스타일
# 특정 프로세스 검색
ps aux | grep node
pgrep node                    # PID만
pgrep -l node                 # PID와 이름
# 프로세스 트리
ps auxf                       # 리눅스
pstree                        # 트리 구조
pstree -p                     # PID 포함
# 실시간 모니터링
top                           # 기본
top -o cpu                    # CPU 순 정렬 (맥)
htop                          # 개선된 top (설치 필요)
# 특정 프로세스 모니터링
top -p 1234                   # PID 1234만 (리눅스)

프로세스 종료

# 프로세스 종료
kill 1234                     # PID로 종료 (SIGTERM)
kill -9 1234                  # 강제 종료 (SIGKILL)
killall node                  # 이름으로 모두 종료
pkill node                    # 패턴으로 종료
# 포트로 프로세스 찾아 종료
lsof -ti:8080 | xargs kill
kill $(lsof -ti:8080)
# 실전 예제: 좀비 프로세스 정리
ps aux | grep defunct | awk '{print $2}' | xargs kill -9

백그라운드 실행

# 백그라운드 실행
npm start &
nohup npm start &             # 터미널 종료 후에도 실행
nohup npm start > app.log 2>&1 &  # 로그 파일로
# 백그라운드 작업 확인
jobs
jobs -l                       # PID 포함
# 포그라운드로 가져오기
fg %1                         # 작업 번호 1
# 실행 중인 프로세스 일시정지
Ctrl+Z
bg                            # 백그라운드로 재개

5. 로그 분석 및 텍스트 처리

실시간 로그 모니터링

# 실시간 로그
tail -f /var/log/app.log
tail -f -n 100 app.log        # 최근 100줄부터
# 여러 파일 동시 모니터링
tail -f app.log error.log
multitail app.log error.log   # 분할 화면 (설치 필요)
# 패턴 필터링하며 실시간
tail -f app.log | grep "ERROR"
tail -f app.log | grep --line-buffered "ERROR"  # 즉시 출력

로그 분석

# 에러 개수
grep -c "ERROR" app.log
# 시간대별 에러
grep "2026-04-01 14:" app.log | grep "ERROR"
# 상위 에러 유형
grep "ERROR" app.log | awk '{print $5}' | sort | uniq -c | sort -rn
# IP별 요청 수
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
# 응답 시간 분석
awk '{sum += $10; count++} END {print "Avg:", sum/count, "ms"}' app.log
# 특정 시간대 추출
sed -n '/2026-04-01 14:00/,/2026-04-01 15:00/p' app.log

텍스트 정렬 및 중복 제거

# 정렬
sort file.txt
sort -r file.txt              # 역순
sort -n file.txt              # 숫자 정렬
sort -k 2 file.txt            # 2번째 컬럼 기준
# 중복 제거
sort file.txt | uniq
sort file.txt | uniq -c       # 개수 포함
sort file.txt | uniq -d       # 중복만
# 실전 예제: 접속 IP 상위 10개
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

wc: 단어·줄 개수

# 줄 개수
wc -l file.txt
cat file.txt | wc -l
# 단어 개수
wc -w file.txt
# 바이트 크기
wc -c file.txt
# 실전 예제
find . -name "*.js" | wc -l   # JS 파일 개수
grep "ERROR" app.log | wc -l  # 에러 개수

6. 네트워크 디버깅 심화

패킷 캡처 및 분석

# tcpdump (root 권한 필요)
sudo tcpdump -i eth0          # eth0 인터페이스
sudo tcpdump -i any port 80   # 모든 인터페이스, 포트 80
sudo tcpdump -i eth0 -w capture.pcap  # 파일로 저장
sudo tcpdump -r capture.pcap  # 파일 읽기
# 특정 호스트
sudo tcpdump host 192.168.1.100
sudo tcpdump src 192.168.1.100
sudo tcpdump dst 192.168.1.100
# HTTP 요청 보기
sudo tcpdump -i any -A port 80 | grep "GET\|POST"

네트워크 속도 테스트

# 다운로드 속도
curl -o /dev/null -w "Speed: %{speed_download} bytes/sec\n" https://example.com/file.zip
# 대역폭 측정
iperf3 -c server_ip           # 클라이언트
iperf3 -s                     # 서버
# ping 통계
ping -c 100 google.com | tail -3

방화벽 확인

# iptables (리눅스)
sudo iptables -L
sudo iptables -L -n -v        # 상세
# ufw (Ubuntu)
sudo ufw status
sudo ufw allow 22/tcp
sudo ufw deny 80/tcp
# firewalld (CentOS/RHEL)
sudo firewall-cmd --list-all
sudo firewall-cmd --add-port=8080/tcp --permanent

7. 디스크 및 시스템 정보

디스크 사용량

# 전체 디스크
df -h                         # 사람이 읽기 쉽게
df -h /                       # 루트 파티션만
df -i                         # inode 사용량
# 디렉토리별 크기
du -sh *                      # 현재 디렉토리 하위
du -sh /var/log/*             # 로그 디렉토리
du -h --max-depth=1 /var      # 1단계까지
# 큰 디렉토리 찾기
du -sh * | sort -rh | head -10
du -ah / | sort -rh | head -20  # 파일 포함
# 실전 예제: 디스크 풀 때
df -h                         # 어느 파티션?
du -sh /var/log/* | sort -rh  # 로그 확인
find /var/log -name "*.log" -mtime +30 -size +100M  # 오래된 큰 로그

시스템 정보

# OS 정보
uname -a                      # 전체 정보
uname -r                      # 커널 버전
cat /etc/os-release           # 리눅스 배포판
sw_vers                       # 맥 버전
# CPU 정보
lscpu                         # 리눅스
sysctl -n machdep.cpu.brand_string  # 맥
cat /proc/cpuinfo             # 리눅스
# 메모리 정보
free -h                       # 리눅스
vm_stat                       # 맥
cat /proc/meminfo             # 리눅스
# 가동 시간
uptime
uptime -p                     # 사람이 읽기 쉽게

시스템 리소스 모니터링

# 실시간 리소스
top
htop                          # 개선된 버전
glances                       # 종합 모니터링
# I/O 모니터링
iostat                        # CPU·디스크 I/O
iostat -x 2                   # 2초마다 상세
iotop                         # 프로세스별 I/O (root)
# 네트워크 I/O
iftop                         # 실시간 네트워크 (root)
nethogs                       # 프로세스별 네트워크

8. 권한 및 소유자 관리

권한 변경

# chmod: 권한 변경
chmod 755 script.sh           # rwxr-xr-x
chmod +x script.sh            # 실행 권한 추가
chmod -R 644 files/           # 재귀적으로
# 숫자 의미
# 4 = 읽기(r), 2 = 쓰기(w), 1 = 실행(x)
# 755 = rwxr-xr-x (소유자 7, 그룹 5, 기타 5)
# 644 = rw-r--r-- (소유자 6, 그룹 4, 기타 4)
# 실전 예제
chmod 600 ~/.ssh/id_rsa       # SSH 키 권한
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh

소유자 변경

# chown: 소유자 변경
sudo chown user file.txt
sudo chown user:group file.txt
sudo chown -R user:group dir/
# 실전 예제
sudo chown -R www-data:www-data /var/www/html
sudo chown -R $USER:$USER ~/project

권한 확인

# 상세 권한
ls -l file.txt
stat file.txt                 # 더 상세
# 실행 가능 파일 찾기
find . -type f -perm -111
find . -type f -executable

9. 압축 및 아카이브

tar: 압축·해제

# 압축
tar -czf archive.tar.gz dir/  # gzip
tar -cjf archive.tar.bz2 dir/ # bzip2
tar -cJf archive.tar.xz dir/  # xz (더 작음)
# 해제
tar -xzf archive.tar.gz
tar -xzf archive.tar.gz -C /path/to/dest  # 특정 위치
# 내용 확인 (해제 안 함)
tar -tzf archive.tar.gz
tar -tzf archive.tar.gz | grep "file"
# 실전 예제: 백업
tar -czf backup-$(date +%Y%m%d).tar.gz ~/project
tar -czf - ~/project | ssh user@remote "cat > backup.tar.gz"

zip: 압축·해제

# 압축
zip archive.zip file1.txt file2.txt
zip -r archive.zip dir/       # 디렉토리
# 해제
unzip archive.zip
unzip archive.zip -d dest/    # 특정 위치
unzip -l archive.zip          # 내용 확인
# 암호화
zip -e secure.zip file.txt

gzip, bzip2

# gzip
gzip file.txt                 # file.txt.gz 생성 (원본 삭제)
gzip -k file.txt              # 원본 유지
gunzip file.txt.gz            # 해제
# bzip2
bzip2 file.txt
bunzip2 file.txt.bz2
# 압축률 비교
gzip file.txt    # 빠름, 보통 압축
bzip2 file.txt   # 느림, 높은 압축
xz file.txt      # 가장 느림, 최고 압축

10. 개발 환경 설정

환경 변수

# 환경 변수 확인
env                           # 모든 환경 변수
echo $PATH
echo $HOME
printenv PATH
# 환경 변수 설정
export API_KEY="secret"
export PATH="$PATH:/new/path"
# 영구 설정 (bash)
echo 'export API_KEY="secret"' >> ~/.bashrc
source ~/.bashrc
# 영구 설정 (zsh)
echo 'export API_KEY="secret"' >> ~/.zshrc
source ~/.zshrc

SSH

# SSH 접속
ssh user@hostname
ssh -p 2222 user@hostname     # 포트 지정
ssh -i ~/.ssh/key.pem user@hostname  # 키 파일
# SSH 키 생성
ssh-keygen -t ed25519 -C "[email protected]"
ssh-keygen -t rsa -b 4096
# 공개키 복사
ssh-copy-id user@hostname
cat ~/.ssh/id_rsa.pub | ssh user@hostname "cat >> ~/.ssh/authorized_keys"
# SSH 터널링
ssh -L 8080:localhost:80 user@remote  # 로컬 포트 포워딩
ssh -R 8080:localhost:3000 user@remote  # 리모트 포트 포워딩
# SCP: 파일 복사
scp file.txt user@remote:/path/
scp -r dir/ user@remote:/path/
scp user@remote:/path/file.txt ./

Git 관련 명령어

# 브랜치 정리
git branch -d old-branch
git branch -D force-delete
git remote prune origin       # 삭제된 리모트 브랜치 정리
# 로그 한 줄로
git log --oneline -10
git log --graph --oneline --all
# 변경 사항 확인
git diff
git diff --staged
git diff HEAD~1 HEAD
# 실전 예제: 특정 파일 히스토리
git log -p -- path/to/file.txt
git log --follow -- file.txt  # 이름 변경 추적

Docker 관련

# 컨테이너 관리
docker ps                     # 실행 중
docker ps -a                  # 모든 컨테이너
docker logs -f container_id   # 로그 실시간
docker exec -it container_id bash  # 컨테이너 접속
# 이미지 관리
docker images
docker rmi image_id
docker system prune -a        # 미사용 정리
# 실전 예제: 디버깅
docker logs --tail 100 -f container_id
docker exec -it container_id sh -c "ps aux"
docker stats                  # 리소스 사용량

11. 실전 시나리오별 명령어 조합

시나리오 1: “포트 8080이 이미 사용 중”

# 1. 포트 사용 프로세스 확인
lsof -i :8080
# 또는
netstat -tuln | grep 8080
# 2. PID 확인 후 종료
kill $(lsof -ti:8080)
# 3. 재확인
lsof -i :8080

시나리오 2: “서버가 느려요”

# 1. CPU·메모리 확인
top
htop
# 2. 디스크 I/O 확인
iostat -x 2
# 3. 네트워크 확인
iftop
nethogs
# 4. 로그 확인
tail -f /var/log/app.log | grep "ERROR\|WARN"
# 5. 프로세스별 리소스
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10

시나리오 3: “디스크가 꽉 찼어요”

# 1. 디스크 사용량 확인
df -h
# 2. 큰 디렉토리 찾기
du -sh /* | sort -rh | head -10
du -sh /var/* | sort -rh
# 3. 큰 파일 찾기
find / -type f -size +1G 2>/dev/null
find /var/log -name "*.log" -size +100M
# 4. 오래된 로그 삭제
find /var/log -name "*.log" -mtime +30 -delete
find /tmp -mtime +7 -delete
# 5. Docker 정리 (개발 환경)
docker system prune -a
docker volume prune

시나리오 4: “API가 응답 안 해요”

# 1. 서비스 실행 확인
ps aux | grep node
systemctl status myapp        # systemd
# 2. 포트 리스닝 확인
lsof -i :3000
netstat -tuln | grep 3000
# 3. 로컬 연결 테스트
curl http://localhost:3000/health
curl -v http://localhost:3000
# 4. 외부 연결 테스트
curl http://server-ip:3000
telnet server-ip 3000
# 5. 방화벽 확인
sudo iptables -L
sudo ufw status
# 6. 로그 확인
tail -f /var/log/app.log
journalctl -u myapp -f        # systemd

시나리오 5: “특정 에러 로그만 추출”

# 1. 시간대별 에러
grep "2026-04-01 14:" app.log | grep "ERROR" > errors.txt
# 2. 에러 유형별 분류
grep "ERROR" app.log | awk '{print $5}' | sort | uniq -c | sort -rn
# 3. 특정 에러만
grep "NullPointerException" app.log > null_errors.txt
# 4. 컨텍스트 포함
grep -A 10 "ERROR" app.log > errors_with_context.txt
# 5. 여러 파일에서
grep -r "ERROR" /var/log/app/*.log | grep "database"

시나리오 6: “배포 스크립트 자동화”

#!/bin/bash
# deploy.sh
set -e  # 에러 시 중단
echo "🚀 배포 시작..."
# 1. Git 최신 코드
git pull origin main
# 2. 의존성 설치
npm ci
# 3. 빌드
npm run build
# 4. 기존 프로세스 종료
pkill -f "node.*server.js" || true
# 5. 백업
tar -czf backup-$(date +%Y%m%d-%H%M%S).tar.gz dist/
# 6. 새 프로세스 시작
nohup npm start > app.log 2>&1 &
# 7. 헬스 체크
sleep 5
curl -f http://localhost:3000/health || exit 1
echo "✅ 배포 완료"

시나리오 7: “로그 로테이션 수동”

# 1. 현재 로그 백업
cp app.log app.log.$(date +%Y%m%d)
# 2. 로그 비우기
> app.log
# 또는
truncate -s 0 app.log
# 3. 오래된 백업 삭제
find . -name "app.log.*" -mtime +30 -delete
# 4. 압축
gzip app.log.20260301

12. 고급 팁 및 트릭

파이프 조합

# 프로세스 메모리 사용량 상위 10개
ps aux | awk '{print $4, $11}' | sort -rn | head -10
# 접속 IP별 요청 수
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn
# 에러율 계산
total=$(wc -l < app.log)
errors=$(grep -c "ERROR" app.log)
echo "scale=2; $errors / $total * 100" | bc
# 디렉토리별 파일 개수
find . -type f | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn

유용한 별칭 (alias)

# ~/.bashrc 또는 ~/.zshrc에 추가
alias ll='ls -lah'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
alias grep='grep --color=auto'
alias ports='lsof -i -P -n | grep LISTEN'
alias myip='curl ifconfig.me'
alias serve='python3 -m http.server 8000'
# Git 별칭
alias gs='git status'
alias ga='git add'
alias gc='git commit -m'
alias gp='git push'
alias gl='git log --oneline -10'
# Docker 별칭
alias dps='docker ps'
alias dpa='docker ps -a'
alias di='docker images'
alias dlog='docker logs -f'

히스토리 활용

# 명령어 히스토리
history
history | grep "docker"
# 히스토리 재실행
!123                          # 123번 명령어
!!                            # 직전 명령어
!$                            # 직전 명령어의 마지막 인자
!*                            # 직전 명령어의 모든 인자
# 실전 예제
sudo !!                       # 직전 명령어를 sudo로
ls /var/log
cd !$                         # cd /var/log

파일 비교

# diff: 파일 비교
diff file1.txt file2.txt
diff -u file1.txt file2.txt   # unified 형식
diff -y file1.txt file2.txt   # 나란히
# 디렉토리 비교
diff -r dir1/ dir2/
# 바이너리 비교
cmp file1.bin file2.bin

파일 검색 고급

# locate (DB 기반, 빠름)
locate file.txt
sudo updatedb                 # DB 업데이트
# which: 실행 파일 경로
which python
which -a python               # 모든 경로
# whereis: 바이너리·소스·매뉴얼
whereis python

13. 자주 쓰는 단축키

터미널 단축키

Ctrl+C          현재 명령어 중단
Ctrl+Z          현재 프로세스 일시정지
Ctrl+D          EOF (로그아웃)
Ctrl+L          화면 지우기 (clear)
Ctrl+A          줄 맨 앞으로
Ctrl+E          줄 맨 뒤로
Ctrl+U          커서 앞 전부 삭제
Ctrl+K          커서 뒤 전부 삭제
Ctrl+W          단어 하나 삭제
Ctrl+R          명령어 히스토리 검색
Ctrl+S          출력 일시정지
Ctrl+Q          출력 재개

커서 이동

Alt+B           단어 하나 뒤로
Alt+F           단어 하나 앞으로
Ctrl+XX         줄 맨 앞과 현재 위치 토글

14. 시스템 관리 (systemd)

서비스 관리

# 서비스 상태
systemctl status nginx
systemctl status myapp
# 서비스 시작·정지
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx   # 설정만 리로드
# 부팅 시 자동 시작
sudo systemctl enable nginx
sudo systemctl disable nginx
# 로그 확인
journalctl -u nginx
journalctl -u nginx -f        # 실시간
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx --since "2026-04-01 14:00"

서비스 파일 작성

# /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/usr/bin/node server.js
Restart=always
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
# 서비스 등록
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

15. 성능 분석 및 디버깅

strace: 시스템 콜 추적

# 프로세스 추적
strace ls
strace -p 1234                # 실행 중인 프로세스
# 파일 I/O만
strace -e open,read,write ls
# 시간 측정
strace -c ls                  # 통계
strace -T ls                  # 각 호출 시간
# 실전 예제: 설정 파일 찾기
strace -e open myapp 2>&1 | grep "config"

ldd: 라이브러리 의존성

# 실행 파일 의존성
ldd /usr/bin/python3
ldd myapp
# 실전 예제: 누락된 라이브러리 찾기
ldd myapp | grep "not found"

네트워크 디버깅 고급

# 연결 상태별 개수
netstat -an | awk '/tcp/ {print $6}' | sort | uniq -c
# TIME_WAIT 많을 때
netstat -an | grep TIME_WAIT | wc -l
# 특정 IP 연결 수
netstat -an | grep 192.168.1.100 | wc -l
# 실전 예제: DDoS 의심 시
netstat -an | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20

16. 자주 쓰는 원라이너 (One-liners)

파일 처리

# 빈 줄 제거
grep -v '^$' file.txt
# 중복 줄 제거
sort file.txt | uniq
# 파일 합치기
cat file1.txt file2.txt > merged.txt
# CSV 특정 컬럼
awk -F',' '{print $2}' data.csv
# JSON 파싱 (jq 필요)
curl https://api.example.com/users | jq '.[] | .name'
cat data.json | jq '.users[0].email'

시스템 모니터링

# CPU 사용률 상위 10개
ps aux | sort -rk 3 | head -10
# 메모리 사용률 상위 10개
ps aux | sort -rk 4 | head -10
# 디스크 사용률 80% 이상
df -h | awk '$5+0 > 80 {print $0}'
# 좀비 프로세스 찾기
ps aux | awk '$8=="Z" {print $0}'

네트워크

# 외부 IP
curl -s ifconfig.me
# 포트 스캔
nc -zv example.com 80-443
# DNS 전파 확인
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
# 응답 시간 측정
time curl https://example.com > /dev/null

로그 분석

# 시간대별 요청 수
awk '{print $4}' access.log | cut -d: -f2 | sort | uniq -c
# 상태 코드별 개수
awk '{print $9}' access.log | sort | uniq -c
# 느린 요청 찾기
awk '$10 > 1000 {print $0}' app.log  # 1000ms 이상
# 에러 로그만 추출
grep -E "ERROR|FATAL" app.log > errors.txt

17. 맥 전용 명령어

맥 시스템 관리

# 앱 목록
ls /Applications
# Homebrew
brew install package
brew update
brew upgrade
brew list
brew search keyword
# 서비스 관리 (brew services)
brew services list
brew services start postgresql
brew services stop postgresql
# 맥 정보
sw_vers
system_profiler SPHardwareDataType

맥 네트워크

# 네트워크 인터페이스
networksetup -listallhardwareports
networksetup -getinfo Wi-Fi
# DNS 캐시 클리어
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# 열린 파일·포트
lsof -i -P -n | grep LISTEN

18. 리눅스 전용 명령어

패키지 관리

# Ubuntu/Debian (apt)
sudo apt update
sudo apt upgrade
sudo apt install package
sudo apt remove package
sudo apt autoremove
# CentOS/RHEL (yum/dnf)
sudo yum update
sudo yum install package
sudo dnf install package
# 패키지 검색
apt search keyword
yum search keyword

systemd 고급

# 실패한 서비스
systemctl --failed
# 부팅 시간 분석
systemd-analyze
systemd-analyze blame         # 서비스별 시간
# 로그 크기 제한
journalctl --disk-usage
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M

19. 개발자 필수 도구

설치 권장 도구

# 리눅스
sudo apt install -y \
  curl wget git vim \
  htop tree ncdu \
  net-tools dnsutils \
  jq ripgrep fd-find \
  tmux
# 맥
brew install \
  curl wget git vim \
  htop tree ncdu \
  jq ripgrep fd \
  tmux fzf bat

도구별 용도

도구용도예제
ripgrep빠른 검색rg "error" src/
fd빠른 파일 찾기fd "\.js$"
jqJSON 파싱cat data.json | jq '.name'
batcat 개선bat file.txt
ncdu디스크 사용량 UIncdu /var
tmux터미널 멀티플렉서tmux new -s dev
fzf퍼지 파인더history | fzf

ripgrep (rg) 예제

# grep보다 빠름
rg "error" src/
rg -i "error"                 # 대소문자 무시
rg -l "TODO"                  # 파일명만
rg -t js "import"             # JS 파일만
rg "error" -g "*.log"         # 로그 파일만
rg -A 5 "error"               # 후 5줄

fd 예제

# find보다 빠르고 간단
fd "\.js$"
fd -e js                      # 확장자
fd -t f                       # 파일만
fd -t d                       # 디렉토리만
fd -H "\.env"                 # 숨김 파일 포함
fd -E node_modules            # 제외

20. 보안 관련 명령어

SSH 보안

# SSH 로그인 시도 확인
sudo grep "Failed password" /var/log/auth.log
sudo grep "Accepted" /var/log/auth.log
# IP별 실패 횟수
sudo grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
# 현재 SSH 세션
who
w
last                          # 로그인 히스토리

파일 무결성

# 체크섬
md5sum file.txt               # 리눅스
md5 file.txt                  # 맥
shasum -a 256 file.txt        # SHA-256
# 파일 비교
md5sum file1.txt file2.txt

열린 포트 스캔

# nmap (설치 필요)
nmap localhost
nmap -p 1-65535 localhost     # 모든 포트
nmap -sV localhost            # 서비스 버전

21. 실전 체크리스트

서버 배포 전 체크

# 1. 디스크 공간
df -h
# 2. 메모리
free -h
# 3. 포트 충돌
lsof -i :8080
# 4. 방화벽
sudo ufw status
# 5. 로그 로테이션 설정
ls -lh /var/log/*.log
# 6. 환경 변수
env | grep API_KEY
# 7. 권한
ls -l /var/www/html

장애 대응 체크

# 1. 서비스 상태
systemctl status myapp
# 2. 최근 로그
journalctl -u myapp -n 100
# 3. 리소스
top
df -h
# 4. 네트워크
netstat -tuln | grep LISTEN
curl http://localhost:3000/health
# 5. 프로세스
ps aux | grep myapp

22. 정리

카테고리별 핵심 명령어

카테고리명령어용도
디렉토리cd, pwd, ls, tree탐색
파일cat, less, head, tail내용 보기
검색grep, find, rg, fd파일·텍스트 찾기
텍스트awk, sed, cut, sort처리·변환
네트워크curl, netstat, lsof, ss연결·포트
프로세스ps, top, kill, htop관리·모니터링
디스크df, du, ncdu사용량
압축tar, gzip, zip아카이브
권한chmod, chown, sudo접근 제어
시스템systemctl, journalctl서비스 관리

자주 쓰는 조합 패턴

# 로그 실시간 에러 모니터링
tail -f app.log | grep --line-buffered "ERROR"
# 프로세스 메모리 사용량
ps aux | awk '{print $4, $11}' | sort -rn | head -10
# 포트 사용 프로세스 종료
kill $(lsof -ti:8080)
# 디스크 큰 파일 찾기
du -ah / 2>/dev/null | sort -rh | head -20
# 접속 IP 상위 10개
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10

학습 팁

  1. man 페이지 활용: man ls, man grep
  2. tldr 설치: 간단한 예제 보기 (npm install -g tldr)
  3. 히스토리 검색: Ctrl+R로 이전 명령어 빠르게 찾기
  4. 별칭 설정: 자주 쓰는 명령어는 ~/.bashrc에 별칭 추가
  5. 스크립트 작성: 반복 작업은 쉘 스크립트로 자동화

23. 실전 예제: 문제 해결 시나리오

예제 1: Node.js 앱이 시작 안 됨

# 1. 포트 충돌 확인
lsof -i :3000
# 출력: node 1234 user ....*:3000 (LISTEN)
# 2. 프로세스 종료
kill 1234
# 3. 재시작
npm start
# 4. 로그 확인
tail -f logs/app.log

예제 2: 디스크 풀 때

# 1. 사용량 확인
df -h
# 출력: /dev/sda1 98% 사용
# 2. 큰 디렉토리 찾기
du -sh /* | sort -rh | head -5
# 출력: /var/log 15GB
# 3. 로그 확인
du -sh /var/log/* | sort -rh
# 출력: app.log 10GB
# 4. 오래된 로그 삭제
find /var/log -name "*.log" -mtime +7 -size +100M -delete
# 5. 재확인
df -h

예제 3: API 응답 느림

# 1. 프로세스 리소스 확인
top -p $(pgrep -d',' node)
# 2. 네트워크 연결 수
netstat -an | grep :3000 | grep ESTABLISHED | wc -l
# 3. 응답 시간 측정
time curl http://localhost:3000/api/users
# 4. 로그에서 느린 요청
awk '$10 > 1000 {print $0}' app.log
# 5. 데이터베이스 연결 확인
lsof -i :5432                 # PostgreSQL

예제 4: 메모리 누수 의심

# 1. 메모리 사용량 추이
while true; do
  ps aux | grep myapp | awk '{print $4, $6}'
  sleep 60
done
# 2. 상세 메모리 정보
pmap 1234                     # PID 1234
cat /proc/1234/status | grep VmRSS
# 3. 힙 프로파일링 (Node.js)
node --inspect server.js
# Chrome DevTools로 연결
# 4. 재시작 후 비교
systemctl restart myapp

24. 정리 및 다음 단계

핵심 요약

매일 쓰는 10개:

  1. ls -lah — 파일 목록
  2. cd — 디렉토리 이동
  3. grep — 텍스트 검색
  4. tail -f — 로그 실시간
  5. ps aux | grep — 프로세스 찾기
  6. lsof -i — 포트 확인
  7. curl — HTTP 요청
  8. df -h — 디스크 사용량
  9. top — 리소스 모니터링
  10. systemctl status — 서비스 상태 문제 해결 흐름:
  11. 로그 확인: tail -f, journalctl
  12. 리소스 확인: top, df, free
  13. 네트워크 확인: lsof, netstat, curl
  14. 프로세스 확인: ps, pgrep
  15. 재시작: systemctl restart

학습 자료

온라인 연습:

  • explainshell.com — 명령어 분해 설명
  • tldr.sh — 간단한 예제
  • commandlinefu.com — 커뮤니티 원라이너 :
  • “The Linux Command Line” by William Shotts
  • “Unix and Linux System Administration Handbook”

다음 단계

명령어에 익숙해지면:

  1. 자주 쓰는 명령어 10개 선택
  2. ~/.bashrc에 별칭 추가
  3. 배포 스크립트 작성
  4. 모니터링 대시보드 구축

자주 묻는 질문 (FAQ)

Q. 명령어를 외워야 하나요?

A. 자주 쓰는 10~20개만 외우고, 나머지는 필요할 때 찾아 쓰세요. man 명령어나 tldr로 빠르게 확인할 수 있습니다.

Q. 리눅스와 맥 명령어 차이는?

A. 대부분 동일하지만, GNU(리눅스)와 BSD(맥) 버전 차이가 있습니다. 예: sed -i (리눅스) vs sed -i ' (맥). 이 글에서는 공통 명령어를 우선 소개했습니다.

Q. Windows에서는 못 쓰나요?

A. WSL(Windows Subsystem for Linux), Git Bash, PowerShell 일부 명령어로 사용 가능합니다. 또는 Docker 컨테이너에서 리눅스 환경을 실행하세요. 한 줄 요약: 개발 현장에서 매일 쓰는 리눅스·맥 명령어를 실전 예제로 정리한 치트시트입니다. 관련 글:

심화 부록: 구현·운영 관점

이 부록은 앞선 본문에서 다룬 주제(「개발자를 위한 리눅스·맥 명령어 실전 가이드 | 네트워크·파일·프로세스·디버깅」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.

내부 동작과 핵심 메커니즘

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]
sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(런타임·게이트웨이·프로세스)
  participant D as 의존성(API·DB·큐·파일)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)
  • 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.

프로덕션 운영 패턴

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가
용량피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.

확장 예시: 엔드투엔드 미니 시나리오

앞선 본문 주제(「개발자를 위한 리눅스·맥 명령어 실전 가이드 | 네트워크·파일·프로세스·디버깅」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)
  authorize(validated, ctx)
  result = domainCore(validated)
  persistOrEmit(result, idempotentKey)
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정 불일치프로필·시크릿·기본값, 리전스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

배포 전에는 git addgit commitgit pushnpm run deploy 순서를 권장합니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

리눅스, , 터미널, 명령어, CLI, 네트워크, 디버깅, 개발자도구, bash, shell 등으로 검색하시면 이 글이 도움이 됩니다.