Complete Guide to Automating SSH Login with Expect in Bash Scripts

Nov 17, 2025 · Programming · 12 views · 7.8

Keywords: Expect | SSH automation | Bash scripting | Password handling | Interactive sessions

Abstract: This article provides an in-depth exploration of integrating Expect tool within Bash scripts to automate SSH password input. By analyzing common scripting errors, it offers multiple effective solutions including pure Expect implementation, Bash-Expect hybrid programming, and sshpass alternatives. The content thoroughly explains the critical role of interact command, password prompt matching patterns, security considerations, and provides complete code examples with best practices for building reliable SSH automation scripts.

Problem Background and Challenges

In automated operations and system management scenarios, there is often a need to connect to remote servers via SSH to execute commands. However, traditional Bash scripts encounter difficulties when dealing with interactive password input. The Expect tool is specifically designed to handle such interactive sessions, but proper integration with Bash scripts requires special attention.

Analysis of Original Script Issues

The user's initial script successfully sends the password but fails to maintain the SSH session. The key issue is the absence of the interact command, which allows user interaction with the spawned process. When the Expect script completes execution, the SSH subprocess also terminates, causing immediate return to the Bash prompt.

#!/bin/bash
read -s PWD

/usr/bin/expect <<EOD
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com
expect "password"
send "$PWD\n"
EOD
echo "you're out"

Optimal Solution: Pure Expect Implementation

Based on the highest-rated answer, using pure Expect scripts to handle SSH connections is recommended. This approach avoids the complexity of Bash-Expect hybrid programming and provides better stability and control.

#!/usr/bin/expect

# Set timeout to prevent indefinite waiting
set timeout 30

# Get command line arguments
set host [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]

# Launch SSH connection
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $user@$host

# Handle various possible password prompts
expect {
    "password:" {
        send -- "$password\r"
        exp_continue
    }
    "Password:" {
        send -- "$password\r"
        exp_continue
    }
    "yes/no?" {
        send "yes\r"
        exp_continue
    }
    "y/n?" {
        send "y\r"
        exp_continue
    }
    "#" {
        # Successful login, enter interactive mode
        interact
    }
    "$ " {
        # Successful login, enter interactive mode
        interact
    }
}

Bash-Expect Hybrid Programming Approach

If Expect must be integrated within a Bash script, the following improved version can be used. The key is adding the interact command after sending the password to ensure user interaction with the SSH session.

#!/bin/bash

# Securely read password
read -s -p "Enter SSH password: " PWD

/usr/bin/expect <<EOD
set timeout 30
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com

# Use more flexible matching patterns
expect {
    "password:" {
        send -- "$PWD\r"
        exp_continue
    }
    "Password:" {
        send -- "$PWD\r"
        exp_continue
    }
    "yes/no?" {
        send "yes\r"
        exp_continue
    }
}

# Wait for successful login prompt
expect {
    "#" {
        interact
    }
    "$ " {
        interact
    }
}
EOD

echo "SSH session ended"

Alternative Approach: Using sshpass

For simple password automation needs, sshpass provides a more lightweight solution. While less secure, it simplifies script writing in controlled environments.

#!/bin/bash

read -s -p "Enter SSH password: " PWD

# Use sshpass to directly provide password
sshpass -p$PWD ssh -oStrictHostKeyChecking=no -oCheckHostIP=no usr@$myhost.example.com

echo "SSH session ended"

Core Concepts Explained

Role of interact Command

The interact command is one of the most critical commands in Expect, transferring control to the user for direct interaction with the spawned process. When the user exits the SSH session, control returns to the Expect script, which then exits normally.

Password Prompt Matching Strategy

Different SSH servers may use varying password prompt texts. Common variants include:

Using Expect's multi-pattern matching handles these variants:

expect {
    "password:" {
        send -- "$password\r"
        exp_continue
    }
    "Password:" {
        send -- "$password\r"
        exp_continue
    }
    "*password:" {
        send -- "$password\r"
        exp_continue
    }
}

Security Considerations

Special attention to security is required when handling passwords in automation scripts:

Advanced Application Scenarios

Handling Host Key Verification

When connecting to a new host for the first time, SSH asks about accepting the host key. This can be automated in Expect scripts:

expect {
    "Are you sure you want to continue connecting (yes/no)?" {
        send "yes\r"
        exp_continue
    }
    "password:" {
        send -- "$password\r";
        exp_continue
    }
}

Executing Remote Commands and Returning

If only specific commands need execution on the remote server rather than entering an interactive session, implement as follows:

#!/usr/bin/expect

set timeout 30
set host [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set command [lindex $argv 3]

spawn ssh -oStrictHostKeyChecking=no $user@$host $command

expect {
    "password:" {
        send -- "$password\r"
    }
    "Password:" {
        send -- "$password\r"
    }
}

# Wait for command execution to complete
expect eof

Error Handling and Debugging

When developing Expect scripts, enabling debug output helps diagnose issues:

#!/usr/bin/expect

# Enable debug mode
exp_internal 1

# Or redirect Expect output to file
log_file expect_debug.log

# Script content...

Performance Optimization Recommendations

Conclusion

Through proper use of the Expect tool, automated SSH password handling can be effectively implemented within Bash scripts. The key lies in understanding the role of the interact command, correctly handling various password prompt variants, and following security best practices. While SSH key authentication is a more secure choice, password-based automation remains a necessary solution in certain specific scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.