Tự động hóa Interactive CLI: Tuyệt chiêu xử lý các câu lệnh ‘đòi hỏi’ trên Linux

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Nỗi ám ảnh mang tên Interactive CLI

Viết shell script mà gặp mấy lệnh cứ đòi nhập mật khẩu giữa chừng thì đúng là cực hình. Bạn muốn tự động hóa hoàn toàn, nhưng công cụ lại dừng lại chờ xác nhận ‘yes/no’ hoặc password. Điển hình nhất là lệnh passwd, ssh (khi chưa có key), hay mấy trình cài đặt phần mềm từ thập kỷ trước.

Trên con server Ubuntu 22.04 (4GB RAM) mình quản lý, mình từng phải ‘canh’ lúc 2h sáng chỉ để gõ pass cho một tool backup FTP cổ lỗ sĩ. Tool này không hỗ trợ truyền pass qua tham số. Việc ngồi chờ để gõ vài ký tự mỗi đêm là một sự lãng phí thời gian khủng khiếp. Đó là lúc mình tìm đến expect.

Tại sao các cách thông thường lại thất bại?

Trước khi dùng expect, mình đã thử vài đường tắt nhưng không ăn thua:

  • Dùng Pipe (echo "pass" | command): Cách này thường thất bại với sudo hoặc passwd. Lý do là các công cụ bảo mật này đọc trực tiếp từ /dev/tty (thiết bị đầu cuối) chứ không thèm ngó ngàng đến stdin.
  • Dùng Flag (-y): apt install -y thì quá ổn. Nhưng thực tế, rất nhiều script nội bộ hoặc phần mềm legacy không hề có các flag ‘hào phóng’ như vậy.

Expect: Người đóng vai người dùng

Expect không phải là một thủ thuật, nó là một chương trình thực thụ. Nó hoạt động theo kịch bản hội thoại: “Tôi đợi bạn nói A, tôi sẽ đáp lại B”.

Sau nửa năm đưa vào vận hành thực tế, mình rút ra được vài điểm cốt lõi:

  • Điểm cộng: Xử lý được mọi loại tương tác. Khả năng rẽ nhánh cực tốt: nếu thấy ‘Error’ thì thoát, thấy ‘Success’ thì làm tiếp. Đặc biệt, tool autoexpect có thể tự viết script hộ bạn.
  • Điểm trừ: Cú pháp Tcl (Tool Command Language) hơi lạ lẫm với dân chuyên Bash. Bạn cũng phải đối mặt với rủi ro bảo mật khi lưu mật khẩu dạng plain text trong file.

Cài đặt và các lệnh ‘xương sống’

Trên Ubuntu/Debian, bạn chỉ mất 3 giây để cài đặt:

sudo apt update && sudo apt install expect -y

Mọi kịch bản expect hầu như chỉ xoay quanh 4 lệnh này:

  1. spawn: Kích hoạt tiến trình (ví dụ: mở kết nối SSH).
  2. expect: Nằm chờ một từ khóa cụ thể xuất hiện trên màn hình.
  3. send: Đẩy dữ liệu vào (như cách bạn gõ phím).
  4. interact: Trả quyền điều khiển lại cho bạn khi cần.

Ví dụ 1: Tự động đổi mật khẩu trong 1 nốt nhạc

Lệnh passwd thường bắt nhập mật khẩu hai lần. Script change_password.exp dưới đây sẽ xử lý gọn:

#!/usr/bin/expect -f

set user [lindex $argv 0]
set password [lindex $argv 1]

spawn passwd $user
expect "Enter new UNIX password:"
send "$password\r"
expect "Retype new UNIX password:"
send "$password\r"
expect "password updated successfully"
expect eof

Mẹo: Đừng quên \r ở cuối chuỗi send. Nó tương đương với việc bạn nhấn phím Enter. Thiếu nó, script sẽ treo vô thời hạn.

Ví dụ 2: SSH ‘vượt rào’ khi không có Key

Dù SSH Key là tiêu chuẩn, nhưng đôi khi bạn buộc phải login bằng pass vào các thiết bị mạng cũ. Đây là cách xử lý:

#!/usr/bin/expect -f

set timeout 10
spawn ssh [email protected]

expect {
    "yes/no" {
        send "yes\r"
        exp_continue
    }
    "password:" {
        send "Secret123\r"
    }
}

expect "$"
send "uptime\r"
send "exit\r"
expect eof

Ở đây, mình dùng cấu trúc rẽ nhánh. Nếu server hỏi xác nhận fingerprint (yes/no), script sẽ trả lời ‘yes’ rồi đợi tiếp đến khi thấy dòng ‘password’.

Tuyệt chiêu Autoexpect: Để máy tự viết code

Viết script thủ công rất dễ sai chính tả. Mình thường dùng autoexpect để tiết kiệm 80% thời gian. Bạn chỉ cần chạy:

autoexpect ./your_script.sh

Sau đó, bạn cứ thao tác như người thật. autoexpect sẽ ghi lại mọi thứ và xuất ra file script.exp. Bạn chỉ việc mở file đó ra, xóa bớt những đoạn thừa thãi là xong.

Vấn đề bảo mật: Đừng chủ quan

Lưu mật khẩu trong file là một rủi ro lớn. Để an toàn hơn, mình luôn áp dụng hai quy tắc thép:

  1. Siết quyền truy cập: Chạy chmod 600 script.exp ngay lập tức. Chỉ bạn mới có quyền đọc file này.
  2. Dùng biến môi trường: Không bao giờ hardcode mật khẩu. Hãy truyền mật khẩu từ một hệ thống quản lý secret như HashiCorp Vault hoặc biến môi trường đã được mã hóa.

Sau khi áp dụng Expect, công việc backup của mình đã tự động 100%, giảm tỷ lệ lỗi do gõ sai xuống bằng 0. Nếu bạn đang quản lý những hệ thống ‘khó bảo’, Expect chính là vũ khí giải cứu bạn khỏi những đêm trực nhàm chán.

Share: