Kỹ Thuật Xử Lý Shell Linux Nâng Cao: Tham Số, Dữ Liệu Và Quản Trị Hệ Thống

Tùy Biến Tham Số Shell

Một trong những sức mạnh lớn nhất của bash nằm ở khả năng thao tác với chuỗi và biến thông qua các cú pháp mở rộng tham số. Dưới đây là các trường hợp sử dụng phổ biến.

Hình thức ${parameter:+expression} thực hiện việc kiểm tra nếu parameter tồn tại và không phải là rỗng, hệ thống sẽ trả về giá trị của expression.

#!/bin/bash
# Ví dụ thay thế ký tự trong biến
filename="backup/data_report%202023.txt"
# Thay thế tất cả ký tự '%' bằng ký tự '_'
clean_name="${filename/%/_}" 
echo "$clean_name"

Các toán tử như %# hoạt động dựa trên cơ chế khớp mẫu theo quy tắc không tham lam (non-greedy) hoặc tham lam (greedy).

  • Mô tả ngắn gọn: ${VAR%pattern} xóa phần phù hợp với pattern từ phía bên phải của biến VAR và giữ lại phần còn lại.
  • Gấp đôi (%): ${VAR%%pattern} loại bỏ chuỗi dài nhất khớp với pattern tính từ phía sau về trước.
  • Tương tự cho #: ${VAR#pattern} xóa từ bên trái sang phải theo mô hình không tham lam, trong khi ${VAR##pattern} tìm kiếm tối đa từ trái sang phải.
path="/usr/local/lib/module.so"
# Lấy tên file gốc, bỏ phần đường dẫn
basename_file="${path##*/}"
# Lấy phần đuôi file
extension="${path##*.}"
echo "Tên: $basename_file, Phần mở rộng: $extension"

Để trích xuất một đoạn con hoặc độ dài biến, bạn có thể sử dụng chỉ số:

