Automating Interactive CLIs: Mastering “Demanding” Linux Commands

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

The Nightmare of Interactive CLIs

Writing shell scripts that get stuck waiting for passwords is a nightmare. You want full automation, but the tool stops and waits for a ‘yes/no’ confirmation or a password. Typical examples include the passwd command, ssh (when keys aren’t set up), or legacy software installers from decades ago.

On an Ubuntu 22.04 server (4GB RAM) I manage, I once had to stay up until 2 AM just to type a password for an ancient FTP backup tool. This tool didn’t support passing passwords via parameters. Waiting to type a few characters every night was a massive waste of time. That’s when I turned to expect.

Why Do Standard Methods Fail?

Before using expect, I tried a few shortcuts that didn’t work:

  • Using Pipes (echo "pass" | command): This often fails with sudo or passwd. These security tools read directly from /dev/tty (the terminal) rather than looking at stdin.
  • Using Flags (-y): apt install -y works great. But in reality, many internal scripts or legacy software don’t offer such “generous” flags.

Expect: Playing the Role of the User

Expect isn’t just a trick; it’s a real program. It works based on a conversational script: “I wait for you to say A, and I’ll respond with B.”

After six months of production use, here are my core takeaways:

  • Pros: Handles all types of interaction. Excellent branching logic: exit if “Error” is detected, continue if “Success” appears. Specifically, the autoexpect tool can even write scripts for you.
  • Cons: Tcl (Tool Command Language) syntax feels a bit strange to Bash users. You also face security risks by storing passwords in plain text files.

Installation and Core Commands

On Ubuntu/Debian, installation takes just 3 seconds:

sudo apt update && sudo apt install expect -y

Most expect scripts revolve around these 4 commands:

  1. spawn: Starts the process (e.g., opening an SSH connection).
  2. expect: Waits for a specific keyword to appear on the screen.
  3. send: Inputs data (simulating keystrokes).
  4. interact: Hands control back to the user when needed.

Example 1: Automating Password Changes in a Snap

The passwd command usually requires entering the password twice. The following change_password.exp script handles it cleanly:

#!/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

Tip: Don’t forget the \r at the end of the send string. It’s equivalent to pressing Enter. Without it, the script will hang indefinitely.

Example 2: Bypassing SSH Prompts Without Keys

While SSH Keys are the standard, sometimes you’re forced to log in with a password on old network devices. Here’s how to handle it:

#!/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

Here, I use a branching structure. If the server asks to confirm the fingerprint (yes/no), the script answers ‘yes’ and then continues to wait for the ‘password’ prompt.

Autoexpect Trick: Let the Machine Write the Code

Writing scripts manually is prone to typos. I often use autoexpect to save 80% of the time. Just run:

autoexpect ./your_script.sh

Then, interact with it like a real person. autoexpect will record everything and export it to a script.exp file. You just need to open that file and trim the unnecessary parts.

Security Concerns: Don’t Be Complacent

Storing passwords in files is a major risk. To stay safe, I always follow two golden rules:

  1. Restrict Access: Run chmod 600 script.exp immediately. Only you should have permission to read this file.
  2. Use Environment Variables: Never hardcode passwords. Pass passwords from a secret management system like HashiCorp Vault or encrypted environment variables.

After implementing Expect, my backup jobs are 100% automated, reducing the error rate from typos to zero. If you’re managing “stubborn” systems, Expect is the weapon that will save you from boring night shifts.

Share: