Lệnh expect trong linux với các ví dụ dễ hiểu

Lệnh expect trong Linux là một công cụ mạnh mẽ giúp tự động hóa các tương tác với các chương trình khác thông qua dòng lệnh. Nó cho phép bạn viết các script để trả lời các câu hỏi hoặc nhập liệu tự động, thay vì phải làm thủ công. Với expect, bạn có thể dễ dàng tự động hóa các tác vụ lặp đi lặp lại như đăng nhập vào máy chủ hoặc cài đặt phần mềm.

Lệnh expect trong linux là gì?

Lệnh command expect in linux là một công cụ mạnh mẽ giúp tự động hóa các tương tác với các chương trình khác thông qua dòng lệnh. Nó hoạt động bằng cách "mong đợi" (expect) một chuỗi ký tự cụ thể từ chương trình, sau đó gửi một phản hồi được xác định trước. Điều này rất hữu ích cho việc tự động hóa các tác vụ lặp đi lặp lại, chẳng hạn như đăng nhập vào máy chủ từ xa hoặc cấu hình thiết bị mạng. Với expect, bạn có thể viết các script để tự động trả lời các câu hỏi hoặc nhập mật khẩu, giúp tiết kiệm thời gian và công sức. Expect là một giải pháp tuyệt vời để xử lý các tình huống mà tương tác thủ công trở nên tẻ nhạt và dễ mắc lỗi.

Tìm hiểu về lệnh expect và cú pháp cơ bản của nó

Lệnh expect trong Linux cho phép bạn tự động hóa các chương trình dòng lệnh tương tác.

Điều này đặc biệt hữu ích cho các tác vụ như đăng nhập tự động hoặc truyền tệp.

Nó cũng hữu ích trong mọi tình huống mà chương trình yêu cầu nhập liệu từ người dùng.

Cài đặt expect

Đầu tiên, hãy xác minh rằng gói expect đã được cài đặt trên hệ thống của bạn.

Mở terminal của bạn và chạy:

which expect

Nếu expect đã được cài đặt, bạn sẽ thấy đường dẫn của nó (ví dụ: /usr/bin/expect).

Nếu không, bạn cần cài đặt nó:

sudo apt-get update
sudo apt-get install -y expect

Tìm hiểu cú pháp expect cơ bản

Lệnh expect sử dụng một ngôn ngữ kịch bản dựa trên Tcl (Tool Command Language).

Cấu trúc cơ bản của một kịch bản expect bao gồm các lệnh sau:

  1. spawn: Bắt đầu một tiến trình để tương tác.
  2. expect: Chờ đầu ra cụ thể từ tiến trình đã tạo.
  3. send: Gửi đầu vào đến tiến trình đã tạo.
  4. set timeout: Đặt thời gian chờ đầu ra mong đợi.

Hãy tạo một kịch bản expect đơn giản để minh họa các khái niệm này.

Mở một trình soạn thảo văn bản và tạo một tệp có tên hello.exp trong thư mục dự án của bạn:

cd ~/project
nano hello.exp

Nhập nội dung sau vào tệp:

#!/usr/bin/expect -f

## Set a timeout of 10 seconds
set timeout 10

## Spawn the bash process
spawn bash

## Wait for the bash prompt
expect "$ "

## Send a command to the bash process
send "echo Hello from expect\r"

## Wait for the bash prompt again
expect "$ "

## Exit the bash session
send "exit\r"

## Wait for the process to complete
expect eof

Lưu tệp bằng cách nhấn Ctrl+O, sau đó Enter và thoát nano bằng Ctrl+X.

Làm cho kịch bản có thể thực thi:

chmod +x ~/project/hello.exp

Bây giờ chạy kịch bản:

~/project/hello.exp

Bạn sẽ thấy đầu ra tương tự như sau:

spawn bash
$ echo Hello from expect
Hello from expect
$ exit
exit

Giải thích từng dòng của kịch bản

Hãy để tôi giải thích từng dòng trong kịch bản:

  • #!/usr/bin/expect -f: Đây là dòng shebang, cho hệ thống biết sử dụng trình thông dịch expect để chạy kịch bản này.
  • set timeout 10: Đặt thời gian chờ là 10 giây cho bất kỳ lệnh expect nào sau đó.
  • spawn bash: Bắt đầu một tiến trình shell bash mới mà expect sẽ tương tác.
  • expect "$ ": Chờ dấu nhắc bash xuất hiện.
  • send "echo Hello from expect\r": Gửi lệnh đến shell bash. Lưu ý \r ở cuối, mô phỏng việc nhấn Enter.
  • expect "$ ": Chờ dấu nhắc bash một lần nữa, sau khi lệnh đã được thực thi.
  • send "exit\r": Gửi lệnh exit để đóng shell bash.
  • expect eof: Chờ tiến trình đã tạo kết thúc.

Ví dụ đơn giản này minh họa chức năng cốt lõi của expect.

Trong các bước tiếp theo, chúng ta sẽ sử dụng các khái niệm này để tạo các kịch bản thực tế hơn.

Tạo Script Đăng Nhập SSH Giả Lập với Expect

Trong bước này, ta sẽ tạo một script expect mô phỏng quá trình đăng nhập SSH. Vì không thể thực hiện đăng nhập SSH thực tế, ta sẽ tạo script giả lập.

Hiểu Luồng Xác Thực SSH

Khi kết nối đến server từ xa qua SSH, tương tác điển hình bao gồm các bước sau:

  1. Khởi tạo kết nối với lệnh ssh username@hostname.
  2. Chấp nhận host key (nếu kết nối lần đầu).
  3. Nhập mật khẩu khi được yêu cầu.
  4. Truy cập vào shell của server từ xa.

Hãy tạo một môi trường SSH giả lập để minh họa cách expect có thể tự động hóa quy trình này.

Tạo Script Server SSH Giả Lập

Đầu tiên, hãy tạo một script mô phỏng server SSH yêu cầu mật khẩu:

cd ~/project
nano mock_ssh_server.sh

Nhập nội dung sau:

#!/bin/bash

echo "The authenticity of host 'mockserver' can't be established."
echo "RSA key fingerprint is SHA256:abcdefghijklmnopqrstuvwxyz123456."
echo "Are you sure you want to continue connecting (yes/no)? "
read answer

if [ "$answer" != "yes" ]; then
  echo "Host key verification failed."
  exit 1
fi

echo "Warning: Permanently added 'mockserver' (RSA) to the list of known hosts."
echo "Password: "
read -s password

if [ "$password" == "mockpassword" ]; then
  echo "Last login: Wed Nov 1 12:00:00 2023 from 192.168.1.100"
  echo "Welcome to Mock SSH Server"
  echo "mockuser@mockserver:~$ "

  while true; do
    read -p "" command
    if [ "$command" == "exit" ]; then
      echo "Connection to mockserver closed."
      exit 0
    else
      echo "Executing: $command"
      echo "mockuser@mockserver:~$ "
    fi
  done
else
  echo "Permission denied, please try again."
  exit 1
fi

Lưu file và cấp quyền thực thi:

chmod +x ~/project/mock_ssh_server.sh

Script này mô phỏng:

  • Thông báo xác minh host SSH.
  • Yêu cầu nhập mật khẩu.
  • Một shell đơn giản phản hồi các lệnh.

Tạo Script Expect để Tự Động Hóa Đăng Nhập

Bây giờ, hãy tạo một script expect để tự động hóa tương tác với server SSH giả lập:

cd ~/project
nano ssh_login.exp

Nhập nội dung sau:

#!/usr/bin/expect -f

## Set variables
set timeout 10
set password "mockpassword"

## Start the mock SSH server
spawn ./mock_ssh_server.sh

## Handle the host verification prompt
expect "Are you sure you want to continue connecting (yes/no)? "
send "yes\r"

## Handle the password prompt
expect "Password: "
send "$password\r"

## Wait for the shell prompt
expect "mockuser@mockserver:~$ "

## Execute a command
send "ls -la\r"
expect "mockuser@mockserver:~$ "

## Exit the session
send "exit\r"

## Wait for the process to complete
expect eof

puts "\nSSH login automation completed successfully!"

Lưu file và cấp quyền thực thi:

chmod +x ~/project/ssh_login.exp

Chạy Script Đăng Nhập Tự Động

Bây giờ, hãy chạy script expect để tự động hóa tương tác với server SSH giả lập:

cd ~/project
./ssh_login.exp

Bạn sẽ thấy kết quả tương tự như sau:

spawn ./mock_ssh_server.sh
The authenticity of host 'mockserver' can't be established.
RSA key fingerprint is SHA256:abcdefghijklmnopqrstuvwxyz123456.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'mockserver' (RSA) to the list of known hosts.
Password:
Last login: Wed Nov 1 12:00:00 2023 from 192.168.1.100
Welcome to Mock SSH Server
mockuser@mockserver:~$ ls -la
Executing: ls -la
mockuser@mockserver:~$ exit
Connection to mockserver closed.

SSH login automation completed successfully!

Giải Thích Script

Hãy để tôi giải thích từng phần của script expect:

  1. set timeout 10: Đặt timeout toàn cục là 10 giây cho tất cả lệnh expect.
  2. set password "mockpassword": Lưu mật khẩu vào một biến.
  3. spawn ./mock_ssh_server.sh: Khởi động script server SSH giả lập.
  4. expect "Are you sure you want to continue connecting (yes/no)? ": Chờ thông báo xác minh host.
  5. send "yes\r": Gửi "yes" để chấp nhận host key.
  6. expect "Password: ": Chờ yêu cầu nhập mật khẩu.
  7. send "$password\r": Gửi mật khẩu.
  8. expect "mockuser@mockserver:~$ ": Chờ shell prompt.
  9. send "ls -la\r": Gửi lệnh để liệt kê các file.
  10. expect "mockuser@mockserver:~$ ": Chờ shell prompt một lần nữa.
  11. send "exit\r": Gửi lệnh exit để đóng phiên.
  12. expect eof: Chờ quá trình kết thúc.
  13. puts "\nSSH login automation completed successfully!": In thông báo thành công.

Ví dụ này minh họa cách expect có thể được sử dụng để tự động hóa toàn bộ quá trình đăng nhập SSH. Từ chấp nhận host key đến thực thi lệnh và thoát an toàn.

Xử lý Nhiều Dấu Nhắc và Phản Hồi với expect

Trong thực tế, các chương trình tương tác thường có nhiều dấu nhắc và phản hồi khác nhau. Chúng ta sẽ học cách xử lý nhiều dấu nhắc và phản hồi có điều kiện trong script expect.

Hiểu về Khối Điều Kiện Expect

Lệnh expect có thể dùng cấu trúc khối pattern-action để xử lý các dấu nhắc khác nhau:

expect {
    "pattern1" { actions for pattern1 }
    "pattern2" { actions for pattern2 }
    timeout { actions for timeout }
    eof { actions for end of file }
}

Cấu trúc này cho phép script phản hồi khác nhau tùy thuộc vào output nhận được.

Tạo Script Xử Lý Nhiều Dấu Nhắc

Chúng ta sẽ tạo một script mô phỏng chương trình có nhiều dấu nhắc:

cd ~/project
nano multi_prompt.sh

Nhập nội dung sau:

#!/bin/bash

echo "Please select an option:"
echo "1. Show date and time"
echo "2. List files"
echo "3. Show system info"
echo "4. Exit"
echo -n "Enter your choice (1-4): "
read choice

case $choice in
  1)
    echo "Current date and time:"
    date
    ;;
  2)
    echo "File listing:"
    ls -la
    ;;
  3)
    echo "System information:"
    uname -a
    ;;
  4)
    echo "Exiting program..."
    exit 0
    ;;
  *)
    echo "Invalid option. Please enter a number between 1 and 4."
    exit 1
    ;;
esac

echo "Do you want to continue? (yes/no): "
read answer

if [ "$answer" == "yes" ]; then
  echo "Continuing..."
  echo "Operation completed successfully."
else
  echo "Exiting program..."
fi

Lưu file và cấp quyền thực thi:

chmod +x ~/project/multi_prompt.sh

Bây giờ, tạo script expect để tương tác với chương trình và xử lý các dấu nhắc:

cd ~/project
nano handle_prompts.exp

Nhập nội dung sau:

#!/usr/bin/expect -f

## Set a timeout
set timeout 10

## Start the multi-prompt program
spawn ./multi_prompt.sh

## Wait for the choice prompt
expect "Enter your choice (1-4): "

## Generate a random choice (1-3)
set choice [expr {int(rand() * 3) + 1}]
send "$choice\r"

## Process the result based on the choice
switch $choice {
    1 {
        expect "Current date and time:"
        expect "Do you want to continue? (yes/no): "
    }
    2 {
        expect "File listing:"
        expect "Do you want to continue? (yes/no): "
    }
    3 {
        expect "System information:"
        expect "Do you want to continue? (yes/no): "
    }
}

## Handle the continue prompt
expect {
    "Do you want to continue? (yes/no): " {
        ## 70% chance to say yes, 30% chance to say no
        if {rand() < 0.7} {
            send "yes\r"
            expect "Operation completed successfully."
        } else {
            send "no\r"
            expect "Exiting program..."
        }
    }
    timeout {
        puts "Timeout waiting for continue prompt"
        exit 1
    }
}

## Wait for the program to complete
expect eof

puts "\nMulti-prompt handling completed successfully!"

