Bash Scripting สำหรับ SysAdmin บน Ubuntu Server 26.04

Bash Scripting สำหรับ SysAdmin บน Ubuntu Server 26.04

งานของ SysAdmin หลายอย่างเป็นงานที่ต้องทำซ้ำ เช่น ตรวจสอบพื้นที่ Disk, ดูสถานะ Service, สำรองไฟล์ Configuration หรือค้นหา Error จาก Log หากต้องพิมพ์คำสั่งเดิมทุกวัน นอกจากเสียเวลาแล้ว ยังมีโอกาสพิมพ์ผิดหรือข้ามขั้นตอนสำคัญได้

Bash Scripting ช่วยรวบรวมคำสั่งเหล่านี้ไว้ในไฟล์เดียว ทำให้สามารถเรียกใช้งานซ้ำ ตั้งเวลาทำงานอัตโนมัติ และตรวจสอบผลลัพธ์อย่างเป็นระบบได้

บทความนี้จะเริ่มตั้งแต่โครงสร้างพื้นฐานของ Bash Script ไปจนถึงการสร้างสคริปต์ตรวจสอบรายละเอียดของ Ubuntu Server ที่สามารถนำไปใช้งานจริงได้

Ubuntu Server 26.04 LTS มีชื่อรุ่นว่า Resolute Raccoon เปิดตัวเมื่อวันที่ 23 เมษายน 2026 และอยู่ในช่วง Standard Support ถึงเดือนพฤษภาคม 2031

สภาพแวดล้อมอ้างอิงของบทความ

Operating System: Ubuntu Server 26.04 LTS
Codename: Resolute Raccoon
Shell: GNU Bash 5.3
Bash Package: 5.3-2ubuntu1

Ubuntu Repository ของรุ่น 26.04 LTS จัดเตรียม Bash รุ่น 5.3 เป็นค่าเริ่มต้น


สิ่งที่ต้องมีก่อนเริ่ม

ผู้อ่านควรมีสิ่งต่อไปนี้

  • Ubuntu Server 26.04 LTS

  • บัญชีผู้ใช้ที่เรียกใช้ sudo ได้

  • ความรู้พื้นฐานเกี่ยวกับ Linux Command Line

  • Text Editor เช่น nano, vim หรือ Visual Studio Code

  • สิทธิ์ SSH สำหรับเชื่อมต่อ Server

ตรวจสอบรุ่นของระบบปฏิบัติการ

# แสดงข้อมูล Ubuntu ที่กำลังใช้งาน
cat /etc/os-release

ตรวจสอบรุ่นของ Bash

# แสดงเวอร์ชันของ Bash
bash --version


Bash Script คืออะไร

Bash Script คือไฟล์ข้อความที่บรรจุคำสั่ง Linux ตั้งแต่หนึ่งคำสั่งขึ้นไป เมื่อเรียกใช้งาน Bash จะอ่านคำสั่งตามลำดับจากบนลงล่าง

ตัวอย่างงานที่เหมาะกับ Bash Script ได้แก่

  • ตรวจสอบพื้นที่ Disk และ Memory

  • สำรองข้อมูลหรือ Configuration

  • ตรวจสอบสถานะ Service

  • อ่านและกรอง Log

  • สร้าง User จำนวนมาก

  • ตรวจสอบ Network Connectivity

  • Deploy Application

  • ตั้งเวลาทำงานด้วย Cron

  • เรียก REST API ด้วย curl

Bash เหมาะกับงาน System Administration เพราะสามารถเรียกใช้คำสั่ง Linux และเชื่อมต่อคำสั่งหลายตัวเข้าด้วยกันได้โดยตรง


สร้าง Bash Script แรก

สร้าง Directory สำหรับเก็บ Lab

# สร้าง Directory สำหรับฝึกเขียน Bash Script
mkdir -p ~/bash-lab

# เข้าไปยัง Directory
cd ~/bash-lab

สร้างไฟล์ชื่อ hello.sh

nano hello.sh

เพิ่มคำสั่งต่อไปนี้

#!/usr/bin/env bash