text="Hello World"
# Cắt từ ký tự thứ 2 đến 4 ký tự (bắt đầu từ index 1, độ dài 5)
sub_text="${text:1:5}"
# Độ dài tổng cộng của chuỗi
len=${#text}
echo "Chuỗi con: $sub_text, Tổng chiều dài: $len"

Quản Lý Người Dùng Và Nhóm

Các công cụ dòng lệnh dưới đây hỗ trợ admin trong việc cấu hình tài khoản hệ thống.

# Thêm người dùng 'devuser' vào nhóm 'developers'
usermod -aG developers devuser

# Xóa thành viên khỏi nhóm
gpasswd -d devuser developers

# Thay đổi shell mặc định cho tài khoản
chsh -s /bin/bash devuser

# Thiết lập ngày hết hạn cho tài khoản (format: YYYY-MM-DD)
chage -E 2024-12-31 devuser

# Xem thông tin hạn sử dụng tài khoản
chage -l devuser

# Khóa và mở khóa tài khoản
usermod -L devuser # Khóa
usermod -U devuser # Mở khóa

Toán Học Với BC

Đối với các phép tính số học phức tạp hơn integer, utility bc là lựa chọn tiêu chuẩn.

# Chuyển đổi hệ cơ số (từ thập phân sang nhị phân)
number=100
echo "obase=2; $number" | bc

# Chuyển ngược lại (nhị phân sang thập phân)
echo "obase=10; ibase=2; 1100100" | bc

# Tính toán số thập phân với độ chính xác được định nghĩa (scale)
echo "scale=4; 22/7" | bc

# Căn bậc hai và luỹ thừa
echo "sqrt(144)" | bc
echo "2^10" | bc

Định Danh Tập Tin Tùy Chỉnh

Command exec cho phép tạo các file descriptor mới để quản lý luồng dữ liệu độc lập, hữu ích trong việc đọc/ghi song song hoặc xử lý log.

# Khởi tạo file descriptor số 3 để đọc tập tin input_data
exec 3<input_data.txt

# Gửi dữ liệu ra màn hình
cat <&3 

# Khởi tạo file descriptor số 4 để ghi đè (truncation mode)
exec 4>>output_log.txt
echo "Starting process..." >&4

# Đóng file descriptor khi hoàn tất
exec 3<&-
exec 4>&-

Mảng Và Mảng Liên Kết

Bash hỗ trợ cả mảng tuần tự (dùng index số) và mảng liên kết (associative array, dùng key string).

# Định nghĩa mảng thường
numbers=(10 20 30 40)
echo "Giá trị tại index 1: ${numbers[1]}"
echo "Toàn bộ nội dung: ${numbers[@]}"
echo "Số lượng phần tử: ${#numbers[@]}"

# Định nghĩa mảng liên kết (cần declare -A)
declare -A user_info
user_info["admin"]="Alice"
user_info["guest"]="Bob"

# Truy cập và lặp qua mảng liên kết
echo "${user_info[admin]}"
for key in "${!user_info[@]}"; do
  echo "Key: $key, Value: ${user_info[$key]}"
done

Lưu ý Về Alias Và Test Điều Kiện

Khi cần thực thi lệnh gốc mà không bị alias ảnh hưởng, hãy thêm dấu \ trước tên lệnh hoặc sử dụng đường dẫn tuyệt đối. Ngoài ra, các test điều kiện giúp script đưa ra quyết định dựa trên trạng thái filesystem.

# Kiểm tra tính hợp lệ của file/directory
if [ -f "$filepath" ]; then
    echo "File tồn tại"
fi

if [ -d "$dirpath" ]; then
    echo "Là thư mục"
fi

if [ -r "$filepath" ]; then
    echo "Có quyền đọc"
fi

Các tệp cấu hình shell kích hoạt khi login phụ thuộc vào kiểu tương tác:

  • Login Interactive: Đọc /etc/profile, ~/.bash_profile, hoặc ~/.profile.
  • Non-login Interactive: Đọc /etc/bashrc~/.bashrc.

Hướng Dẫn Tìm Kiếm Với Find

Công cụ find cực kỳ linh hoạt, hỗ trợ các toán tử logic và giới hạn độ sâu đệ quy.

# Tìm file .log nhưng loại trừ thư mục cache
find /var/www -type f -name "*.log" -prune -o -print

# Giới hạn tìm kiếm ở độ sâu tối đa 3 cấp
find /home -maxdepth 3 -name "*.txt"

# Tìm file truy cập trong vòng 7 phút qua
find . -amin -7

Biến đặc biệt trong find bao gồm:

  • -atime n: Thời gian truy cập gần đây nhất.
  • -mtime n: Thời gian sửa đổi nội dung gần đây nhất.
  • -ctime n: Thời gian sửa đổi metadata (permission/ownership) gần đây nhất.

Thao Tác Với Văn Bản (Xargs, Split, Csplit)

xargs dùng để chuyển đầu vào thành đối số dòng lệnh. Cú pháp -I rất hữu ích để thay thế vị trí placeholder.

# Tìm file mã nguồn và đếm dòng chứa từ main
find . -name "*.c" | xargs -I {} sh -c "echo 'File: {}; grep -n main {}'"

Chia nhỏ file lớn (Split) sử dụng dd tạo dữ liệu giả lập, rồi dùng split.

# Tạo file thử nghiệm 1MB
dd if=/dev/zero of=testdata bs=1M count=1

# Chia thành nhiều file nhỏ
split -b 100k testdata part_

# Nối lại các phần file
cat part_* > merged_testdata

csplit chia file dựa trên mẫu regex hoặc vị trí dòng. Ví dụ tách log theo máy chủ:

csplit server.log '/SERVER/' {*} -z -f "server_"

Sử Dụng Diff Và Patch

So sánh sự khác biệt giữa các phiên bản và áp dụng bản vá.

# Tạo diff dạng unified
diff -u config.old config.new > backup.patch

# Áp dụng patch
patch -p1 < backup.patch

# Đảo ngược thay đổi (nếu đã áp dụng nhầm)
patch -R -p1 < backup.patch

Để tìm giao điểm giữa hai danh sách file đã sắp xếp, dùng comm.

# Chỉ hiển thị dòng giống nhau (loại bỏ cột 1 và 2)
comm listA listB -1 -2

Xử Lý Dòng (Cut, Sed, Awk)

Cut: Trích xuất trường theo cột hoặc byte.

cut -d':' -f1 /etc/passwd

Sed: Thay thế văn bản nâng cao. Sử dụng & để giữ nguyên chuỗi khớp ban đầu trong kết quả thay thế.

# Thêm dấu ngoặc vuông quanh mỗi từ
echo "hello world" | sed 's/\w*/[\&]/g'

Awk: Ngôn ngữ xử lý văn bản mạnh mẽ.

#!/bin/bash
# Đếm số dòng chứa từ "error" trong logs
awk 'BEGIN { count=0 } /error/ { count++ } END { print "Total errors: " count }' /var/log/syslog

Biến hệ thống trong awk:

  • NR: Số dòng hiện tại.
  • $NF: Trường cuối cùng của dòng.
  • FS: Ký tự phân cách trường (mặc định là khoảng trắng).

Truyền biến môi trường vào awk qua tùy chọn -v:

limit=10
awk -v max="$limit" '{ if ($1 <= max) print }' data.txt

Quyền Hạn Đặc Biệt

Có các bit đặc biệt như Sticky Bit (t) ngăn chặn xóa file bởi người dùng khác trong thư mục chung (ví dụ /tmp). Setuid (s) cho phép chạy chương trình với quyền của chủ sở hữu.

# Đặt sticky bit
chmod +t /shared_folder

# Thiết lập setuid cho binary
chmod u+s /usr/bin/passwd

Chống biến đổi file vĩnh viễn bằng chattr:

# Ghi bất biến (immutable)
chattr +i important_config.conf

# Cho phép chỉ thêm dữ liệu (append-only)
chattr +a app_log.txt

Giám Sát Tài Nguyên

Để debug hiệu năng hệ thống, tổ hợp các công cụ sau là bắt buộc:

Tài NguyênDụng Cụ
CPUtop, htop, mpstat, pidstat -u
I/Oiostat, iotop, dstat --top-bio
Mạngss, netstat, nload, iptraf
Tracestrace (syscall), ltrace (library calls)

Ví dụ theo dõi quá trình tiêu tốn CPU cao nhất bằng dstat:

dstat --top-cpu -n 1 --top-mem

Log Rotate

Cấu hình /etc/logrotate.d/custom giúp tự động cắt và nén log files.

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        /usr/bin/systemctl reload myapp.service
    endscript
}

Điều Hướng Thư Mục Linh Hoạt

Thay vì liên tục dùng cd, hãy dùng stack của pushdpopd để quay lui nhanh chóng.

pushd /project/src
# Đang làm việc tại /project/src
popd
# Quay trở lại thư mục trước đó

Thẻ: Bash shell-scripting linux-administration DevOps System-Tools

Đăng vào ngày 2 tháng 7 lúc 04:16