/static/codemoomoo2.png

2. Introduction of Linux OS

บทนี้อธิบายรากฐานของระบบปฏิบัติการลีนุกซ์ (Linux) ตั้งแต่ประวัติ ปรัชญา สถาปัตยกรรม ตระกูลของดิสทริบิวชัน (Distribution) มาตรฐานลำดับชั้นไฟล์ (FHS) ระบบ Init การจัดการแพ็กเกจ การจัดการผู้ใช้และสิทธิ์ ไปจนถึงการติดตั้งและตั้งค่าพื้นฐาน เนื้อหามุ่งให้ผู้เรียนเข้าใจโครงสร้างภายในและสามารถลงมือทำได้จริงบนเครื่องของตนเอง


2.1 ประวัติและปรัชญาของ Unix/Linux

Unix คือระบบปฏิบัติการที่วางรากฐานแนวคิดเกือบทั้งหมดของระบบปฏิบัติการยุคใหม่ ตั้งแต่แนวคิด Process, File Descriptor, Pipe, Hierarchical File System และปรัชญา "Everything is a file" ในขณะที่ Linux คือ Kernel ที่ Linus Torvalds เขียนขึ้นใหม่โดยได้แรงบันดาลใจจาก MINIX และ Unix แล้วนำมาประกอบร่างกับเครื่องมือจาก GNU Project จนกลายเป็นระบบปฏิบัติการแบบ Unix-like ที่ใช้งานทั่วโลกในปัจจุบัน

2.1.1 กำเนิดของ Unix (AT&T Bell Labs, Ken Thompson, Dennis Ritchie)

ในปี ค.ศ. 1969 ที่ AT&T Bell Labs ทีมวิจัยนำโดย Ken Thompson, Dennis Ritchie, Douglas McIlroy และ Joe Ossanna ได้พัฒนา Unix ขึ้นเพื่อทดแทนโครงการ Multics ที่มีขนาดใหญ่เกินไป เหตุการณ์สำคัญ ได้แก่

แนวคิดสำคัญที่ Unix นำเสนอ ได้แก่ Small Tools (โปรแกรมเล็ก ๆ ที่ทำงานเฉพาะด้าน), Pipe (การต่อเชื่อม input/output ระหว่างโปรแกรม), Hierarchical File System (ระบบไฟล์แบบต้นไม้), Shell ที่เป็นทั้งตัวแปลภาษาและภาษาโปรแกรม

2.1.2 BSD และตระกูล Unix (FreeBSD, OpenBSD, NetBSD, macOS/Darwin)

ในปี ค.ศ. 1977 University of California, Berkeley ได้รับ source code ของ Unix จาก AT&T และพัฒนาเป็น BSD (Berkeley Software Distribution) ที่เพิ่มฟีเจอร์สำคัญ เช่น TCP/IP stack, vi editor, C shell (csh), Fast File System (FFS)

การฟ้องร้องระหว่าง AT&T vs BSDi/UC Berkeley ในช่วงต้นทศวรรษ 1990 ทำให้ BSD พัฒนาช้าลง และเปิดโอกาสให้ Linux เติบโตแทนในช่วงเวลาเดียวกัน หลังจากคดีจบลง BSD แตกสายออกเป็นหลายโครงการ

โครงการ (Project) จุดเด่น (Strengths) เป้าหมาย (Focus)
FreeBSD Performance, ZFS, Jail Server, Desktop
OpenBSD Security, Code Audit, pf firewall Secure Server
NetBSD Portability (รันได้กว่า 50 สถาปัตยกรรม) Research, Embedded
DragonFly BSD HAMMER filesystem, SMP High Performance
macOS/Darwin XNU kernel (Mach + BSD), commercial Consumer, Creative Work

macOS ของ Apple ใช้ XNU kernel ซึ่งรวม Mach microkernel เข้ากับส่วนประกอบของ FreeBSD จึงทำให้ macOS เป็น Unix-certified อย่างเป็นทางการ ในขณะที่ Linux ไม่ใช่ Unix แต่เป็นเพียง Unix-like

2.1.3 กำเนิดของ Linux (Linus Torvalds, 1991) และ Kernel Versioning

เมื่อวันที่ 25 สิงหาคม ค.ศ. 1991 Linus Torvalds นักศึกษามหาวิทยาลัย Helsinki ได้โพสต์ข้อความอันโด่งดังในกลุ่มข่าว comp.os.minix ประกาศเกี่ยวกับระบบปฏิบัติการ "งานอดิเรก" ที่กำลังสร้างอยู่บนเครื่อง Intel 80386 โดยยืนยันว่า "จะไม่ใหญ่และไม่เป็น professional เหมือน GNU"

โครงสร้าง Kernel Version ในปัจจุบัน เช่น 6.8.12

Version = MAJOR . MINOR . PATCH

โดย MAJOR เปลี่ยนเมื่อเลขเวอร์ชันย่อยขึ้นถึงจุดที่ Linus พอใจจะเพิ่ม (ไม่ได้สะท้อนการเปลี่ยนแปลงใหญ่ในเชิงเทคนิค), MINOR คือรอบการออกหลัก (ทุก ๆ ~10 สัปดาห์), PATCH คือ bug fix ใน stable tree

มีสาย LTS (Long-Term Support) ที่ดูแลโดยทีม kernel.org สำหรับใช้ใน Enterprise และ Embedded system โดยสนับสนุนยาวนาน 2-6 ปี

flowchart LR
    subgraph Era1["ยุค Unix (1969-1990)"]
        direction TB
        A["1969
Unix V1
Bell Labs"] --> B["1973
Rewritten in C
พอร์ตได้"] B --> C["1977
BSD แยกสาย
UC Berkeley"] C --> D["1983
GNU Project
R. Stallman"] end subgraph Era2["ยุค Linux กำเนิด (1991-2000)"] direction TB E["1991
Linux 0.01
L. Torvalds"] --> F["1992
GPLv2
License"] F --> G["1994
Linux 1.0
Stable"] G --> H["1996
Linux 2.0
SMP Support"] end subgraph Era3["ยุค Enterprise (2000-2010)"] direction TB I["2003
Linux 2.6
New Scheduler"] --> J["2005
Git กำเนิด
สำหรับ kernel"] J --> K["2007
Android ใช้ Linux
Smartphone"] end subgraph Era4["ยุคปัจจุบัน (2010-now)"] direction TB L["2011
Linux 3.0"] --> M["2015
Linux 4.0
Live Patch"] M --> N["2019
Linux 5.0
Container"] N --> O["2022+
Linux 6.x
Rust in Kernel"] end Era1 --> Era2 Era2 --> Era3 Era3 --> Era4

2.1.4 GNU Project และ Free Software Foundation (Richard Stallman)

ในปี ค.ศ. 1983 Richard Stallman (RMS) แห่ง MIT ประกาศก่อตั้ง GNU Project (GNU's Not Unix) เพื่อสร้างระบบปฏิบัติการแบบ Unix ที่เป็น Free Software ทั้งหมด และในปี ค.ศ. 1985 ได้ก่อตั้ง Free Software Foundation (FSF) เพื่อส่งเสริมซอฟต์แวร์เสรี

GNU กำหนดนิยาม Four Essential Freedoms ของซอฟต์แวร์เสรี

  1. Freedom 0: เสรีภาพในการรันโปรแกรมเพื่อวัตถุประสงค์ใดก็ได้
  2. Freedom 1: เสรีภาพในการศึกษาการทำงานของโปรแกรมและดัดแปลง (ต้องเข้าถึง source code)
  3. Freedom 2: เสรีภาพในการแจกจ่ายสำเนา
  4. Freedom 3: เสรีภาพในการแจกจ่ายเวอร์ชันที่ดัดแปลงแล้ว

GNU Project สร้างเครื่องมือสำคัญมากมายก่อนที่ Linux จะกำเนิด เช่น GCC (Compiler), Emacs (Editor), Bash (Shell), Coreutils (ls, cp, mv), Binutils (ld, as), glibc (C Library), Make, GDB แต่ขาดชิ้นสำคัญคือ Kernel (โครงการ GNU Hurd ไม่สามารถพัฒนาให้เสถียรได้ทันเวลา) จนกระทั่ง Linux kernel เข้ามาเติมเต็ม ทำให้เกิดระบบปฏิบัติการ GNU/Linux ที่ใช้กันทุกวันนี้

2.1.5 ปรัชญา Unix: "Do one thing and do it well", "Everything is a file"

Doug McIlroy ผู้เขียน pipe ได้สรุปปรัชญา Unix ไว้อย่างสั้น ๆ ว่า

  1. Write programs that do one thing and do it well — เขียนโปรแกรมให้ทำสิ่งเดียวแต่ทำให้ดี
  2. Write programs to work together — เขียนโปรแกรมให้ทำงานร่วมกันได้
  3. Write programs to handle text streams — ใช้ text stream เป็นส่วนต่อประสานสากล

อีกหลักการที่สำคัญคือ "Everything is a file" ซึ่งหมายถึงทรัพยากรเกือบทุกอย่างในระบบถูกมองว่าเป็น "ไฟล์" และใช้ System Call เดียวกันในการอ่านเขียน เช่น

ตัวอย่างการทดลองจริงที่แสดงปรัชญานี้

# อ่านข้อมูล CPU จาก /proc (virtual file) เหมือนอ่านไฟล์ธรรมดา
cat /proc/cpuinfo | grep "model name" | head -1

# ส่งข้อมูลสุ่มไปยังไฟล์ device /dev/null เพื่อทิ้ง
dd if=/dev/urandom of=/dev/null bs=1M count=10

# อ่านข้อความจาก keyboard (TTY) ผ่าน pipe
echo "hello" | cat

2.1.6 License: GPL (v2/v3), LGPL, MIT, BSD, Apache, MPL

ระบบนิเวศ Open Source ประกอบด้วยสัญญาอนุญาต (license) หลากหลายรูปแบบ แบ่งเป็นสองกลุ่มใหญ่คือ Copyleft (ต้องเปิดเผยการดัดแปลงด้วย) และ Permissive (ใช้ได้อิสระแม้ในซอฟต์แวร์ปิด)

License ประเภท (Type) Copyleft ใช้กับ Closed Source ข้อกำหนดหลัก
GPL v2 Strong Copyleft ต้องเผยแพร่ source code เมื่อแจกจ่าย binary
GPL v3 Strong Copyleft เพิ่มเรื่อง patent และ Tivoization
LGPL Weak Copyleft ✅ (เฉพาะ library) ✅ (ถ้า dynamic link) link แบบ dynamic ได้โดยไม่ต้องเปิด code ของ app
MIT Permissive แค่ระบุ copyright และ license
BSD (2/3-clause) Permissive ระบุ copyright, ห้ามใช้ชื่อผู้เขียนโฆษณา
Apache 2.0 Permissive + Patent มี patent grant ชัดเจน
MPL 2.0 File-level Copyleft ✅ (เฉพาะไฟล์) ✅ (ถ้าแยกไฟล์) ไฟล์ที่ดัดแปลงต้องเปิด, ไฟล์อื่นอิสระ

Linux Kernel ใช้ GPL v2 ซึ่งเป็นหัวใจที่ทำให้ Linux ยังคงความเปิดเผยได้อย่างต่อเนื่อง นักพัฒนาคนใดแก้ไข kernel แล้วแจกจ่ายต้องเปิด source code ให้ผู้รับด้วย


2.2 สถาปัตยกรรมของ Linux

สถาปัตยกรรมของ Linux (Linux Architecture) ถูกแบ่งเป็นชั้นตามระดับสิทธิ์ (privilege level) ของ CPU อย่างชัดเจน โดยโค้ดที่ใกล้ฮาร์ดแวร์จะทำงานใน Kernel Space ส่วนแอปพลิเคชันและเครื่องมือผู้ใช้ทำงานใน User Space การแบ่งแบบนี้เป็นหัวใจของความเสถียรและความปลอดภัย

flowchart TB
    subgraph US["User Space (Ring 3)"]
        direction TB
        APP["Applications
(Firefox, VS Code, Python)"] LIB["Libraries
(glibc, libssl, libstdc++)"] SHELL["Shell + Coreutils
(bash, ls, cp, mv)"] APP --> LIB SHELL --> LIB end subgraph SCI["System Call Interface"] SYSCALL["syscall instruction
(open, read, write, fork, exec)"] end subgraph KS["Kernel Space (Ring 0)"] direction TB PROC["Process Mgmt
(Scheduler, Signals)"] MEM["Memory Mgmt
(VM, Paging)"] VFS["VFS / File Systems
(ext4, btrfs, proc)"] NET["Networking
(TCP/IP Stack)"] DEV["Device Drivers
(Block, Char, Net)"] LKM["Loadable Kernel
Modules (.ko)"] end subgraph HW["Hardware"] direction LR CPU["CPU"] RAM["RAM"] DISK["Disk"] NIC["NIC"] GPU["GPU"] CPU ~~~ RAM ~~~ DISK ~~~ NIC ~~~ GPU end LIB -->|calls| SYSCALL SYSCALL -->|dispatch| PROC SYSCALL --> MEM SYSCALL --> VFS SYSCALL --> NET PROC --> DEV MEM --> DEV VFS --> DEV NET --> DEV DEV --> HW LKM -.->|dynamic load| DEV

2.2.1 User Space vs Kernel Space

CPU ตระกูล x86 มีระดับสิทธิ์ 4 ระดับ (Ring 0-3) แต่ Linux ใช้จริงเพียง 2 ระดับ

การสลับ mode เกิดขึ้นเมื่อ

  1. User process เรียก System Call เช่น read(), write()
  2. เกิด Interrupt จากอุปกรณ์ เช่น keyboard, network
  3. เกิด Exception เช่น page fault, division by zero

ต้นทุนการสลับ mode (mode switch) ประมาณ 100-300 cycles ซึ่งเหตุนี้ทำให้การเขียนโปรแกรมที่ดีต้องลดจำนวน system call (ใช้ buffered I/O, sendfile(), io_uring)

2.2.2 Linux Kernel (Monolithic + Loadable Kernel Module)

Linux Kernel ใช้สถาปัตยกรรมแบบ Monolithic Kernel แปลว่าระบบย่อยทั้งหมด (Process Management, Memory Management, File System, Device Driver, Networking) อยู่ในพื้นที่ที่อยู่เดียวกัน (same address space) การสื่อสารระหว่างระบบย่อยจึงเร็วเพราะเรียกฟังก์ชันตรง ๆ ได้

แต่ Linux ก็เพิ่มความยืดหยุ่นด้วย Loadable Kernel Module (LKM) ที่สามารถโหลดเข้าและออกจาก Kernel ได้ระหว่างทำงาน โดยไม่ต้อง reboot ตัวอย่างคำสั่งจัดการโมดูล

# แสดงโมดูลที่โหลดอยู่ในปัจจุบัน
lsmod | head -10

# ดูรายละเอียดโมดูล (เช่น driver ของ Wi-Fi)
modinfo iwlwifi

# โหลดโมดูลด้วยตัวเอง (ต้องใช้สิทธิ์ root)
sudo modprobe vboxdrv

# ปลดโมดูลออก
sudo modprobe -r vboxdrv

# ดูโมดูลที่ถูก autoload ตอน boot
ls /etc/modules-load.d/

2.2.3 System Call Interface (SCI) และ glibc

System Call Interface (SCI) คือ "ประตู" ที่ User Space ใช้ติดต่อกับ Kernel ในสถาปัตยกรรม x86_64 จะใช้คำสั่ง syscall โดยเก็บหมายเลข system call ใน register rax และอาร์กิวเมนต์ใน rdi, rsi, rdx, r10, r8, r9 ตามลำดับ

ตัวอย่างหมายเลข system call (syscall number) บน Linux x86_64

Number Name หน้าที่
0 read อ่านข้อมูลจาก file descriptor
1 write เขียนข้อมูลไปยัง file descriptor
2 open เปิดไฟล์
3 close ปิดไฟล์
57 fork สร้าง process ใหม่
59 execve แทนที่ process ด้วยโปรแกรมใหม่
60 exit สิ้นสุด process
231 exit_group สิ้นสุดทุก thread

glibc (GNU C Library) เป็น wrapper ที่ห่อ system call ให้เรียกใช้ง่ายเหมือนเรียกฟังก์ชัน C ทั่วไป

// ตัวอย่าง: เขียน "Hello, Linux!" ลง stdout โดยใช้ glibc wrapper
#include <unistd.h>   // sys call wrapper
#include <string.h>

int main(void) {
    // เรียก write() ของ glibc ซึ่งจะเรียก syscall หมายเลข 1
    const char *msg = "Hello, Linux!\n";
    write(1, msg, strlen(msg));   // fd=1 คือ stdout
    return 0;
}

/*
คอมไพล์และรัน:
  gcc hello.c -o hello
  ./hello
ตรวจสอบ syscall จริงที่ถูกเรียก:
  strace ./hello
จะเห็นบรรทัด: write(1, "Hello, Linux!\n", 14) = 14
*/

การเรียก System Call โดยตรงโดยไม่ผ่าน glibc ทำได้ด้วย syscall wrapper

#include <sys/syscall.h>
#include <unistd.h>
#include <string.h>

int main(void) {
    const char *msg = "Direct syscall!\n";
    // เรียก syscall หมายเลข __NR_write (=1) โดยตรง
    syscall(SYS_write, 1, msg, strlen(msg));
    return 0;
}

2.2.4 GNU Coreutils / Userland

Userland หมายถึงชุดเครื่องมือและไลบรารีที่อยู่ใน User Space ซึ่งประกอบเป็น "ประสบการณ์" ของ Linux distribution GNU Coreutils คือชุดคำสั่งพื้นฐานที่ขาดไม่ได้

บางดิสทริบิวชันเลือกใช้ userland ที่ไม่ใช่ GNU เช่น Alpine Linux ใช้ BusyBox (รวมคำสั่งหลายสิบตัวในไบนารีเดียว ขนาดเล็กมาก) และ musl libc แทน glibc เหมาะกับ container และ embedded system

2.2.5 Shell และ Application Layer

Shell เป็นทั้ง Command Interpreter และภาษาโปรแกรม ทำหน้าที่เป็นสะพานระหว่างผู้ใช้กับ Kernel ชั้นของการทำงานบน Linux สามารถแบ่งเป็น

  1. Kernel: จัดการทรัพยากร ฮาร์ดแวร์
  2. System Library (glibc): wrapper ของ syscall
  3. System Daemon: systemd, sshd, cron, NetworkManager
  4. Shell: bash, zsh, fish
  5. Coreutils + CLI Tools: ls, cp, grep, sed
  6. TUI/GUI: nvim, htop, GNOME, KDE
  7. Applications: Firefox, VS Code, Blender

2.2.6 Device File (/dev), Pseudo File System (/proc, /sys)

Linux ใช้ Virtual File System (VFS) เพื่อให้ทุกอย่างดูเป็นไฟล์ Pseudo file system ที่สำคัญมี

/dev — ไฟล์ device ที่แทนอุปกรณ์จริงหรือจำลอง จัดการโดย udev หรือ systemd-udevd

# ดูดิสก์บล็อก
ls -l /dev/sd*     # /dev/sda, /dev/sdb
ls -l /dev/nvme*   # /dev/nvme0n1

# ไฟล์พิเศษ
ls -l /dev/null /dev/zero /dev/urandom /dev/tty

# ส่งข้อความไปหา terminal อื่น (ต้องรู้ชื่อ tty)
# สมมติปลายทางเป็น /dev/pts/1
echo "สวัสดีอาจารย์ Moo!" | sudo tee /dev/pts/1

/proc — ไฟล์จำลองที่สะท้อนสถานะ kernel และ process

# CPU info
cat /proc/cpuinfo | grep "model name" | head -1

# หน่วยความจำ
cat /proc/meminfo | head -5

# uptime (หน่วย: วินาทีที่เปิดเครื่อง / idle time)
cat /proc/uptime

# kernel version
cat /proc/version

# process แต่ละตัวมี directory ชื่อเป็น PID
ls /proc/$$/          # ข้อมูลของ shell ตัวปัจจุบัน
cat /proc/$$/status | head -10
cat /proc/$$/cmdline

/sys — sysfs ที่สะท้อนโครงสร้าง device และ kernel object

# ตรวจระดับแบตเตอรี่ (สำหรับ Laptop)
cat /sys/class/power_supply/BAT0/capacity
cat /sys/class/power_supply/BAT0/status

# MAC address ของ Network interface
cat /sys/class/net/eth0/address 2>/dev/null || \
  cat /sys/class/net/wlan0/address

# CPU frequency ปัจจุบัน
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 2>/dev/null

2.3 Linux Distribution

Linux Distribution (Distro) คือการนำ Linux Kernel มารวมเข้ากับ userland (GNU coreutils หรืออื่น ๆ), libraries, package manager, init system, desktop environment และ configuration เพื่อสร้างเป็นระบบปฏิบัติการที่ใช้งานได้จริง แต่ละ distro มี "ตัวตน" (identity) ที่ต่างกันทั้งปรัชญา กลุ่มเป้าหมาย และวงจรการปล่อย (release cycle)

2.3.1 Debian-based: Debian, Ubuntu, Linux Mint, Pop!_OS, MX Linux

Debian ก่อตั้งโดย Ian Murdock ในปี ค.ศ. 1993 ชื่อมาจากการผสมชื่อของ Ian และภรรยา "Debra" ขึ้นชื่อเรื่องความเสถียร (stable branch มี release cycle 2 ปี) และใช้ dpkg + apt เป็น package manager ฐานข้อมูลแพ็กเกจในคลัง Debian main มีกว่า 60,000 แพ็กเกจ

2.3.2 Red Hat-based: RHEL, Fedora, CentOS Stream, Rocky Linux, AlmaLinux

Red Hat Enterprise Linux (RHEL) เป็นดิสทริบิวชันเชิงพาณิชย์ของ Red Hat (ปัจจุบันเป็นของ IBM) ใช้ package manager rpm + dnf (เดิมคือ yum) กลุ่มผู้ใช้หลักคือองค์กรขนาดใหญ่และ data center

2.3.3 Arch-based: Arch Linux, Manjaro, EndeavourOS, CachyOS

Arch Linux ยึดหลัก KISS (Keep It Simple, Stupid) ติดตั้งแบบ minimal แล้วให้ผู้ใช้ประกอบเอง ใช้ package manager pacman และมี AUR (Arch User Repository) ที่รวมสคริปต์สร้างแพ็กเกจจำนวนมหาศาล (แพ็กเกจทางการ + AUR รวมกันหลักแสน)

Arch เป็น Rolling Release อัปเดตต่อเนื่อง ไม่มีเลขเวอร์ชัน ArchWiki เป็นเอกสารอ้างอิงที่ดีที่สุดตัวหนึ่งในวงการ Linux

อาจารย์ Moo ใช้งาน CachyOS อยู่แล้ว ซึ่งเป็น Arch-based ที่ compile ด้วย -march=x86-64-v3 เพื่อรีดประสิทธิภาพจาก CPU ใหม่ ๆ (รวมถึง Ryzen AI 7 350 ของอาจารย์)

2.3.4 SUSE-based: openSUSE Leap / Tumbleweed, SLES

SUSE Linux Enterprise Server (SLES) คู่แข่ง RHEL ในยุโรป มีชื่อเสียงเรื่องเครื่องมือ YaST (Yet another Setup Tool) ที่ครอบคลุม

2.3.5 Independent: Gentoo, Void, Alpine, NixOS, Slackware

Gentoo ใช้ Portage ที่ compile จาก source code ผู้ใช้สามารถกำหนด USE flags เพื่อเลือกฟีเจอร์ เหมาะกับ customization สูงสุด

Void Linux ใช้ XBPS (X Binary Package System) และใช้ runit เป็น init (ไม่ใช่ systemd) มี musl edition สำหรับผู้ที่ไม่ต้องการ glibc

Alpine Linux เบามาก (ISO ~150MB) ใช้ musl + BusyBox + OpenRC เหมาะกับ container (เป็น base image ยอดนิยมของ Docker)

NixOS ใช้ Nix Package Manager ที่จัดการ dependency แบบ functional ทำให้ได้ Reproducible Build และสามารถ rollback ได้ทุก generation

Slackware distro ที่เก่าแก่ที่สุดที่ยังอยู่ (ตั้งแต่ ค.ศ. 1993) ยึดถือ simplicity แบบดั้งเดิม

2.3.6 Specialized: Kali, Parrot (Security), Proxmox (Virtualization), OpenWrt (Router)

2.3.7 Rolling Release vs Fixed Release vs Point Release

ลักษณะ (Aspect) Rolling Release Point Release LTS (Long Term Support)
ตัวอย่าง Arch, Tumbleweed Fedora, Ubuntu (ไม่ใช่ LTS) RHEL, Ubuntu LTS, Debian stable
รอบปล่อย ต่อเนื่อง ไม่มีเลขเวอร์ชัน ทุก 6-12 เดือน 2-5 ปี
ความใหม่ ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
ความเสถียร ⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
ความเสี่ยง update พัง ปานกลาง ต่ำ ต่ำมาก
เหมาะกับ Desktop, Developer, Home Lab Desktop, Developer Server, Production

2.3.8 เกณฑ์การเลือก Distribution สำหรับงาน Server, Desktop, Embedded, Container


2.4 Filesystem Hierarchy Standard (FHS)

Filesystem Hierarchy Standard (FHS) คือข้อกำหนดที่บอกว่า ไฟล์ประเภทใดควรอยู่ที่ไหน ในระบบ Unix-like ดูแลโดย Linux Foundation ปัจจุบันเป็นเวอร์ชัน 3.0 FHS ทำให้ผู้ใช้และนักพัฒนาสามารถคาดเดาได้ว่าควรไปค้นหาไฟล์ที่ใด ไม่ว่าจะใช้ distro ใดก็ตาม

flowchart TB
    ROOT["/ (Root Filesystem)"]

    subgraph L1["ไบนารีและไลบรารีระบบ"]
        BIN["/bin
(essential cmds)"] SBIN["/sbin
(system cmds)"] LIB["/lib, /lib64"] USR["/usr
(user programs)"] OPT["/opt
(3rd-party)"] end subgraph L2["การตั้งค่าและข้อมูลแปรผัน"] ETC["/etc
(config)"] VAR["/var
(logs, cache, mail)"] TMP["/tmp
(temporary)"] RUN["/run
(runtime)"] end subgraph L3["ผู้ใช้"] HOME["/home
(users)"] ROOTD["/root
(root's home)"] end subgraph L4["Virtual Filesystem"] PROC["/proc
(kernel info)"] SYS["/sys
(devices)"] DEV["/dev
(device nodes)"] end subgraph L5["สื่อบันทึกและการบูต"] BOOT["/boot
(kernel, initramfs)"] MNT["/mnt
(manual mount)"] MEDIA["/media
(removable)"] SRV["/srv
(service data)"] end ROOT --> L1 ROOT --> L2 ROOT --> L3 ROOT --> L4 ROOT --> L5

2.4.1 / (root), /bin, /sbin, /usr, /usr/local, /opt

หมายเหตุ: distro สมัยใหม่หลายตัวทำ /usr merge คือ /bin เป็น symlink ไปยัง /usr/bin, /sbin/usr/sbin, /lib/usr/lib เพื่อให้จัดการง่ายขึ้น (Fedora, Arch, Ubuntu ใหม่ ๆ)

2.4.2 /etc (config), /var (variable data), /tmp

ไฟล์ (File) หน้าที่ (Purpose)
/etc/passwd ข้อมูลผู้ใช้
/etc/shadow password hash
/etc/group ข้อมูล group
/etc/sudoers การกำหนดสิทธิ์ sudo
/etc/hostname ชื่อเครื่อง
/etc/hosts static DNS mapping
/etc/resolv.conf DNS server
/etc/fstab การ mount อัตโนมัติ
/etc/crontab task scheduler
/etc/ssh/sshd_config config SSH server

2.4.3 /home, /root

2.4.4 /proc, /sys, /dev, /run

2.4.5 /boot, /mnt, /media, /srv

ตัวอย่างสำรวจ FHS บนเครื่องของท่าน

# ดูขนาดของแต่ละ top-level directory
sudo du -sh /* 2>/dev/null | sort -h | tail -15

# ดูไฟล์ใน /etc ที่ถูกแก้ไขล่าสุด 7 วัน
find /etc -type f -mtime -7 2>/dev/null | head -20

# ดู log ล่าสุด
sudo tail -n 20 /var/log/syslog 2>/dev/null || \
  sudo journalctl -n 20

# ดู device node ทั้งหมดใน /dev ที่เป็น disk
ls -l /dev/ | grep -E '^b'   # b = block device

2.5 Init System และการจัดการบริการ

Init System คือโปรเซสแรกที่ Kernel รันขึ้นมา (มี PID 1) ทำหน้าที่เป็น "พ่อของทุกโปรเซส" บน Linux และรับผิดชอบการเริ่ม/หยุดบริการ (service / daemon) เมื่อเครื่องเปิด/ปิด

ลำดับการ boot แบบภาพรวม

flowchart TB
    POWER["เปิดเครื่อง
(Power On)"] --> FW["BIOS / UEFI
(Firmware)"] FW --> BL["Bootloader
(GRUB, systemd-boot)"] BL --> KERN["Linux Kernel
+ initramfs"] KERN --> INIT["PID 1
(Init System)"] INIT --> SVC["Services
(sshd, NetworkManager, cron)"] SVC --> LOGIN["Login
(getty / display manager)"]

2.5.1 SysVinit (Runlevel, rc.d)

SysVinit เป็นระบบ init แบบดั้งเดิม ใช้แนวคิด Runlevel แทนสถานะของระบบ

Runlevel ความหมาย
0 Halt (ปิดเครื่อง)
1 / S Single user mode (rescue)
2 Multi-user ไม่มี network
3 Multi-user + network (CLI)
4 ไม่ใช้ (customizable)
5 Multi-user + network + GUI
6 Reboot

SysVinit ใช้ shell script ใน /etc/init.d/ และ symlink ใน /etc/rc[0-6].d/ เพื่อสั่งบริการตอนเปลี่ยน runlevel

ปัญหาของ SysVinit

2.5.2 systemd: Unit, Service, Target, Timer, Socket, journalctl

systemd (เปิดตัว ค.ศ. 2010 โดย Lennart Poettering ที่ Red Hat) แก้ปัญหาของ SysVinit ทั้งหมด ปัจจุบันเป็น init system ของ distro ส่วนใหญ่ (Debian, Ubuntu, Fedora, Arch, openSUSE)

แนวคิดหลักของ systemd: Unit ทุกสิ่งเป็น Unit ที่มีประเภทต่าง ๆ

คำสั่งหลักของ systemctl

# ดูสถานะระบบทั้งหมด
systemctl status

# ดู service ที่กำลังรันอยู่
systemctl list-units --type=service --state=running

# เริ่ม/หยุด/รีสตาร์ท service
sudo systemctl start sshd
sudo systemctl stop sshd
sudo systemctl restart sshd
sudo systemctl reload nginx      # reload โดยไม่ restart

# เปิด/ปิดการ auto-start ตอน boot
sudo systemctl enable sshd
sudo systemctl disable sshd
sudo systemctl enable --now sshd  # enable และ start พร้อมกัน

# ดู log ของ service
sudo journalctl -u sshd -n 50 --no-pager

# ดู log แบบ tail -f
sudo journalctl -u sshd -f

# ดู log ตั้งแต่ boot นี้
sudo journalctl -b

# ดู target ปัจจุบัน (คล้าย runlevel)
systemctl get-default
# เปลี่ยน default target
sudo systemctl set-default multi-user.target

# ตรวจสอบเวลา boot (ช่วยหา service ที่ช้า)
systemd-analyze
systemd-analyze blame | head -10
systemd-analyze critical-chain

2.5.3 OpenRC (Gentoo, Alpine), runit (Void), s6

distro บางตัวเลือกใช้ init ที่เบากว่า systemd

Init Distro หลัก จุดเด่น
OpenRC Gentoo, Alpine Shell-based, เขียน service script ง่าย
runit Void, Artix Minimal, start/stop เร็วมาก, supervise service อัตโนมัติ
s6 ระบบ advanced Process supervisor ระดับสูง มีทีม s6-rc จัดการ dependency
dinit artix, experimental dependency-aware, lightweight
SysVinit Devuan, Slackware classic, simple

2.5.4 การเขียน systemd service file เบื้องต้น

ต่อไปนี้คือตัวอย่างสร้างบริการ "hello-moo" ที่รันสคริปต์ตอน boot

ขั้นที่ 1: สร้างสคริปต์ที่จะรัน

# สร้างสคริปต์
sudo tee /usr/local/bin/hello-moo.sh > /dev/null <<'EOF'
#!/bin/bash
# สคริปต์ตัวอย่างสำหรับอาจารย์ Moo
# เขียนข้อความพร้อมเวลาปัจจุบันลง log ทุก ๆ 30 วินาที

while true; do
    echo "[$(date '+%F %T')] Hello อาจารย์ Moo from systemd!" \
        >> /var/log/hello-moo.log
    sleep 30
done
EOF

sudo chmod +x /usr/local/bin/hello-moo.sh

ขั้นที่ 2: สร้างไฟล์ unit

sudo tee /etc/systemd/system/hello-moo.service > /dev/null <<'EOF'
[Unit]
Description=Hello Moo Demo Service (ตัวอย่างสำหรับการเรียน systemd)
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/hello-moo.sh
Restart=on-failure
RestartSec=5
User=nobody
Group=nogroup
# ความปลอดภัยเบื้องต้น
ProtectSystem=strict
ProtectHome=true
NoNewPrivileges=true
ReadWritePaths=/var/log

[Install]
WantedBy=multi-user.target
EOF

ขั้นที่ 3: โหลดและเปิดใช้งาน

# โหลด unit file ใหม่
sudo systemctl daemon-reload

# เปิดใช้งานและเริ่มทันที
sudo systemctl enable --now hello-moo.service

# ตรวจสถานะ
systemctl status hello-moo.service

# ดู log
sudo tail -f /var/log/hello-moo.log

# ปิดและลบ
sudo systemctl disable --now hello-moo.service
sudo rm /etc/systemd/system/hello-moo.service
sudo systemctl daemon-reload

ส่วนของไฟล์ unit อธิบายดังนี้


2.6 Package Management

Package Manager คือหัวใจของ Linux distribution ที่แก้ปัญหาดั้งเดิมของการติดตั้งซอฟต์แวร์จาก source code (compile เอง, dependency พันกัน) ด้วยการจัดการเป็นชุด Package พร้อมทั้ง metadata, dependency graph, และ repository

2.6.1 Low-level vs High-level Package Manager

การจัดการแพ็กเกจส่วนใหญ่แบ่งเป็น 2 ชั้น

flowchart TB
    subgraph HIGH["High-level (แก้ dependency, จัดการ repository)"]
        APT["apt (Debian/Ubuntu)"]
        DNF["dnf (Fedora/RHEL)"]
        ZYP["zypper (openSUSE)"]
        PAC["pacman (Arch)"]
    end

    subgraph LOW["Low-level (จัดการไฟล์ .deb/.rpm)"]
        DPKG["dpkg"]
        RPM["rpm"]
    end

    subgraph REPO["Repository (ที่เก็บแพ็กเกจ)"]
        MAIN["main / official"]
        UNIVERSE["universe / community"]
        PPA["PPA / COPR / AUR"]
    end

    APT --> DPKG
    DNF --> RPM
    ZYP --> RPM
    PAC -->|own format .pkg.tar.zst| FILE["package file"]
    DPKG --> FILE
    RPM --> FILE
    HIGH <--> REPO

2.6.2 APT และ dpkg (Debian/Ubuntu)

dpkg เป็น low-level ของ Debian ติดตั้ง/ถอน/สอบถามไฟล์ .deb

apt / apt-get เป็น high-level ที่ครอบ dpkg

# อัปเดตฐานข้อมูล repository
sudo apt update

# อัปเกรดแพ็กเกจทั้งหมด
sudo apt upgrade
sudo apt full-upgrade   # อาจถอนแพ็กเกจเก่าที่ขัดแย้ง

# ติดตั้ง
sudo apt install nginx git curl

# ถอน (คงไฟล์ config)
sudo apt remove nginx
# ถอนสมบูรณ์
sudo apt purge nginx

# ค้นหาแพ็กเกจ
apt search "neural network"
apt show python3-numpy

# ดูแพ็กเกจที่ติดตั้งไว้
dpkg -l | grep python
# ดูไฟล์ในแพ็กเกจ
dpkg -L nginx
# ค้นว่าไฟล์นี้มาจากแพ็กเกจไหน
dpkg -S /usr/bin/python3

# ติดตั้งจากไฟล์ .deb ที่ download เอง
sudo dpkg -i ./pkg.deb
sudo apt -f install   # แก้ dependency ที่ขาด

2.6.3 DNF และ RPM (Fedora/RHEL)

rpm เป็น low-level, dnf (ชื่อเต็ม Dandified YUM) เป็น high-level

# อัปเดตและอัปเกรด
sudo dnf check-update
sudo dnf upgrade

# ติดตั้ง / ถอน / ค้นหา
sudo dnf install nginx git curl
sudo dnf remove nginx
dnf search "machine learning"
dnf info python3-numpy

# ดูแพ็กเกจที่ติดตั้ง
rpm -qa | grep python

# ไฟล์ในแพ็กเกจและย้อนกลับ
rpm -ql nginx
rpm -qf /usr/sbin/nginx

# Group (ติดตั้งกลุ่มแพ็กเกจ เช่น development tools)
sudo dnf group install "Development Tools"

# ย้อนกลับ transaction
sudo dnf history
sudo dnf history undo 42

2.6.4 Pacman และ AUR (Arch)

pacman ใช้ format .pkg.tar.zst เก็บในรูป tarball บีบอัดด้วย zstd

# Sync ฐานข้อมูล + อัปเกรดระบบ (ทำพร้อมกันเสมอ! Arch เป็น rolling release)
sudo pacman -Syu

# ติดตั้ง
sudo pacman -S nginx git curl

# ถอน (พร้อม dependency ที่ไม่มีใครใช้)
sudo pacman -Rns nginx

# ค้นหา
pacman -Ss neovim
pacman -Si python

# แสดงที่ติดตั้ง
pacman -Q | wc -l      # นับจำนวนแพ็กเกจ
pacman -Qe             # explicit (ที่สั่งติดตั้งเอง)
pacman -Qdt            # orphan dependency (ไม่มีใครใช้แล้ว)
pacman -Qi nginx       # ข้อมูลแพ็กเกจ
pacman -Ql nginx       # ไฟล์ในแพ็กเกจ
pacman -Qo /usr/bin/ls # ไฟล์นี้มาจากแพ็กเกจไหน

# ล้าง cache
sudo pacman -Sc

AUR (Arch User Repository) คือคลัง PKGBUILD ที่ชุมชนส่งมา ต้องใช้ AUR helper เช่น yay, paru

# ติดตั้ง yay ครั้งแรก (ต้อง clone + makepkg)
sudo pacman -S --needed base-devel git
git clone https://aur.archlinux.org/yay-bin.git
cd yay-bin && makepkg -si

# ติดตั้งจาก AUR (เช่น visual-studio-code-bin)
yay -S visual-studio-code-bin

# อัปเดตทั้ง official + AUR
yay -Syu

2.6.5 Zypper (openSUSE), Portage/emerge (Gentoo), APK (Alpine), XBPS (Void)

Zypper (openSUSE)

sudo zypper refresh
sudo zypper update
sudo zypper install nginx
sudo zypper remove nginx
zypper search nginx
zypper info nginx

Portage / emerge (Gentoo) — compile จาก source

# Sync repository (portage tree)
sudo emerge --sync
# ติดตั้งและอัปเกรด world
sudo emerge -avuDN @world
# ติดตั้งแพ็กเกจ
sudo emerge -av www-servers/nginx

APK (Alpine) — เบาและเร็วมาก

sudo apk update
sudo apk upgrade
sudo apk add nginx curl git
sudo apk del nginx
apk search nginx
apk info -L nginx

XBPS (Void)

sudo xbps-install -Su          # อัปเดตระบบ
sudo xbps-install -S nginx     # ติดตั้ง
sudo xbps-remove -R nginx      # ถอนพร้อม dependency
xbps-query -Rs nginx           # ค้นหาใน repo

2.6.6 Universal: Flatpak, Snap, AppImage, Nix

Package format ข้าม distro ที่ออกแบบมาเพื่อแก้ปัญหาความต่าง ecosystem

Format ผู้สร้าง Sandboxing ขนาด หลายเวอร์ชันพร้อมกัน หมายเหตุ
Flatpak ชุมชน (Red Hat หลัก) ✅ (Bubblewrap) ปานกลาง Flathub เป็น repo หลัก
Snap Canonical ✅ (AppArmor) ใหญ่ Snap Store ควบคุมโดย Canonical
AppImage Simon Peter ❌ (portable) ใหญ่ ไฟล์เดียวรันได้ ไม่ต้อง install
Nix NixOS community มี option ปานกลาง reproducible, functional
# Flatpak
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install flathub org.mozilla.firefox
flatpak run org.mozilla.firefox

# Snap
sudo snap install code --classic
sudo snap refresh

# AppImage (แค่ chmod +x แล้วรัน)
chmod +x MyApp-x86_64.AppImage
./MyApp-x86_64.AppImage

2.6.7 Repository, PPA, COPR

# เพิ่ม PPA
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12
sudo dnf copr enable user/project
sudo dnf install package-from-copr

2.7 การจัดการผู้ใช้และสิทธิ์ (User & Permission Management)

Linux เป็น multi-user system ตั้งแต่กำเนิด การแยกสิทธิ์ระหว่างผู้ใช้และระหว่างโปรเซสจึงฝังอยู่ในแกนกลาง ทุกไฟล์มี owner และ group และมีสิทธิ์ 3 ระดับ (owner / group / others) x 3 การกระทำ (read / write / execute)

2.7.1 /etc/passwd, /etc/shadow, /etc/group, /etc/sudoers

/etc/passwd เก็บข้อมูลผู้ใช้ (อ่านได้โดยทุกคน — ในอดีตเก็บ password hash ด้วย ปัจจุบันย้ายไป shadow แล้ว)

รูปแบบแต่ละบรรทัด (7 field คั่นด้วย :)

moo:x:1000:1000:Moo Lecturer,,,:/home/moo:/bin/bash
 ^   ^  ^    ^        ^         ^          ^
 |   |  |    |        |         |          shell
 |   |  |    |        |         home directory
 |   |  |    |        GECOS (full name, etc.)
 |   |  |    GID (primary group)
 |   |  UID
 |   password placeholder (x = ใช้ shadow)
 username

/etc/shadow (อ่านได้เฉพาะ root) เก็บ password hash

moo:$6$rounds=656000$salt$hashedpw:19876:0:99999:7:::
 ^    ^                              ^
 user hashed password (SHA-512 ขึ้นต้น $6$) วันที่เปลี่ยน password ล่าสุด

/etc/group

sudo:x:27:moo,alice
docker:x:999:moo

/etc/sudoers แก้ด้วย visudo เท่านั้น (ป้องกัน syntax ผิดที่ทำให้ระบบพัง)

# ให้ user moo สั่ง sudo ได้ทุกอย่าง
moo ALL=(ALL:ALL) ALL

# ให้ group wheel/sudo สั่งได้โดยต้องใส่ password
%wheel ALL=(ALL) ALL

# อนุญาตคำสั่งเฉพาะ โดยไม่ต้องใส่ password
alice ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx

2.7.2 useradd, usermod, userdel, passwd, groupadd

# สร้าง user ใหม่พร้อม home directory และ shell เป็น bash
sudo useradd -m -s /bin/bash -c "Aj. Moo Lecturer" moo

# ตั้งรหัสผ่าน
sudo passwd moo

# สร้าง group
sudo groupadd developers

# เพิ่ม user ลง group (สำคัญ: -aG = append; ถ้าลืม -a จะลบจาก group อื่น!)
sudo usermod -aG developers,docker moo

# เปลี่ยน shell
sudo usermod -s /bin/zsh moo

# ล็อค/ปลดล็อคบัญชี
sudo usermod -L moo    # lock
sudo usermod -U moo    # unlock

# ลบ user (พร้อม home directory)
sudo userdel -r oldemp

# ดูสมาชิก group
getent group developers
groups moo
id moo

2.7.3 sudo, su, visudo

# รันคำสั่งเป็น root
sudo systemctl restart nginx

# เปิด shell เป็น root
sudo -i
sudo -s
su -                 # ใส่ password ของ root

# รันเป็น user อื่น
sudo -u postgres psql

# แก้ sudoers อย่างปลอดภัย
sudo visudo

# แก้ drop-in file (แนะนำ)
sudo visudo -f /etc/sudoers.d/moo

2.7.4 File Permission: rwx, Owner/Group/Others

สิทธิ์ไฟล์แสดงด้วย 10 ตัวอักษร (หรือเลขฐานแปด)

-rwxr-xr--  1 moo devs 4096 Apr 20 14:22 script.sh
^^^^^^^^^^
│└──┴──┴── others: r-- (อ่านได้)
│   └──┴── group: r-x (อ่าน + execute)
│      └── owner: rwx (อ่าน + เขียน + execute)
└── type (- = file, d = directory, l = symlink, b = block, c = char, s = socket, p = pipe)

แปลงเป็นเลข octal: r=4, w=2, x=1

rwx=4+2+1=7, r-x=4+1=5, r--=4

ดังนั้น rwxr-xr-- = 754

ความหมายของ rwx ต่างกันระหว่าง file และ directory

สิทธิ์ ใน File ใน Directory
r อ่านเนื้อหาไฟล์ได้ ls ดูชื่อไฟล์ใน dir ได้
w แก้ไขเนื้อหาได้ สร้าง/ลบ/rename ไฟล์ใน dir ได้
x รันเป็นโปรแกรม/สคริปต์ได้ cd เข้าไปใน dir ได้ / เข้าถึงไฟล์ใน dir ได้

2.7.5 chmod (Symbolic และ Octal), chown, chgrp

Symbolic mode: ใช้ตัวอักษร

# u=user(owner), g=group, o=others, a=all
# +,-,= เพิ่ม, ลบ, กำหนด
# r,w,x,X(exec เฉพาะ dir/file ที่ exec อยู่แล้ว),s(SUID/SGID),t(sticky)

chmod u+x script.sh          # ให้ owner รันได้
chmod g-w file.txt           # ลบสิทธิ์เขียนของ group
chmod o= secret.key          # others ไม่มีสิทธิ์เลย
chmod a+r public.txt         # ทุกคนอ่านได้
chmod u=rwx,g=rx,o=r dir/    # กำหนดตรง ๆ
chmod -R g+w project/        # recursive
chmod -R u=rwX,g=rX,o= dir/  # X ตามที่อธิบายข้างบน

Octal mode: ใช้เลข 3 หลัก (หรือ 4 หลักถ้ามี SUID/SGID/Sticky)

chmod 755 script.sh          # rwxr-xr-x (ใช้กับ script, binary)
chmod 644 file.txt           # rw-r--r-- (ใช้กับไฟล์ทั่วไป)
chmod 600 ~/.ssh/id_ed25519  # rw------- (ต้อง private!)
chmod 700 ~/.ssh             # rwx------
chmod 750 /home/moo          # rwxr-x---
chmod 4755 /usr/bin/passwd   # SUID + 755

chown / chgrp

# เปลี่ยนเจ้าของ
sudo chown moo file.txt

# เปลี่ยนเจ้าของและ group พร้อมกัน
sudo chown moo:developers file.txt

# เปลี่ยนเฉพาะ group
sudo chgrp developers file.txt

# Recursive
sudo chown -R moo:moo /home/moo/project

2.7.6 Special Permission: SUID, SGID, Sticky Bit

# SUID (4xxx)
sudo chmod 4755 myprog        # แสดงเป็น rwsr-xr-x
# ถ้า owner ไม่มี x: แสดงเป็น rwSr-xr-x

# SGID (2xxx) — ใช้บ่อยกับ directory สำหรับงานกลุ่ม
sudo mkdir /srv/shared
sudo chown root:developers /srv/shared
sudo chmod 2775 /srv/shared    # rwxrwsr-x
# ทุกไฟล์ที่สร้างใน /srv/shared จะเป็นของ group developers อัตโนมัติ

# Sticky Bit (1xxx)
sudo chmod 1777 /tmp           # rwxrwxrwt
# ตรวจสอบ /tmp ของระบบ: จะเห็น 't'
ls -ld /tmp

2.7.7 ACL (setfacl, getfacl)

POSIX Access Control List (ACL) แก้ข้อจำกัดของระบบ owner/group/others ที่กำหนดสิทธิ์ผู้ใช้หลายคนไม่ได้

# ติดตั้ง (บาง distro ไม่มีมาให้)
sudo apt install acl          # Debian/Ubuntu
sudo pacman -S acl            # Arch (มักมีแล้ว)

# ตรวจสอบ ACL
getfacl project/

# ให้ user alice อ่าน+เขียน file โดยไม่เปลี่ยน group
setfacl -m u:alice:rw file.txt

# ให้ group qa อ่านอย่างเดียว
setfacl -m g:qa:r file.txt

# default ACL บน directory (ทุกไฟล์ใหม่จะสืบทอด)
setfacl -d -m u:alice:rwx shared_dir/

# ลบ ACL
setfacl -x u:alice file.txt
setfacl -b file.txt    # ลบทั้งหมด

# ดูผลลัพธ์ (จะเห็น '+' ท้ายสิทธิ์ปกติใน ls -l)
ls -l file.txt
# -rw-rw-r--+ 1 moo devs 0 Apr 20 14:30 file.txt

2.7.8 Capability และ umask

Linux Capability แบ่งสิทธิ์ root ออกเป็นส่วน ๆ (กว่า 40 caps) แทนที่จะให้ทั้งหมด เช่น

# ดู capability ของไฟล์
getcap /usr/bin/ping
# /usr/bin/ping cap_net_raw=ep

# ตั้ง capability ให้ binary (แทน SUID)
sudo setcap cap_net_bind_service=+ep /usr/local/bin/mynode
# ทำให้ Node.js bind port 80 ได้โดยไม่ต้องรันด้วย root

umask คือ "mask" ที่หักสิทธิ์ default เมื่อสร้างไฟล์/directory

permfile = 666 umask , permdir = 777 umask

ค่า umask ทั่วไป: 022 (ไฟล์ใหม่ 644, dir ใหม่ 755), 027 (ไฟล์ใหม่ 640, dir ใหม่ 750 — เข้มงวดกว่า)

# ดูค่าปัจจุบัน
umask           # เช่น 0022
# ตั้งใหม่ (มีผลเฉพาะ shell session นี้)
umask 027
# ทดสอบ
touch test.txt && ls -l test.txt   # ต้องได้ rw-r-----

# ตั้งถาวร: เพิ่มลง ~/.bashrc หรือ /etc/profile
echo "umask 027" >> ~/.bashrc

2.8 การติดตั้งและตั้งค่าพื้นฐาน

การติดตั้ง Linux ประกอบด้วยขั้นตอนหลัก ๆ ได้แก่ เตรียม media → boot → แบ่ง partition → ติดตั้ง base → ติดตั้ง bootloader → ตั้งค่า network/locale/user → reboot

flowchart TB
    A["1. ดาวน์โหลด ISO
(Download)"] --> B["2. เขียน USB
(dd/Ventoy)"] B --> C["3. Boot USB
(F12/F9/Del)"] C --> D["4. แบ่ง Partition
(fdisk/parted/gparted)"] D --> E["5. Format FS
(mkfs.ext4/btrfs)"] E --> F["6. Mount & Install
(bootstrap)"] F --> G["7. ติดตั้ง Bootloader
(GRUB)"] G --> H["8. ตั้งค่าพื้นฐาน
(user, network, locale)"] H --> I["9. Reboot
เข้าใช้งาน"]

2.8.1 การเตรียม Installation Media (dd, Ventoy, Rufus)

dd (Linux/macOS) — เขียน ISO ลง USB แบบ raw

# ตรวจชื่อ USB (ระวัง! อย่าให้ชี้ไปผิด disk)
lsblk
# สมมติ USB คือ /dev/sdb (ไม่ใช่ /dev/sdb1)

# unmount ก่อน
sudo umount /dev/sdb*

# เขียน ISO (ใช้เวลาสักพัก, status=progress แสดงความคืบหน้า)
sudo dd if=./cachyos-desktop-linux-250720.iso of=/dev/sdb \
        bs=4M status=progress oflag=sync conv=fdatasync
sync

Ventoy — เขียน 1 ครั้ง ใช้ได้หลาย ISO แค่ copy ไฟล์ลงไป

# ติดตั้ง Ventoy ลง USB (ล้างข้อมูลทั้งหมด!)
sudo ./Ventoy2Disk.sh -i /dev/sdb
# หลังจากนั้น mount USB แล้ว copy ISO ลงไปได้เลย
cp ubuntu-24.04.iso /run/media/moo/Ventoy/
cp archlinux.iso    /run/media/moo/Ventoy/

Rufus / Etcher — GUI บน Windows/macOS

2.8.2 Partition Scheme (MBR vs GPT) และ Filesystem Layout

MBR (Master Boot Record) — มาตรฐานเก่า

GPT (GUID Partition Table) — มาตรฐานใหม่

Layout แนะนำสำหรับ Desktop/Server ทั่วไป (UEFI + GPT)

Partition Mount Size FS หมายเหตุ
1 /boot/efi 512 MB - 1 GB FAT32 ESP (EFI System Partition)
2 /boot (optional) 1 GB ext4 แยกสำหรับ encrypted root
3 [SWAP] 8-16 GB swap หรือใช้ swapfile ก็ได้
4 / 50-100 GB+ ext4 / btrfs root filesystem
5 /home (optional) ที่เหลือ ext4 / btrfs แยก home ออกเพื่อติดตั้งใหม่ได้ง่าย

สูตรคำนวณ swap อย่างง่าย

swapsuggest = { RAM, ถ้าต้องการ hibernation RAM, ถ้าไม่ hibernate (ประมาณ)

เช่น RAM 32 GB → swap ~6 GB (ไม่ hibernate) หรือ 32 GB (hibernate)

คำสั่งสำหรับแบ่ง partition บน Linux ที่ติดตั้งอยู่

# ดู partition ปัจจุบัน
lsblk -f
sudo fdisk -l

# ใช้ cfdisk (TUI ใช้งานง่าย)
sudo cfdisk /dev/sda

# หรือใช้ parted (non-interactive ได้)
sudo parted /dev/sda mklabel gpt
sudo parted /dev/sda mkpart ESP fat32 1MiB 513MiB
sudo parted /dev/sda set 1 esp on
sudo parted /dev/sda mkpart primary ext4 513MiB 100%

# Format
sudo mkfs.fat -F32 /dev/sda1
sudo mkfs.ext4 /dev/sda2
# หรือ btrfs
sudo mkfs.btrfs -L root /dev/sda2

2.8.3 Bootloader: GRUB, systemd-boot, rEFInd

GRUB 2 (GRand Unified Bootloader) — ทรงพลังที่สุด รองรับทั้ง BIOS และ UEFI

# ติดตั้ง GRUB (UEFI)
sudo grub-install --target=x86_64-efi \
     --efi-directory=/boot/efi --bootloader-id=GRUB

# ติดตั้ง GRUB (Legacy BIOS)
sudo grub-install --target=i386-pc /dev/sda

# สร้าง grub.cfg
sudo grub-mkconfig -o /boot/grub/grub.cfg

# แก้ตัวเลือกหลัก: /etc/default/grub
# GRUB_TIMEOUT=5
# GRUB_DEFAULT=0
# GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
# หลังแก้ต้อง mkconfig ใหม่

systemd-boot — เรียบง่าย เฉพาะ UEFI

# ติดตั้ง
sudo bootctl install

# สร้าง entry: /boot/loader/entries/arch.conf
# title   Arch Linux
# linux   /vmlinuz-linux
# initrd  /initramfs-linux.img
# options root=UUID=xxx rw

rEFInd — GUI สวย เหมาะกับ dual-boot หลาย OS

2.8.4 Dual-boot กับ Windows/macOS

ขั้นตอนทั่วไปสำหรับ Windows + Linux dual-boot

  1. Install Windows ก่อนเสมอ (Windows ชอบเขียน MBR/EFI ของตัวเอง ทับ bootloader อื่น)
  2. บูต Windows เข้าไป ปิด Fast Startup และ BitLocker
  3. ใช้ Disk Management ย่อ (shrink) partition ของ Windows
  4. บูต Linux installer เลือก "Install alongside Windows" หรือแบ่งเอง
  5. GRUB จะ detect Windows ใน EFI และเพิ่ม entry อัตโนมัติ
  6. ในไบออสตั้ง Linux ก่อน Windows ในลำดับ boot

ปัญหาที่เจอบ่อย

2.8.5 Network เบื้องต้น (NetworkManager, systemd-networkd)

NetworkManager — ใช้บน Desktop เกือบทุก distro

# TUI client
nmtui

# CLI
nmcli device status
nmcli device wifi list
nmcli device wifi connect "ShopeeFood_5G" password "mypass"

# แก้ไข connection ที่มีอยู่
nmcli connection show
nmcli connection modify "Wired connection 1" ipv4.addresses 192.168.1.50/24
nmcli connection modify "Wired connection 1" ipv4.gateway 192.168.1.1
nmcli connection modify "Wired connection 1" ipv4.dns "1.1.1.1 8.8.8.8"
nmcli connection modify "Wired connection 1" ipv4.method manual
nmcli connection up "Wired connection 1"

systemd-networkd — minimal นิยมบน server

สร้าง /etc/systemd/network/20-wired.network

[Match]
Name=enp3s0

[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=1.1.1.1
DNS=8.8.8.8
sudo systemctl enable --now systemd-networkd
sudo systemctl enable --now systemd-resolved

ตรวจสอบและทดสอบ

ip addr
ip route
ss -tulnp                  # port ที่ listen
ping -c 3 1.1.1.1          # ทดสอบ IP routing
ping -c 3 google.com       # ทดสอบ DNS
resolvectl status          # สถานะ DNS (systemd)

2.8.6 Locale, Timezone, Keyboard Layout

Locale — ภาษา, ตัวเลข, สกุลเงิน, วันเวลา

# ดู locale ปัจจุบัน
locale

# ดู locale ที่ติดตั้ง
locale -a

# Debian/Ubuntu: แก้แล้วสร้างใหม่
sudo dpkg-reconfigure locales

# หรือเปิดใช้ th_TH.UTF-8 และ en_US.UTF-8 ใน /etc/locale.gen
sudo sed -i 's/^#\(th_TH.UTF-8\)/\1/;s/^#\(en_US.UTF-8\)/\1/' /etc/locale.gen
sudo locale-gen

# ตั้ง default (ทั้งระบบ)
sudo localectl set-locale LANG=en_US.UTF-8 LC_TIME=th_TH.UTF-8

Timezone

# ดูโซนปัจจุบัน
timedatectl

# ตั้งโซน
sudo timedatectl set-timezone Asia/Bangkok

# เปิด NTP sync
sudo timedatectl set-ntp true

# ดูรายการโซนทั้งหมด
timedatectl list-timezones | grep -i bangkok

Keyboard Layout

# TTY/Console (เฉพาะตอนไม่มี GUI)
sudo localectl set-keymap us
sudo localectl set-keymap th

# GUI (X11/Wayland) — ใช้ localectl เช่นกันหรือตั้งใน desktop
sudo localectl set-x11-keymap "us,th" pc105 "" "grp:alt_shift_toggle"
# สลับ layout ด้วย Alt+Shift

สรุปบทที่ 2

บทนี้ได้ปูพื้นฐานของระบบปฏิบัติการ Linux ตั้งแต่ประวัติและปรัชญา Unix ที่กลายเป็นรากฐานของทุกอย่าง สถาปัตยกรรมแบบ monolithic kernel + LKM ที่ผสมข้อดีของ monolithic และ modular เข้าด้วยกัน ระบบนิเวศของ distribution ที่หลากหลายตามปรัชญาและกลุ่มเป้าหมาย มาตรฐาน FHS ที่ทำให้ทุก distro มีโครงสร้างคุ้นตา init system ที่จัดการบริการ (โดยเฉพาะ systemd ที่ครอบคลุม) package manager หลากหลายตระกูล การจัดการผู้ใช้และสิทธิ์ที่เป็นหัวใจความปลอดภัย จนถึงการติดตั้งและตั้งค่าพื้นฐานที่ผู้เรียนสามารถนำไปทดลองใช้งานจริงได้บนเครื่องของตนเอง