# แสดงข้อความบนหน้าจอ
echo "Hello SysAdmin"

# แสดงชื่อเครื่อง
echo "Hostname: $(hostname)"

# แสดงเวลาปัจจุบัน
echo "Current time: $(date)"


บันทึกไฟล์และกำหนดสิทธิ์ Execute

# เพิ่มสิทธิ์ให้ไฟล์สามารถ Execute ได้
chmod +x hello.sh

เรียกใช้งาน:

./hello.sh

ความหมายของ Shebang

บรรทัดแรกของ Script เรียกว่า shebang

#!/usr/bin/env bash

Shebang ระบุว่าไฟล์นี้ต้องถูกประมวลผลด้วย Bash การใช้ /usr/bin/env bash จะค้นหา Bash จากตัวแปร PATH ของระบบ

สำหรับ Script ที่ต้องควบคุมตำแหน่ง Interpreter อย่างแน่นอน สามารถใช้:

#!/bin/bash


ใช้ Strict Mode ลดข้อผิดพลาด

Script สำหรับงานดูแลระบบควรตรวจจับข้อผิดพลาดให้เร็วที่สุด ตัวอย่างโครงสร้างที่แนะนำคือ:

#!/usr/bin/env bash

# -E ส่ง ERR trap เข้าไปใน function
# -e หยุด Script เมื่อคำสั่งล้มเหลว
# -u แจ้ง Error เมื่อเรียกตัวแปรที่ยังไม่ได้กำหนด
# pipefail ทำให้ Pipeline ตรวจพบคำสั่งที่ล้มเหลว
set -Eeuo pipefail

pipefail ทำให้สถานะของ Pipeline เป็นค่าจากคำสั่งด้านขวาสุดที่ล้มเหลว แทนที่จะตรวจเฉพาะคำสั่งสุดท้าย ส่วน bash -n สามารถใช้ตรวจ Syntax โดยไม่ Execute Script

ตัวอย่างปัญหาที่ pipefail ช่วยตรวจพบ

#!/usr/bin/env bash
set -o pipefail

# grep อ่านไฟล์ที่ไม่มีอยู่ แม้ wc จะทำงานสำเร็จ
grep "ERROR" /var/log/file-does-not-exist.log | wc -l

ตรวจสอบ Exit Status

echo $?

ค่า 0 หมายถึงสำเร็จ ส่วนค่าที่ไม่ใช่ 0 หมายถึงเกิด Error หรือพบเงื่อนไขที่โปรแกรมกำหนดไว้

Strict Mode ไม่ได้แทนที่การจัดการ Error ทั้งหมด คำสั่งที่อยู่ภายใน if, while, until, && และ || มีเงื่อนไขการทำงานร่วมกับ errexit ที่แตกต่างกัน จึงควรทดสอบ Script ทุกเส้นทางก่อนใช้บน Production


ตัวแปรและการ Quote

กำหนดตัวแปรได้โดยไม่ใส่ช่องว่างรอบเครื่องหมาย =

#!/usr/bin/env bash

SERVER_NAME="web-server-01"
BACKUP_DIR="/var/backups/my server"

echo "$SERVER_NAME"
echo "$BACKUP_DIR"

ควรครอบตัวแปรด้วย Double Quote

# ถูกต้อง รองรับค่าที่มีช่องว่าง
cp "$SOURCE_FILE" "$DESTINATION_FILE"

หลีกเลี่ยง:

# อาจเกิด Word Splitting หรือ Filename Expansion
cp $SOURCE_FILE $DESTINATION_FILE

Bash จะดำเนินการ Parameter Expansion, Word Splitting และ Filename Expansion ตามลำดับของ Shell Expansion การ Quote ตัวแปรจึงช่วยลดปัญหาค่าที่มีช่องว่างหรืออักขระพิเศษ

กำหนดค่าเริ่มต้นให้ตัวแปร

# หาก BACKUP_DAYS ไม่มีค่าหรือเป็นค่าว่าง ให้ใช้ 7
BACKUP_DAYS="${BACKUP_DAYS:-7}"

