Skip to content

Latest commit

 

History

History
244 lines (194 loc) · 6.68 KB

File metadata and controls

244 lines (194 loc) · 6.68 KB

Expect in Linux - Detailed Notes

1. What is Expect?

Expect is a scripting language used for automating interactive applications such as SSH, FTP, Telnet, passwd, and scp. It is built on top of Tcl (Tool Command Language) and allows users to programmatically send and receive input/output for command-line programs that require user interaction.

Key Features:

  • Automates interactive commands.
  • Handles password prompts securely.
  • Can send user input automatically.
  • Enables scripting of CLI-based applications.

Common Use Cases:

  • Automating SSH logins.
  • Automating FTP/Telnet sessions.
  • Changing passwords programmatically.
  • Installing software that requires user input.
  • Sending commands to interactive programs like passwd.

2. Installing Expect in Linux

Most Linux distributions do not have Expect installed by default. You can install it using the following commands:

📌 Ubuntu/Debian:

sudo apt update && sudo apt install expect -y

📌 CentOS/RHEL/Fedora:

sudo yum install expect -y   # For CentOS 7 or RHEL 7
sudo dnf install expect -y   # For CentOS 8+ or Fedora

📌 Arch Linux:

sudo pacman -S expect

📌 Check Version:

expect -v

3. Basic Expect Script Structure

Expect scripts usually have the following structure:

#!/usr/bin/expect   # Shebang (interpreter declaration)

spawn <command>     # Starts an interactive process
expect <pattern>    # Waits for a specific output from the process
send "<response>\r" # Sends input to the process
interact            # Hands control back to the user (optional)
  • spawn → Starts a new process.
  • expect → Waits for specific output before proceeding.
  • send → Sends user input (e.g., password, command).
  • interact → Gives control back to the user after automation.

4. Example: Automating SSH Login

#!/usr/bin/expect

spawn ssh user@remote_host
expect "password:"
send "your_password\r"
interact

Explanation:

  1. spawn ssh user@remote_host → Starts an SSH session.
  2. expect "password:" → Waits for the password prompt.
  3. send "your_password\r" → Sends the password (with \r to simulate "Enter").
  4. interact → Hands over control to the user after login.

Security Warning: Avoid storing passwords in scripts. Use SSH keys instead.


5. Example: Automating FTP Login

#!/usr/bin/expect

spawn ftp ftp.example.com
expect "Name (ftp.example.com:your_user):"
send "your_user\r"
expect "Password:"
send "your_password\r"
expect "ftp>"
send "ls\r"
expect "ftp>"
send "bye\r"

This script automates logging into an FTP server, listing files, and exiting.


6. Using Expect in a Bash Script

Expect can be embedded inside a Bash script using "here documents" (<<EOF).

📌 Example: Using Expect in a Bash Script

#!/bin/bash

expect <<EOF
spawn ssh user@remote_host
expect "password:"
send "your_password\r"
interact
EOF

This method is useful when integrating Expect automation inside a larger Bash script.


7. Handling Timeouts in Expect

By default, Expect waits indefinitely for input. To avoid this, use the timeout command.

📌 Example: Setting a Timeout (5 seconds)

#!/usr/bin/expect
set timeout 5

spawn ssh user@remote_host
expect "password:" { send "your_password\r" } timeout { puts "Connection timed out"; exit 1 }
interact
  • If the password prompt does not appear within 5 seconds, it exits with an error message.

8. Expect with Multiple Conditions (expect with case)

Expect can handle multiple possible outputs using a case-style structure.

📌 Example: Handling Success or Failure

#!/usr/bin/expect

spawn ssh user@remote_host
expect {
    "password:" { send "your_password\r" }
    "Permission denied" { puts "Access Denied!"; exit 1 }
    timeout { puts "Timed out!"; exit 1 }
}
interact
  • If it sees "password:", it sends the password.
  • If "Permission denied" appears, it exits with an error.
  • If no response appears within the timeout, it exits.

9. Running System Commands with Expect

Expect can automate any interactive Linux command, such as changing a password.

📌 Example: Changing the Root Password

#!/usr/bin/expect

spawn passwd root
expect "New password:"
send "MyNewSecurePassword\r"
expect "Retype new password:"
send "MyNewSecurePassword\r"
expect "password updated successfully"
puts "Password changed successfully!"

This script automatically sets a new password for the root user.


10. Debugging Expect Scripts

Expect provides debugging options to understand script behavior.

📌 Enable Debugging with -d (Verbose Output)

expect -d myscript.exp

📌 Adding Debugging Messages in the Script

#!/usr/bin/expect

log_user 1       # Enables logging
puts "Starting SSH Login"

spawn ssh user@remote_host
expect "password:"
send "your_password\r"

puts "SSH Login Successful"
interact

log_user 1 enables logging; puts prints debugging messages.


11. Expect Alternatives

  • SSH Keys: Secure alternative to automate SSH logins.
  • Ansible: Automates configurations without Expect scripts.
  • Python + Pexpect: Python-based alternative for automating interactive programs.

📌 Example: Automating SSH Login with pexpect in Python

import pexpect

child = pexpect.spawn('ssh user@remote_host')
child.expect('password:')
child.sendline('your_password')
child.interact()

Python’s pexpect works similarly to Expect.


12. Expect vs. Bash

Feature Expect Bash
Handles interactive programs ✅ Yes ❌ No
Automates password inputs ✅ Yes ❌ No
Works with SSH, FTP, passwd ✅ Yes ❌ No
More secure scripting ❌ No ✅ Yes (SSH keys)
Used in system automation ✅ Yes ✅ Yes

Expect is better for automating interactive commands, while Bash is better for general scripting.


13. Final Thoughts

  • Expect is powerful for automating interactive command-line applications.
  • Use SSH keys instead of Expect for secure remote access.
  • Expect is useful for FTP, Telnet, passwd, and testing scripts.
  • Avoid storing passwords in scripts; use environment variables or secrets management.

14. Useful Commands

Command Description
expect -d script.exp Run with debugging output
expect -f script.exp Run an Expect script file
man expect Show Expect manual
which expect Find Expect binary location