파일 권한·프로세스 시그널·systemd 서비스·journalctl 로그·디스크와 메모리 점검까지 리눅스 서버 기본 운영 명령을 실행 결과와 함께 익힙니다.
🎯 학습 목표
서버 대부분은 리눅스로 운영됩니다. 이 강을 마치면 권한 오류를 고치고, 프로세스를 안전하게 끝내고, systemd 서비스와 로그, 디스크·메모리 여유를 확인할 수 있습니다.
- 권한 문자열과 숫자 표기(640)를 읽는다
- TERM과 KILL의 차이를 알고 프로세스를 끝낸다
- 서비스·로그·디스크·메모리를 점검한다
환경: Ubuntu 24.04(WSL2, systemd), 일반 사용자. 출력은 모두 실제 실행 결과입니다.
🗂️ 파일 권한과 사용자
리눅스는 모든 파일에 소유자(user)·그룹(group)·기타(other) 세 대상별로 읽기(r)·쓰기(w)·실행(x) 권한을 둡니다. 숫자로는 r=4, w=2, x=1을 더해 표기하므로 640은 소유자 rw-, 그룹 r--, 기타 ---입니다. 내가 누구인지는 id, whoami로 확인하고, 관리자(root) 권한이 필요한 작업은 sudo를 붙여 실행합니다.
$ printf '#!/bin/sh\necho hello from script\n' > hello.sh
$ ls -l hello.sh
-rw-r--r-- 1 chung chung 33 Oct 21 20:12 hello.sh
$ ./hello.sh
bash: ./hello.sh: Permission denied
$ chmod u+x hello.sh && ls -l hello.sh
-rwxr--r-- 1 chung chung 33 Oct 21 20:12 hello.sh
$ ./hello.sh
hello from script
$ chmod 640 hello.sh && stat -c "%A %a %U:%G %n" hello.sh
-rw-r----- 640 chung:chung hello.sh
- 첫 글자
-는 일반 파일(d는 디렉터리), 다음 9글자가 세 대상의 권한,chung chung은 소유자와 그룹입니다. - 실행 권한(x)이 없으면 스크립트 내용이 맞아도 Permission denied입니다.
u+x는 「소유자에게 실행 추가」입니다. stat -c로 기호 표기와 숫자 표기를 한 번에 볼 수 있습니다.
$ ls -l /etc/shadow
-rw-r----- 1 root shadow 830 Sep 11 22:46 /etc/shadow
$ cat /etc/shadow
cat: /etc/shadow: Permission denied
비밀번호 해시가 든 이 파일은 root와 shadow 그룹만 읽으므로 막히는 것이 정상입니다. 권한을 777로 푸는 것은 보안 사고의 지름길입니다.
⚙️ 프로세스·서비스·로그
실행 중인 프로그램을 프로세스라 하고, 각자 번호(PID)를 받습니다. 종료는 시그널로 요청합니다. kill의 기본값 SIGTERM(15)은 「정리하고 끝내라」는 요청이라 프로그램이 파일 저장·연결 종료를 마칠 기회가 있고, SIGKILL(9)은 커널이 즉시 강제 종료하므로 막거나 무시할 수 없습니다.
서버의 상시 프로그램(웹 서버, DB, cron 등)은 서비스로 등록되어 PID 1인 systemd가 시작·재시작·로그 수집을 맡습니다.
| 할 일 | 명령 |
|---|---|
| 상태 보기 | systemctl status 서비스 |
| 시작·중지·재시작 | sudo systemctl start|stop|restart 서비스 |
| 부팅 시 자동 시작 | sudo systemctl enable 서비스 |
| 서비스 로그 | journalctl -u 서비스 -n 50, 실시간은 -f |
💻 실습 — 프로세스·서비스·로그·자원 점검
1단계: 프로세스 찾고 끝내기
$ sleep 600 &
$ ps -o pid,ppid,stat,etime,cmd -p 7996
PID PPID STAT ELAPSED CMD
7996 7971 S 00:00 sleep 600
$ kill 7996
[1]+ Terminated sleep 600
&는 백그라운드 실행, PPID는 부모, STAT S는 대기 상태입니다. PID는 매번 다르니 자기 화면의 번호를 씁니다. TERM을 무시하는 프로그램이라면 어떨까요?
$ bash -c 'trap "" TERM; sleep 600' &
[1] 22862
$ kill 22862; sleep 0.5; ps -o pid,stat,cmd -p 22862
PID STAT CMD
22862 S sleep 600
$ kill -9 22862
[1]+ Killed bash -c 'trap "" TERM; sleep 600'
trap "" TERM으로 TERM을 무시하게 만든 프로세스는 kill 뒤에도 살아 있고, kill -9에서야 끝났습니다. 순서는 TERM → 대기 → KILL입니다.
시스템 전체는 top으로 봅니다. 첫 줄의 load average(1·5·15분 평균 대기 작업 수)는 코어 수(nproc)와 비교해 읽습니다.
2단계: 서비스 상태와 로그
$ systemctl status cron --no-pager
● cron.service - Regular background program processing daemon
Loaded: loaded (/usr/lib/systemd/system/cron.service; enabled; preset: enabled)
Active: active (running) since Mon 2026-10-19 07:17:47 KST; 2 days ago
Main PID: 194 (cron)
… 생략 …
$ journalctl -u cron -n 3 -o cat --no-pager
pam_unix(cron:session): session opened for user root(uid=0) by root(uid=0)
(root) CMD (cd / && run-parts --report /etc/cron.hourly)
pam_unix(cron:session): session closed for user root
enabled는 부팅 시 자동 시작, active (running)은 지금 실행 중이라는 뜻입니다. -o cat은 시각·호스트명 없이 메시지만 보입니다. 파일로 남는 앱 로그는 tail -f로 따라 읽습니다.
$ (for i in 1 2 3; do echo "$(date +%T) INFO request $i" >> app.log; sleep 1; done; echo "$(date +%T) ERROR db timeout" >> app.log) &
$ timeout 5 tail -f app.log
20:12:41 INFO request 1
20:12:42 INFO request 2
20:12:43 INFO request 3
20:12:44 ERROR db timeout
$ grep -n ERROR app.log
4:20:12:44 ERROR db timeout
첫 줄은 1초마다 로그를 쓰는 연습용 작업이고, tail -f는 새 줄이 생길 때마다 바로 보여 줍니다(timeout 5로 5초 뒤 종료, 평소에는 Ctrl+C). 중간의 작업 완료 알림 줄은 생략했습니다.
3단계: 패키지·디스크·메모리
$ apt-cache policy curl
curl:
Installed: 8.5.0-2ubuntu10.16
Candidate: 8.5.0-2ubuntu10.16
… 생략 …
$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sdd 1007G 92G 864G 10% /
$ df -i /
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sdd 67108864 1004850 66104014 2% /
$ du -sh /var/log 2>/dev/null
639M /var/log
$ free -h
total used free shared buff/cache available
Mem: 15Gi 10Gi 244Mi 1.4Gi 6.3Gi 4.9Gi
Swap: 8.0Gi 3.5Gi 4.5Gi
Installed와Candidate가 같으면 최신 패치 상태입니다(갱신은sudo apt update && sudo apt upgrade).df -i는 파일 개수 한도(inode)입니다. 작은 파일이 수백만 개 쌓이면 용량이 남아도 「No space left on device」가 납니다.- 메모리는
free가 아니라available을 봅니다. 리눅스는 남는 메모리를 캐시(buff/cache)로 쓰다가 필요하면 돌려주므로 free가 작아도 정상입니다.
⚠️ 자주 하는 실수와 해결
$ systemctl restart cron
Failed to restart cron.service: Interactive authentication required.
See system logs and 'systemctl status cron.service' for details.
$ apt install -y htop
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
- sudo 빠뜨리기 — 서비스 조작과 패키지 설치는 root 권한이 필요합니다. 위 두 오류는 모두
sudo를 붙이면 해결됩니다. 단, 습관처럼 모든 명령에 붙이지는 않습니다. - 처음부터
kill -9— 정리 기회 없이 끊겨 임시 파일·잠금 파일이 남거나 DB라면 복구 작업이 길어질 수 있습니다. 서비스는systemctl stop으로 끕니다. - 재시작 후 확인 생략 —
restart가 조용히 끝나도 곧 죽을 수 있으니status와 로그를 바로 봅니다.
✏️ 확인 문제
chmod 640 file뒤 권한 문자열은? ① -rwxr----- ② -rw-r----- ③ -rw-rw-r-- ④ -r--r----- 정답 ② — 6=r+w, 4=r, 0=없음.- 스크립트 실행 시 Permission denied가 납니다. 내용이 정상이라면 먼저 할 일은? 정답
chmod u+x로 실행 권한을 준다 — x 권한이 없으면 실행할 수 없습니다. kill PID뒤에도 프로세스가 남았습니다. 맞는 설명은? ① kill은 SIGKILL을 보낸다 ② 프로세스가 SIGTERM을 무시하거나 처리 중이다 ③ PID가 재사용되었다 ④ 권한과 무관하다 정답 ② — 기본은 SIGTERM이며 기다려 본 뒤kill -9를 씁니다.free -h에서 free 244Mi, available 4.9Gi입니다. 판단은? 정답 메모리 여유가 있다 — 캐시는 필요 시 반환되므로 available을 봅니다.- nginx 서비스의 최근 로그 50줄을 보는 명령은? ①
systemctl log nginx②journalctl -u nginx -n 50③tail -u nginx④ps nginx정답 ② —-u는 유닛,-n은 줄 수입니다.
📝 핵심 요약과 다음 강 예고
- 권한: 소유자·그룹·기타 × rwx, 숫자 r4 w2 x1, root 작업은 sudo
- 프로세스:
ps·top, 종료는 TERM 먼저, KILL은 마지막 - 서비스:
systemctl status|restart|enable, 로그는journalctl -u·tail -f - 자원:
df -h·df -i·du -sh, 메모리는 available 기준
다음 강에서는 디스크를 한 단계 더 들어가 블록·파일·오브젝트 스토리지, 파일시스템 마운트, RAID, 그리고 3-2-1 백업 원칙을 실습합니다.
📚 참고 자료
관련 주제
- 파일 권한
- chmod
- 프로세스
- SIGTERM
- SIGKILL
- systemctl
- journalctl
- df
- free
- 개발·프로그래밍
- 개발·프로그래밍 강의
- 클라우드·인프라 실무 — 서버부터 도커·쿠버네티스까지 30강
- NUGUNA
- 누구나
📚 시리즈 전체 공유
클라우드·인프라 실무 — 서버부터 도커·쿠버네티스까지 30강
이 강의가 속한 시리즈는 총 30강(수강생 전용 보너스 · 1~3강 무료)입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.
댓글
불러오는 중...
