파일시스템
권한
프로세스
APT / systemd
SSH / 네트워크
압축 / 파이프
명령어 기본 구조
리눅스 명령어는 대부분 명령어 옵션 인자 순서로 구성됩니다. 옵션은 -x(짧은 형식) 또는 --xxxx(긴 형식)로 쓰며, 여러 짧은 옵션은 -la처럼 붙여 쓸 수 있습니다.
command
[옵션]
[인자/경로]
# 예시
ls
-l -a
/home/ubuntu
# == ls -la /home/ubuntu
알아두면 편한 습관
man 명령어 로 해당 명령어의 매뉴얼(도움말)을 바로 확인할 수 있습니다. 예: man chmod
- 명령어나 옵션이 기억나지 않을 땐
명령어 --help 로 간단한 사용법을 볼 수 있습니다.
- Tab 키로 파일/디렉토리 이름 자동완성, ↑/↓ 키로 이전 명령어 기록 탐색이 가능합니다.
sudo가 붙은 명령어는 시스템 전체에 영향을 줄 수 있으니 실행 전 한 번 더 확인하는 습관을 들이세요.
필수 명령어 한눈에 보기
아래 표는 우분투(및 대부분의 리눅스 배포판)에서 가장 자주 사용하는 핵심 명령어 모음입니다. 각 항목의 자세한 사용법은 사이드바의 해당 섹션에서 예제와 함께 설명합니다.
| 명령어 | 분류 | 설명 및 사용 예 |
| pwd | 탐색 | 현재 작업 디렉토리의 절대 경로를 출력 |
| cd | 탐색 | 디렉토리 이동. cd ..(상위), cd ~(홈) |
| ls | 탐색 | 파일 목록 조회. ls -la로 숨김파일까지 상세히 |
| mkdir | 파일 | 디렉토리 생성. mkdir -p a/b/c로 중첩 생성 |
| touch | 파일 | 빈 파일 생성 또는 수정 시각 갱신 |
| cp | 파일 | 파일/디렉토리 복사. cp -r로 디렉토리 전체 복사 |
| mv | 파일 | 이동 또는 이름 변경 |
| rm | 파일 | 삭제. rm -rf는 강제 삭제(복구 불가, 매우 주의) |
| cat / less | 조회 | 파일 전체 출력(cat) / 페이지 단위로 보기(less) |
| grep | 조회 | 텍스트에서 패턴 검색. grep -r "text" . |
| find | 조회 | 조건에 맞는 파일 탐색. find . -name "*.py" |
| chmod | 권한 | 파일 접근 권한 변경. chmod 755 app.sh |
| chown | 권한 | 파일 소유자/그룹 변경. chown ubuntu:ubuntu file |
| sudo | 권한 | 관리자(root) 권한으로 명령어 실행 |
| ps / top | 프로세스 | 실행 중인 프로세스 확인. top은 실시간 모니터링 |
| kill | 프로세스 | 프로세스 종료. kill -9 PID는 강제 종료 |
| df / du | 시스템 | 디스크 여유 공간(df) / 사용량(du) 확인 |
| free -h | 시스템 | 메모리(RAM) 사용량 확인 |
| apt | 패키지 | 패키지 설치/삭제/업데이트. sudo apt install nginx |
| systemctl | 서비스 | 서비스 시작/중지/상태 확인. systemctl status nginx |
| ssh / scp | 네트워크 | 원격 서버 접속(ssh) / 원격 파일 전송(scp) |
| tar | 압축 | 아카이브 생성·해제. tar -czvf a.tar.gz dir/ |
| history | 기타 | 최근 실행한 명령어 목록 조회 |
탐색: pwd / cd / ls
파일시스템을 이동하고 현재 위치와 내용을 확인하는 가장 기본적인 명령어입니다.
pwd로 현재 경로를 확인하고, cd로 원하는 디렉토리로 이동합니다.
$pwd
# /home/ubuntu/offset0xf/school
$cd projects/
$cd .. # 상위 디렉토리로
$cd ~ # 홈 디렉토리로
$cd - # 바로 직전 디렉토리로
실행 결과
/home/ubuntu/offset0xf/school
-l은 상세 정보(권한·소유자·크기·수정일), -a는 숨김 파일(.으로 시작)까지 표시합니다.
실행 결과
drwxr-xr-x 4 ubuntu ubuntu 4096 Aug 16 09:00 .
drwxr-xr-x 10 ubuntu ubuntu 4096 Aug 16 09:00 ..
-rw-r--r-- 1 ubuntu ubuntu 1820 Aug 15 21:11 simple_routes.py
-rwxr-xr-x 1 ubuntu ubuntu 980 Aug 14 18:03 deploy.sh
ls -l 결과 읽는 법
- 맨 앞
d는 디렉토리, -는 일반 파일, l은 심볼릭 링크를 의미합니다.
- 다음 9자리
rwxr-xr-x는 소유자/그룹/전체 사용자 각각의 읽기(r)·쓰기(w)·실행(x) 권한입니다. 자세한 내용은 권한 관리 섹션 참고.
- 그 뒤로 소유자, 그룹, 파일 크기(byte), 수정 날짜, 파일명 순서로 표시됩니다.
생성·복사·이동·삭제
파일과 디렉토리를 다루는 명령어입니다. 특히 rm은 휴지통을 거치지 않고 즉시 삭제되므로 각별히 주의해야 합니다.
mkdir -p는 중간 경로가 없어도 한 번에 만들어줍니다.
$mkdir -p logs/2026/august
$touch logs/2026/august/access.log
실행 결과
logs/2026/august/access.log # 빈 파일 생성 완료
디렉토리를 복사할 땐 -r(재귀) 옵션이 필수입니다. mv는 대상이 있으면 덮어씁니다.
$cp requirements.txt requirements.txt.bak
$cp -r templates/ templates_backup/
$mv old_name.py new_name.py # 이름 변경
실행 결과
requirements.txt.bak, templates_backup/, new_name.py # 생성/변경 완료
삭제된 파일은 복구할 수 없습니다. -i(확인 질문)를 습관화하거나, 삭제 전 반드시 경로를 재확인하세요.
$rm old_name.py.bak # 파일 하나 삭제
$rm -r templates_backup/ # 디렉토리 재귀 삭제
$rm -rf /some/path # 확인 없이 강제 삭제 — 매우 위험
경고
rm -rf 는 되돌릴 수 없습니다. 경로 앞에 공백/오타가 있으면 의도치 않은 위치가 통째로 삭제될 수 있습니다.
rm -rf 사용 전 체크리스트
rm -rf /, rm -rf ~, rm -rf .* 처럼 광범위한 경로는 절대 그대로 실행하지 마세요.
- 변수를 조합해 경로를 만든다면(
rm -rf $DIR/*) $DIR이 비어있지 않은지 먼저 echo $DIR로 확인하세요.
- 확신이 없다면
rm 대신 mv 대상 /tmp/trash/로 옮겨두고 나중에 지우는 것이 안전합니다.
파일 내용 보기 & 검색
로그 파일을 읽거나 코드 안에서 특정 문자열/파일을 찾을 때 가장 많이 쓰는 명령어들입니다.
| 명령어 | 이름 | 설명 및 사용 예 |
| cat | 전체 출력 | 파일 내용을 한 번에 출력. cat access.log |
| less | 페이지 보기 | 긴 파일을 스크롤하며 확인. q로 종료, /word로 검색 |
| head / tail | 일부 출력 | 앞/뒤 N줄만 출력. tail -n 50 -f access.log(실시간) |
| grep | 패턴 검색 | 텍스트에서 문자열/정규식 검색. -r로 하위 디렉토리 전체 검색 |
| find | 파일 탐색 | 이름·크기·수정일 등 조건으로 파일 탐색 |
| wc -l | 라인 수 | 파일의 줄 수 세기. wc -l app.py |
gunicorn/nginx 로그처럼 계속 쌓이는 파일을 실시간으로 확인할 때 사용합니다. Ctrl+C로 종료합니다.
$tail -f /var/log/nginx/access.log
실행 결과 (계속 갱신됨)
43.203.123.184 - - [16/Aug/2026:09:12:03] "GET /market HTTP/1.1" 200
43.203.123.184 - - [16/Aug/2026:09:12:05] "GET /timetable HTTP/1.1" 200
-r(재귀), -n(줄 번호), -i(대소문자 무시)를 함께 자주 씁니다.
$grep -rn "APIRouter" projects/
실행 결과
:5:router = APIRouter()
:8:router = APIRouter()
이름 패턴, 파일 타입, 수정 시각 등 다양한 조건으로 검색할 수 있습니다.
$find . -name "*.py"
$find . -mtime -1 # 24시간 이내 수정된 파일
$find . -name "__pycache__" -exec rm -rf {} +
실행 결과
./main.py
./projects/simple_routes.py
./projects/admin_auth.py
권한 관리 (chmod / chown)
리눅스의 모든 파일은 소유자(owner) · 그룹(group) · 전체(others) 세 주체에 대해 읽기(r=4)·쓰기(w=2)·실행(x=1) 권한을 가집니다. 세 숫자를 더한 값으로 chmod에 전달합니다.
chmod
755
app.sh
# 7(rwx=4+2+1) 소유자 / 5(r-x=4+1) 그룹 / 5(r-x=4+1) 전체
| 숫자 | 권한 | 설명 |
| 7 | rwx | 읽기+쓰기+실행 모두 허용 |
| 6 | rw- | 읽기+쓰기만 (실행 불가) |
| 5 | r-x | 읽기+실행만 (쓰기 불가) — 디렉토리 접근에 필요 |
| 4 | r-- | 읽기 전용 |
| 644 | rw-r--r-- | 일반 파일의 흔한 기본값 (소유자만 수정 가능) |
| 755 | rwxr-xr-x | 실행 스크립트/디렉토리의 흔한 기본값 |
배포 스크립트에 실행 권한을 주고, venv 등 사용자 소유가 아닌 파일의 소유자를 맞출 때 사용합니다.
$chmod +x deploy.sh # 기존 권한에 실행 권한만 추가
$sudo chown -R ubuntu:ubuntu /home/ubuntu/offset0xf/school
실행 결과
-rwxr-xr-x 1 ubuntu ubuntu 980 Aug 16 09:00 deploy.sh
chmod 777 을 피해야 하는 이유
777은 모든 사용자에게 읽기·쓰기·실행 권한을 전부 허용합니다. 웹서버 파일에 적용하면 누구나 코드를 덮어쓸 수 있는 심각한 보안 취약점이 됩니다.
- "권한 오류가 나서 777로 풀었다"는 임시방편은 대부분 근본 원인(소유자 불일치 등)을 숨길 뿐입니다.
chown으로 소유자를 맞추는 것이 올바른 해결책입니다.
사용자 & sudo
우분투 서버는 root 계정으로 직접 로그인하지 않고, 일반 사용자가 sudo로 필요한 순간만 관리자 권한을 빌려 쓰는 방식을 권장합니다.
systemctl, apt처럼 시스템 설정을 바꾸는 명령어 앞에는 sudo가 필요합니다.
$whoami # 현재 로그인한 사용자명
$sudo systemctl restart fastapi-school
$su - # root로 완전히 전환 (서버 운영에서는 권장하지 않음)
| 명령어 | 이름 | 설명 및 사용 예 |
| sudo | 권한 상승 | 다음 한 명령어만 관리자 권한으로 실행 |
| passwd | 비밀번호 변경 | 현재 사용자의 로그인 비밀번호 변경 |
| adduser | 계정 생성 | sudo adduser 사용자명으로 새 사용자 추가 |
| usermod -aG | 그룹 추가 | sudo usermod -aG sudo 사용자명으로 sudo 권한 부여 |
| id | 계정 정보 | 현재 사용자의 UID/GID와 소속 그룹 확인 |
프로세스 관리
실행 중인 프로그램(프로세스)을 확인하고 필요할 때 종료하는 명령어입니다. gunicorn 워커가 응답이 없거나 포트가 이미 사용 중일 때 특히 자주 쓰게 됩니다.
ps aux는 전체 프로세스 스냅샷, top/htop은 CPU·메모리 사용률을 실시간으로 보여줍니다.
$ps aux | grep gunicorn
$top # q 키로 종료
실행 결과
ubuntu 18422 0.3 2.1 gunicorn: master [main:app]
ubuntu 18423 0.1 2.4 gunicorn: worker [main:app]
먼저 ps aux로 PID(프로세스 번호)를 확인한 뒤 종료합니다. -9는 강제 종료로, 데이터가 저장되지 않을 수 있어 마지막 수단으로만 사용합니다.
$kill 18422 # 정상 종료 요청 (SIGTERM)
$kill -9 18422 # 강제 종료 (최후의 수단)
$sudo fuser -k 8001/tcp # 특정 포트를 점유한 프로세스 종료
systemd로 관리되는 앱은?
- 이 서버의 fastapi-school 등은 gunicorn을
kill로 직접 종료하지 않고, systemctl로 재시작/중지하는 것이 정석입니다.
- systemd가
Restart=always로 설정돼 있으면 kill로 죽여도 자동으로 다시 살아납니다.
시스템 정보 확인
서버의 리소스 상태(디스크, 메모리)와 OS 정보를 빠르게 확인하는 명령어입니다. 디스크가 꽉 차면 배포·로그 기록이 실패하므로 정기적으로 확인하는 것이 좋습니다.
| 명령어 | 이름 | 설명 및 사용 예 |
| df -h | 디스크 여유 | 파티션별 사용량을 사람이 읽기 쉬운 단위(GB)로 출력 |
| du -sh * | 디렉토리 용량 | 현재 위치의 각 항목이 차지하는 용량 확인 |
| free -h | 메모리 | 전체/사용중/여유 RAM과 스왑 확인 |
| uname -a | 커널 정보 | 커널 버전, 아키텍처 등 시스템 정보 |
| lsb_release -a | 배포판 정보 | Ubuntu 버전(예: 24.04) 확인 |
| uptime | 가동 시간 | 서버가 켜진 이후 경과 시간과 부하(load average) |
배포 전 여유 공간이 충분한지, 메모리가 부족하지 않은지 확인하는 습관을 들이면 좋습니다.
실행 결과
Filesystem Size Used Avail Use% Mounted on
/dev/root 20G 9.4G 10G 49% /
total used free shared buff/cache available
Mem: 1.9Gi 620Mi 180Mi 45Mi 1.1Gi 1.0Gi
APT 패키지 관리
APT(Advanced Package Tool)는 우분투의 표준 패키지 관리자입니다. 시스템 패키지 설치는 항상 sudo가 필요합니다.
update는 저장소의 최신 패키지 목록만 가져오고, 실제 패키지 설치는 하지 않습니다. 새 서버를 세팅할 때 순서대로 실행하세요.
# 1. 패키지 목록 최신화
$sudo apt update
# 2. 시스템 전체 업그레이드 (선택)
$sudo apt upgrade -y
# 3. 패키지 설치 / 삭제
$sudo apt install nginx
$sudo apt remove nginx
실행 결과
Setting up nginx (1.24.0-2ubuntu7) ... done.
| 명령어 | 이름 | 설명 및 사용 예 |
| apt search | 패키지 검색 | apt search nginx로 이름/설명에 매칭되는 패키지 찾기 |
| apt show | 패키지 정보 | 버전, 의존성 등 상세 정보 확인 |
| apt list --installed | 설치 목록 | 현재 설치된 모든 패키지 나열 |
| apt autoremove | 정리 | 더 이상 필요 없는 의존성 패키지 일괄 삭제 |
systemd 서비스 관리
이 서버의 fastapi-school 등 gunicorn 앱들은 모두 systemd 서비스로 등록되어 있어, 부팅 시 자동 시작되고 systemctl로 일관되게 제어합니다.
코드를 배포한 뒤에는 restart로 gunicorn 워커를 새 코드로 다시 띄워야 반영됩니다.
$sudo systemctl restart fastapi-school
$sudo systemctl status fastapi-school
$sudo systemctl enable fastapi-school # 부팅 시 자동 시작 등록
실행 결과 (status)
● fastapi-school.service - FastAPI school app
Active: active (running) since Sun 2026-08-16 09:00:12 UTC
Main PID: 18422 (gunicorn)
서비스가 죽었거나 500 에러가 날 때 가장 먼저 확인하는 명령어입니다. -f는 tail -f처럼 실시간 스트리밍입니다.
$sudo journalctl -u fastapi-school -f
$sudo journalctl -u fastapi-school --since "10 min ago"
실행 결과
Aug 16 09:12:03 gunicorn[18422]: INFO Application startup complete.
네트워크 확인
서버의 IP, 연결 상태, 포트 점유 여부를 확인할 때 사용합니다.
| 명령어 | 이름 | 설명 및 사용 예 |
| ip a | IP 확인 | 서버에 할당된 네트워크 인터페이스와 IP 주소 확인 |
| ping | 연결 확인 | ping -c 4 offset0xf.com로 응답/지연시간 확인 |
| curl / wget | HTTP 요청 | 웹 서버 응답 확인, 파일 다운로드 |
| ss -tulnp | 포트 확인 | 현재 열려 있는 포트와 이를 점유한 프로세스 확인 |
| nslookup / dig | DNS 조회 | 도메인의 실제 IP(A 레코드) 확인 |
"Address already in use" 에러가 날 때 어떤 프로세스가 8001 포트를 쓰고 있는지 확인합니다.
$sudo ss -tulnp | grep 8001
실행 결과
tcp LISTEN 0 2048 0.0.0.0:8001 0.0.0.0:* users:(("gunicorn",pid=18422))
SSH / SCP / rsync — 원격 서버 접속 & 파일 전송
로컬 PC에서 이 EC2 서버(43.203.123.184)로 접속하거나 파일을 주고받을 때 사용합니다.
키 파일(.pem)의 권한이 너무 열려 있으면 SSH가 접속을 거부합니다 — chmod 400으로 제한하세요.
$chmod 400 key.pem # 키 파일 권한을 소유자 읽기 전용으로
$ssh -i key.pem ubuntu@43.203.123.184
$scp -i key.pem main.py ubuntu@43.203.123.184:~/offset0xf/school/
$rsync -avz --delete ./dist/ ubuntu@43.203.123.184:~/app/ # 변경분만 동기화
실행 결과
Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.17.0-1015-aws x86_64)
압축 & 아카이브
배포 파일을 묶어서 전송하거나 백업할 때 tar를 가장 많이 사용합니다. 옵션 순서상 f는 항상 마지막에, 그다음에 파일명을 씁니다.
| 옵션 | 이름 | 설명 |
| -c | 생성(create) | 새 아카이브 생성 |
| -x | 추출(extract) | 아카이브 압축 해제 |
| -z | gzip | gzip으로 압축/해제 (.tar.gz) |
| -v | verbose | 진행되는 파일 목록을 출력 |
| -f | 파일 지정 | 대상 아카이브 파일명. 항상 맨 끝 옵션 |
zip/unzip은 sudo apt install zip unzip으로 설치 후 동일한 방식으로 사용합니다.
$tar -czvf backup_20260816.tar.gz templates/ static/
$tar -xzvf backup_20260816.tar.gz -C /tmp/restore/
$zip -r site.zip templates/
$unzip site.zip -d restored/
실행 결과
templates/, static/ → backup_20260816.tar.gz (12.4 MB)
파이프 & 리다이렉션
한 명령어의 출력을 다른 명령어의 입력으로 연결(|)하거나, 파일로 저장(>, >>)하는 방법입니다. 리눅스 CLI의 진짜 힘은 이 조합에서 나옵니다.
command1 | command2
# command1의 출력을 command2의 입력으로
command > file.txt
# 출력을 파일에 덮어쓰기
command >> file.txt
# 출력을 파일 끝에 이어쓰기
로그에서 특정 상태코드가 몇 번 발생했는지 세거나, 결과를 파일로 저장하는 예시입니다.
$grep "500" access.log | wc -l # 500 에러 발생 건수
$ps aux | grep gunicorn > workers.txt
$echo "$(date): 배포 완료" >> deploy_history.log
실전 원라이너 모음
이 서버(fastapi-school 등) 운영 상황을 가정한, 여러 명령어를 조합한 실전 예제입니다.
코드를 업로드한 뒤 서비스를 재시작하고, 정상 기동됐는지 로그와 응답을 함께 확인하는 흐름입니다.
# 1. 의존성 갱신
$source venv/bin/activate && pip install -r requirements.txt
# 2. 서비스 재시작
$sudo systemctl restart fastapi-school
# 3. 상태 & 최근 로그 확인
$sudo systemctl status fastapi-school --no-pager
$sudo journalctl -u fastapi-school -n 30 --no-pager
# 4. 실제 응답 확인
$curl -I https://offset0xf.com
df로 파티션이 꽉 찬 걸 확인했다면, du로 어떤 디렉토리가 용량을 많이 차지하는지 추적합니다.
$df -h
$cd /var/log && du -sh * | sort -rh | head -10
실행 결과
2.1G nginx
640M journal
88M apt
✅ 자주 쓰는 패턴 요약
- 파일 찾고 확인:
find . -name "*.py" | xargs grep -l "router"
- 서비스 재기동:
sudo systemctl restart 서비스명 && sudo systemctl status 서비스명
- 실시간 로그:
sudo journalctl -u 서비스명 -f 또는 tail -f 로그파일
- 포트 점유 확인:
sudo ss -tulnp | grep 포트번호
- 디스크 확인:
df -h 후 du -sh * | sort -rh로 원인 추적
"터미널은 눈이 아니라 손으로 기억하는 도구다 — 자주 치는 명령어일수록 손에 익는다"