echo "เก็บ Backup เป็นเวลา $BACKUP_DAYS วัน"

เรียกใช้งานด้วยค่าที่กำหนดจาก Environment:

BACKUP_DAYS=14 ./backup.sh

รับ Argument จากผู้ใช้

Bash ใช้ตัวแปรพิเศษสำหรับรับ Argument

$0    ชื่อ Script
$1    Argument ตัวที่ 1
$2    Argument ตัวที่ 2
$#    จำนวน Argument
$@    Argument ทั้งหมด
$?    Exit Status ของคำสั่งล่าสุด

ตัวอย่าง Script ตรวจสอบ Service:

#!/usr/bin/env bash
set -Eeuo pipefail

# ตรวจสอบว่าผู้ใช้ส่งชื่อ Service มาหรือไม่
if (( $# != 1 )); then
    echo "วิธีใช้: $0 <service-name>" >&2
    exit 2
fi

SERVICE_NAME="$1"

if systemctl is-active --quiet "$SERVICE_NAME"; then
    echo "Service $SERVICE_NAME กำลังทำงาน"
    exit 0
else
    echo "Service $SERVICE_NAME ไม่ได้อยู่ในสถานะ active"
    exit 1
fi

บันทึกเป็น check-service.sh แล้วทดสอบ:

chmod +x check-service.sh

# ตรวจสอบ SSH Service
./check-service.sh ssh

# ตรวจสอบ Cron Service
./check-service.sh cron

เงื่อนไขใน Bash

Bash รองรับ if, elif และ else

DISK_USAGE=82

if (( DISK_USAGE >= 90 )); then
    echo "CRITICAL: Disk ใกล้เต็ม"
elif (( DISK_USAGE >= 80 )); then
    echo "WARNING: Disk ใช้งานเกิน 80%"
else
    echo "OK: Disk ปกติ"
fi

ตัวดำเนินการที่ใช้บ่อย:

ตัวเลข
-eq    เท่ากับ
-ne    ไม่เท่ากับ
-gt    มากกว่า
-ge    มากกว่าหรือเท่ากับ
-lt    น้อยกว่า
-le    น้อยกว่าหรือเท่ากับ

ไฟล์
-f     เป็นไฟล์ปกติ
-d     เป็น Directory
-e     มีไฟล์หรือ Directory อยู่
-r     อ่านได้
-w     เขียนได้
-x     Execute ได้

ข้อความ
-z     เป็นข้อความว่าง
-n     ไม่ใช่ข้อความว่าง
==     เท่ากัน
!=     ไม่เท่ากัน

ตัวอย่างตรวจสอบไฟล์:

CONFIG_FILE="/etc/ssh/sshd_config"

if [[ -f "$CONFIG_FILE" && -r "$CONFIG_FILE" ]]; then
    echo "สามารถอ่าน $CONFIG_FILE ได้"
else
    echo "ไม่พบไฟล์หรือไม่มีสิทธิ์อ่าน" >&2
fi

Loop สำหรับจัดการข้อมูลหลายรายการ

ใช้ for Loop

SERVICES=("ssh" "cron" "systemd-resolved")

for service in "${SERVICES[@]}"; do
    if systemctl is-active --quiet "$service"; then
        echo "[OK] $service"
    else
        echo "[WARN] $service"
    fi
done

การใช้ "${SERVICES[@]}" จะส่งสมาชิกแต่ละรายการเป็น Argument แยกกันอย่างถูกต้อง

ใช้ while Loop อ่านไฟล์

สมมติว่ามีไฟล์ servers.txt:

server01
server02
server03

Script สำหรับอ่านข้อมูลทีละบรรทัด:

#!/usr/bin/env bash
set -Eeuo pipefail

while IFS= read -r server; do
    [[ -n "$server" ]] || continue
    echo "กำลังตรวจสอบ $server"
done < servers.txt

แยกคำสั่งเป็น Function

Function ทำให้ Script อ่านง่าย ลดคำสั่งซ้ำ และสามารถทดสอบแต่ละส่วนแยกกันได้

#!/usr/bin/env bash
set -Eeuo pipefail

log_info() {
    printf '%s [INFO] %s\n' "$(date '+%F %T')" "$*"
}

check_command() {
    local command_name="$1"

    if command -v "$command_name" >/dev/null 2>&1; then
        log_info "พบคำสั่ง $command_name"
    else
        printf 'ไม่พบคำสั่ง %s\n' "$command_name" >&2
        return 1
    fi
}

check_command curl
check_command systemctl

ควรใช้ local สำหรับตัวแปรภายใน Function เพื่อป้องกันการเขียนทับตัวแปรส่วนอื่นของ Script


Project: สร้าง Script ตรวจสุขภาพ Ubuntu Server

ต่อไปเป็น Script สำหรับตรวจสอบ:

  • พื้นที่ Disk

  • การใช้งาน Memory

  • สถานะ Service

  • Kernel และ Uptime

  • Exit Status สำหรับนำไปเชื่อมต่อ Monitoring System

สร้างไฟล์:

nano server-healthcheck.sh

เพิ่ม Code ต่อไปนี้:

#!/usr/bin/env bash
set -Eeuo pipefail

# กำหนด IFS เพื่อลดปัญหาการแยกคำจากช่องว่าง
IFS=$'\n\t'

# กำหนด PATH ให้แน่นอนเมื่อเรียกจาก Cron หรือ sudo
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# ไฟล์ที่ Script สร้างขึ้นใหม่จะไม่เปิดสิทธิ์ให้ผู้ใช้อื่นเขียน
umask 027

readonly SCRIPT_NAME="${0##*/}"
readonly HOST_NAME="$(hostname -f 2>/dev/null || hostname)"

# สามารถกำหนดค่าใหม่ผ่าน Environment Variable
DISK_THRESHOLD="${DISK_THRESHOLD:-80}"
MEM_THRESHOLD="${MEM_THRESHOLD:-85}"
SERVICE_LIST="${SERVICE_LIST:-ssh cron}"

EXIT_CODE=0

log() {
    local level="$1"
    shift

    printf '%s [%s] %s: %s\n' \
        "$(date '+%F %T')" \
        "$level" \
        "$SCRIPT_NAME" \
        "$*"
}

die() {
    log "ERROR" "$*" >&2
    exit 2
}

on_error() {
    local exit_status=$?

    log "ERROR" \
        "คำสั่งล้มเหลวที่บรรทัด ${BASH_LINENO[0]:-$LINENO}: ${BASH_COMMAND}" \
        >&2

    exit "$exit_status"
}

# เรียก Function on_error เมื่อเกิด Error ที่ไม่ได้จัดการ
trap on_error ERR

require_command() {
    command -v "$1" >/dev/null 2>&1 ||
        die "ไม่พบคำสั่งที่จำเป็น: $1"
}

validate_threshold() {
    local name="$1"
    local value="$2"

    # ตรวจสอบว่าเป็นจำนวนเต็ม
    [[ "$value" =~ ^[0-9]+$ ]] ||
        die "$name ต้องเป็นจำนวนเต็ม 0-100"

    # ตรวจสอบช่วงของค่า
    (( value >= 0 && value <= 100 )) ||
        die "$name ต้องอยู่ระหว่าง 0-100"
}

check_disk() {
    local filesystem
    local usage
    local mountpoint
    local usage_number

    log "INFO" \
        "ตรวจสอบพื้นที่ Disk เกณฑ์เตือน ${DISK_THRESHOLD}%"

    while IFS=' ' read -r filesystem usage mountpoint; do
        # ตัดเครื่องหมาย % ออกจากค่าการใช้งาน
        usage_number="${usage%\%}"

        if (( usage_number >= DISK_THRESHOLD )); then
            log "WARN" \
                "$mountpoint ใช้พื้นที่ ${usage_number}% (${filesystem})"

            EXIT_CODE=1
        else
            log "OK" \
                "$mountpoint ใช้พื้นที่ ${usage_number}% (${filesystem})"
        fi
    done < <(
        df --output=source,pcent,target \
            -x tmpfs \
            -x devtmpfs |
        tail -n +2
    )
}

check_memory() {
    local total_kb
    local available_kb
    local used_percent

    # อ่าน MemTotal และ MemAvailable จาก Kernel
    IFS=' ' read -r total_kb available_kb < <(
        awk '
            /MemTotal:/ {
                total=$2
            }

            /MemAvailable:/ {
                available=$2
            }

            END {
                print total, available
            }
        ' /proc/meminfo
    )

    (( total_kb > 0 )) ||
        die "ไม่สามารถอ่านข้อมูล Memory ได้"

    used_percent=$(
        (
            (total_kb - available_kb) * 100
        ) / total_kb
    )

    if (( used_percent >= MEM_THRESHOLD )); then
        log "WARN" \
            "Memory ถูกใช้งาน ${used_percent}%"

        EXIT_CODE=1
    else
        log "OK" \
            "Memory ถูกใช้งาน ${used_percent}%"
    fi
}

check_services() {
    local service
    local -a services=()

    # SERVICE_LIST ใช้ช่องว่างคั่นชื่อ Service
    # ตัวอย่าง: "ssh cron nginx"
    IFS=' ' read -r -a services <<< "$SERVICE_LIST"

    for service in "${services[@]}"; do
        [[ -n "$service" ]] || continue

        if systemctl is-active --quiet "$service"; then
            log "OK" \
                "Service $service กำลังทำงาน"
        else
            log "WARN" \
                "Service $service ไม่ได้อยู่ในสถานะ active"

            EXIT_CODE=1
        fi
    done
}

main() {
    # ตรวจสอบ Dependency ก่อนเริ่มทำงาน
    require_command awk
    require_command df
    require_command hostname
    require_command systemctl
    require_command tail
    require_command uname
    require_command uptime

    # ตรวจสอบค่าที่ผู้ใช้กำหนด
    validate_threshold \
        "DISK_THRESHOLD" \
        "$DISK_THRESHOLD"

    validate_threshold \
        "MEM_THRESHOLD" \
        "$MEM_THRESHOLD"

    log "INFO" \
        "เริ่มตรวจสอบเครื่อง $HOST_NAME"

    log "INFO" \
        "Kernel: $(uname -r) | Uptime: $(uptime -p)"

    check_disk
    check_memory
    check_services

    if (( EXIT_CODE == 0 )); then
        log "INFO" \
            "ผลตรวจสอบปกติ"
    else
        log "WARN" \
            "พบรายการที่ต้องตรวจสอบเพิ่มเติม"
    fi

    exit "$EXIT_CODE"
}

main "$@"

trap สามารถใช้กำหนดการทำงานเมื่อเกิด Signal หรือ Error ได้ แต่ ERR trap มีข้อยกเว้นในคำสั่งประเภทเงื่อนไขและ Pipeline เช่นเดียวกับ errexit จึงควรใช้ร่วมกับการตรวจสอบสถานะอย่างชัดเจน


ตรวจสอบ Syntax ก่อน Execute

ใช้ bash -n เพื่อตรวจ Syntax โดยยังไม่เรียกคำสั่งภายใน Script:

# ตรวจสอบ Syntax
bash -n server-healthcheck.sh

ถ้าไม่มีข้อความ Error แสดงว่า Bash สามารถ Parse Script ได้

กำหนดสิทธิ์ Execute:

chmod +x server-healthcheck.sh

เรียกใช้งาน:

./server-healthcheck.sh

ตัวอย่างผลลัพธ์

2026-07-30 22:10:01 [INFO] server-healthcheck.sh: เริ่มตรวจสอบเครื่อง ubuntu-server
2026-07-30 22:10:01 [INFO] server-healthcheck.sh: Kernel: 6.x.x | Uptime: up 2 hours
2026-07-30 22:10:01 [INFO] server-healthcheck.sh: ตรวจสอบพื้นที่ Disk เกณฑ์เตือน 80%
2026-07-30 22:10:01 [OK] server-healthcheck.sh: / ใช้พื้นที่ 24% (/dev/mapper/ubuntu--vg-ubuntu--lv)
2026-07-30 22:10:01 [OK] server-healthcheck.sh: Memory ถูกใช้งาน 31%
2026-07-30 22:10:01 [OK] server-healthcheck.sh: Service ssh กำลังทำงาน
2026-07-30 22:10:01 [OK] server-healthcheck.sh: Service cron กำลังทำงาน
2026-07-30 22:10:01 [INFO] server-healthcheck.sh: ผลตรวจสอบปกติ

ตรวจสอบ Exit Status:

./server-healthcheck.sh

# แสดง Exit Status
echo $?

Script กำหนด Exit Status ดังนี้

0    ระบบอยู่ในเกณฑ์ปกติ
1    พบ Disk, Memory หรือ Service ที่ต้องตรวจสอบ
2    Configuration ไม่ถูกต้องหรือไม่พบคำสั่งที่จำเป็น
อื่น ๆ เกิด Error จากคำสั่งภายใน Script

ปรับ Threshold และรายชื่อ Service

กำหนด Disk Threshold เป็น 70%:

DISK_THRESHOLD=70 ./server-healthcheck.sh

กำหนด Memory Threshold เป็น 75%:

MEM_THRESHOLD=75 ./server-healthcheck.sh

ตรวจสอบ SSH, Cron และ Nginx

SERVICE_LIST="ssh cron nginx" \
./server-healthcheck.sh

กำหนดค่าทั้งหมดพร้อมกัน

DISK_THRESHOLD=80 \
MEM_THRESHOLD=85 \
SERVICE_LIST="ssh cron nginx" \
./server-healthcheck.sh

ทดสอบ Input Validation

DISK_THRESHOLD=abc ./server-healthcheck.sh

ผลลัพธ์ควรเป็น:

[ERROR] server-healthcheck.sh: DISK_THRESHOLD ต้องเป็นจำนวนเต็ม 0-100

ตรวจสอบ Code ด้วย ShellCheck

ShellCheck ช่วยค้นหาปัญหาที่พบบ่อยใน Shell Script เช่น ตัวแปรที่ไม่ได้ Quote, Syntax ที่เสี่ยง และคำสั่งที่ทำงานไม่ตรงตามที่คาดไว้

ติดตั้ง ShellCheck

# อัปเดตรายการ Package
sudo apt update

# ติดตั้ง ShellCheck
sudo apt install -y shellcheck

ตรวจสอบ Script:

shellcheck server-healthcheck.sh

ShellCheck เป็นเครื่องมือวิเคราะห์แบบ Static Analysis จึงไม่สามารถแทนที่การทดสอบ Script ในสภาพแวดล้อมจริงได้ แต่ช่วยลดข้อผิดพลาดพื้นฐานก่อนนำ Script ไป Execute


ติดตั้ง Script ไว้ในระบบ

เมื่อตรวจสอบ Script เรียบร้อยแล้ว สามารถติดตั้งไว้ที่ /usr/local/sbin

# ติดตั้ง Script และกำหนด Permission เป็น 0755
sudo install \
    -o root \
    -g root \
    -m 0755 \
    server-healthcheck.sh \
    /usr/local/sbin/server-healthcheck

ทดสอบเรียกจากตำแหน่งใหม่

sudo /usr/local/sbin/server-healthcheck

ตรวจสอบ Permission

ls -l /usr/local/sbin/server-healthcheck

ควรได้ผลลัพธ์ใกล้เคียง

-rwxr-xr-x 1 root root ... /usr/local/sbin/server-healthcheck

ตั้งเวลาทำงานด้วย Cron

ตรวจสอบว่า Cron ทำงานอยู่

systemctl status cron --no-pager

เปิด Root Crontab

sudo crontab -e

เพิ่มรายการต่อไปนี้

# ตรวจสอบระบบทุก 5 นาที และบันทึกผลลง Log
*/5 * * * * DISK_THRESHOLD=80 MEM_THRESHOLD=85 SERVICE_LIST="ssh cron nginx" /usr/local/sbin/server-healthcheck >> /var/log/server-healthcheck.log 2>&1

ตรวจสอบ Log

sudo tail -f /var/log/server-healthcheck.log

ตรวจสอบรายการ Cron ที่กำหนดไว้

sudo crontab -l

⚠️ คำเตือน:
ก่อนตั้ง Cron ควร Execute Script ด้วยตนเองและตรวจสอบ Exit Status ให้เรียบร้อย การตั้งเวลาสคริปต์ที่ยังไม่ได้ทดสอบอาจสร้าง Log จำนวนมากหรือทำงานผิดพลาดซ้ำ ๆ


แนวทางเขียน Bash Script ให้ปลอดภัย

Quote ตัวแปรเสมอ

rm -- "$TARGET_FILE"

การใส่ -- ช่วยบอกคำสั่งว่า Argument หลังจากนั้นเป็นชื่อไฟล์ ไม่ใช่ Option

ตรวจสอบค่าจากผู้ใช้

อย่านำค่าที่รับจาก Argument หรือ Environment Variable ไปใช้โดยตรงโดยไม่มี Validation

[[ "$PORT" =~ ^[0-9]+$ ]] || {
    echo "PORT ต้องเป็นตัวเลข" >&2
    exit 2
}

หลีกเลี่ยง eval

คำสั่ง eval นำข้อความกลับไปประมวลผลเป็นคำสั่ง Shell อีกครั้ง หากข้อความนั้นมาจากผู้ใช้ อาจนำไปสู่ Command Injection ได้

ไม่เก็บ Password ใน Script

ไม่ควรเขียนข้อมูลต่อไปนี้ลงใน Script โดยตรง

DB_PASSWORD="my-secret-password"
API_TOKEN="secret-token"

ควรใช้ Environment Variable, Secret Manager หรือไฟล์ที่กำหนด Permission อย่างเหมาะสมแทน

หลีกเลี่ยงการใช้ root โดยไม่จำเป็น

ให้ใช้บัญชีผู้ใช้ทั่วไปสำหรับพัฒนาและทดสอบ Script ใช้ sudo เฉพาะคำสั่งที่ต้องใช้สิทธิ์ระดับผู้ดูแลระบบจริง ๆ

สำรองข้อมูลก่อนแก้ Configuration

ก่อนใช้ Script แก้ไขไฟล์ใน /etc ควรสำรองไฟล์เดิม

# สำรองไฟล์พร้อม Timestamp
sudo cp \
    /etc/ssh/sshd_config \
    "/etc/ssh/sshd_config.$(date '+%Y%m%d-%H%M%S').bak"

⚠️ ควรตรวจสอบพื้นที่จัดเก็บและ Permission ของ Backup ทุกครั้ง โดยเฉพาะไฟล์ที่อาจมี Key, Password หรือข้อมูลสำคัญ


สรุป

Bash Scripting เป็นทักษะสำคัญสำหรับ SysAdmin เพราะช่วยเปลี่ยนชุดคำสั่งที่ต้องทำซ้ำให้เป็นกระบวนการอัตโนมัติ ลดความผิดพลาดจากการทำงานด้วยมือ และสามารถนำไปเชื่อมต่อกับ Cron, Systemd Timer หรือ Monitoring System ได้

พื้นฐานสำคัญที่ควรฝึกให้คล่องคือการใช้ตัวแปร การ Quote, Argument, เงื่อนไข, Loop, Function, Exit Status และ Error Handling เมื่อเข้าใจส่วนเหล่านี้แล้ว จะสามารถพัฒนา Script สำหรับ Backup, Log Analysis, User Management, Service Monitoring และ Deployment ได้ต่อไป

สำหรับ Script ที่มีผลต่อ Configuration หรือข้อมูลสำคัญ ควรเริ่มทดสอบบน Virtual Machine หรือ Staging Environment เสมอ และตรวจสอบด้วย bash -n กับ ShellCheck ก่อนนำไปใช้บน Production Server



Write by Dr.Arnut Ruttanatirakul
(c) SysAdmin Knowledge
https://www.sysadmin.in.th
August  5, 2026