Lưu file và cấp quyền thực thi:

chmod +x ~/project/handle_prompts.exp

Chạy Script Xử Lý Nhiều Dấu Nhắc

Chạy script expect để tương tác với chương trình nhiều dấu nhắc:

cd ~/project
./handle_prompts.exp

Mỗi lần chạy, script sẽ chọn ngẫu nhiên một tùy chọn và quyết định tiếp tục hoặc thoát. Ví dụ:

spawn ./multi_prompt.sh
Please select an option:
1. Show date and time
2. List files
3. Show system info
4. Exit
Enter your choice (1-4): 2
File listing:
total 20
drwxr-xr-x 2 labex labex 4096 Nov  1 10:00 .
drwxr-xr-x 4 labex labex 4096 Nov  1 10:00 ..
-rwxr-xr-x 1 labex labex  345 Nov  1 10:00 handle_prompts.exp
-rwxr-xr-x 1 labex labex  578 Nov  1 10:00 multi_prompt.sh
-rwxr-xr-x 1 labex labex  221 Nov  1 10:00 ssh_login.exp
Do you want to continue? (yes/no): yes
Continuing...
Operation completed successfully.

Multi-prompt handling completed successfully!

Tạo Script expect Nâng Cao Hơn

Chúng ta sẽ tạo một script nâng cao hơn để xử lý các dấu nhắc và lỗi không mong muốn:

cd ~/project
nano advanced_expect.exp

Nhập nội dung sau:

#!/usr/bin/expect -f

## Set a timeout
set timeout 10

## Define variables
set program "./multi_prompt.sh"
set max_retries 3
set retry_count 0

## Define a procedure to handle errors
proc handle_error {} {
    global retry_count max_retries program
    incr retry_count

    if {$retry_count < $max_retries} {
        puts "\nRetrying... Attempt $retry_count of $max_retries"
        ## Start the program again
        spawn $program
        return 1
    } else {
        puts "\nMaximum retry attempts reached. Exiting."
        exit 1
    }
}

## Start the program
spawn $program

## Main interaction loop
while {$retry_count < $max_retries} {
    expect {
        "Enter your choice (1-4): " {
            send "1\r"  ## Always choose option 1 for deterministic behavior
        }
        "Invalid option" {
            puts "\nReceived invalid option message."
            if {[handle_error]} continue
        }
        "Current date and time:" {
            ## Successfully got date output
        }
        "Do you want to continue? (yes/no): " {
            send "yes\r"
        }
        "Operation completed successfully." {
            puts "\nAdvanced expect script completed successfully!"
            break
        }
        timeout {
            puts "\nTimeout occurred waiting for prompt."
            if {[handle_error]} continue
        }
        eof {
            puts "\nUnexpected end of file."
            if {[handle_error]} continue
        }
    }
}

## Wait for the program to complete
expect eof

Lưu file và cấp quyền thực thi:

chmod +x ~/project/advanced_expect.exp

Chạy script nâng cao:

cd ~/project
./advanced_expect.exp

Ví dụ output:

spawn ./multi_prompt.sh
Please select an option:
1. Show date and time
2. List files
3. Show system info
4. Exit
Enter your choice (1-4): 1
Current date and time:
Wed Nov  1 10:00:00 UTC 2023
Do you want to continue? (yes/no): yes
Continuing...
Operation completed successfully.

Advanced expect script completed successfully!

Hiểu về Script Nâng Cao

Script nâng cao này minh họa một số kỹ thuật expect quan trọng:

    Kết luận cho linux expect command

    Vậy là chúng ta đã cùng nhau khám phá sức mạnh của linux expect command! Hy vọng qua bài viết này, bạn đã hiểu rõ hơn về cách tự động hóa các tương tác với terminal. Expect thực sự là một công cụ vô cùng hữu ích, giúp bạn tiết kiệm thời gian và công sức đáng kể. Hãy thử áp dụng linux expect command vào các tác vụ hàng ngày của bạn để thấy rõ hiệu quả. Đừng ngại thử nghiệm và khám phá thêm các tính năng nâng cao của expect nhé. Chúc bạn thành công trên con đường chinh phục tự động hóa với expect! Nếu có bất kỳ câu hỏi nào, đừng ngần ngại tìm kiếm thêm thông tin hoặc tham khảo các ví dụ khác trên mạng. Hãy nhớ rằng, thực hành là chìa khóa để thành thạo bất kỳ công cụ nào, bao gồm cả expect. Chúc bạn có những trải nghiệm thú vị và hiệu quả với expect!

Last Updated : 17/10/2025