Use SSH public-key authentication whenever you can. If a VPS still requires a host-key confirmation, password, keyboard-interactive challenge, or another prompt, an Expect script can answer that exchange and then run commands. The reliable design is a finite-timeout script with explicit branches for every expected state—not a script that blindly sends a password and waits forever.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
What Expect does in an SSH login
Expect is a Tcl extension and program for driving interactive applications. Its basic cycle is spawn a process, expect text or regular-expression patterns from that process, and send the response. With SSH, the spawned process is normally the OpenSSH client.
As an Amazon Associate I earn from qualifying purchases.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →That makes Expect useful when the login is genuinely interactive. Typical examples include a first connection that asks whether to trust a host key, a legacy server that asks for a password, or a keyboard-interactive system that presents one or more prompts. It is not the best first choice for a repeatable job when key authentication and a non-interactive SSH command will work; a plain SSH command is simpler to audit and less likely to expose a reusable secret.
Choose the authentication design before writing Tcl
OpenSSH supports public-key, keyboard-interactive, and password authentication. Its normal preference puts public keys ahead of keyboard-interactive and password methods. Decide which exchange you actually need, because the choice determines how much secret material the script handles.
#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
| Design | Best use | Credential exposure | Automation behavior |
|---|---|---|---|
| Public-key-only SSH | Scheduled jobs and deployment tasks | The private key stays on the client; no account password is placed in the script | Usually no Expect is needed; unexpected prompts can fail immediately with -o BatchMode=yes |
| Public key plus Expect | A key handles login but a later command or tool remains interactive | Lower than password automation, provided the key is protected | Expect handles only the remaining prompt cycle |
| Password through Expect | Legacy systems or policies that cannot use keys | Highest risk; the secret must never be committed, logged, or placed in command-line arguments | Expect can answer prompts, but must have timeout and failure branches |
| Keyboard-interactive through Expect | Systems that ask for a one-time response, multiple questions, or a challenge | Depends on the challenge and how the response is obtained | Each prompt needs a deliberate pattern; do not treat every prompt as a password prompt |
For a production VPS, establish key access first. Use Expect only for a prompt that cannot be removed or replaced with a safer non-interactive interface.
Prerequisites on the Linux VPS and client
Install Expect on Ubuntu
On Ubuntu, install the distribution package:
sudo apt update
sudo apt install expect
Ubuntu’s Noble package catalogue lists Expect version 5.45.4-3. The package pulls in Tcl and tcl-expect dependencies. Package names and versions vary on other distributions, so use that distribution’s package manager and verify the installed command with:
expect -v
The script’s shebang must point to the location installed on your machine. Find it with command -v expect; the common path is /usr/bin/expect.
Install the OpenSSH components you need
Ubuntu normally includes the OpenSSH client on a desktop or server installation. If it is absent, install it with:
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
sudo apt install openssh-client
A machine that accepts incoming SSH connections needs the server package:
sudo apt install openssh-server
OpenSSH provides encrypted remote control and file transfer. Confirm that the VPS is reachable, that its SSH port is known, and that the account you will automate can start a shell or run the intended command.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Set up key authentication first
Ubuntu’s SSH-key guidance distinguishes the public key, which is installed on the destination account, from the private key, which must not be shared. A passphrase-protected private key used through an agent is preferable to putting an account password in an Expect file.
- On the client, create a key if you do not already have one. An Ed25519 key is a current OpenSSH choice:
ssh-keygen -t ed25519 -f ~/.ssh/vps_deploy
Set a passphrase when the key will be used by a person or by an agent that can unlock it safely. Protect the private file with normal filesystem permissions and back it up only through an approved secret-management process.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
- Install the public key on the VPS account using an interactive setup session:
ssh-copy-id -i ~/.ssh/vps_deploy.pub [email protected]
If ssh-copy-id is unavailable, add the contents of vps_deploy.pub to the account’s ~/.ssh/authorized_keys on the VPS, preserving one complete key per line.
- Test the key explicitly:
ssh -i ~/.ssh/vps_deploy [email protected] 'uname -a'
Only after a second session succeeds should you consider disabling password authentication in the server’s SSH configuration. Keep an alternate administrative session open and verify a recovery path before reloading the SSH service. The exact policy belongs to the system owner; there is no single setting that is safe for every VPS.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Build the Expect script around states, not delays
A dependable script has five elements:
- A shebang that matches the installed Expect path.
- Variables for the account, host, port, and other non-secret parameters.
- A finite timeout so a dead network or VPS cannot leave the job hanging.
- Patterns for host-key confirmation, authentication prompts, authentication failure, the remote shell prompt,
timeout, andeof. - A distinctive prompt match that cannot be confused with ordinary command output.
Expect patterns are unanchored by default, and -re enables regular expressions. exp_continue returns to the same expect block after a response, which is useful when a connection can present several prompts in sequence. Match the complete text used by the OpenSSH version and authentication system on the target rather than assuming every server prints the same wording.
A robust interactive SSH example
Save the following as vps-login.exp, then replace the account, host, command, and prompt expression for your VPS. The example accepts a first-connect host-key question, obtains a password only if a password prompt appears, waits for a shell prompt, runs one command, and exits with a failure status on timeout, end-of-file, or rejected authentication.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
#!/usr/bin/expect -f
set timeout 20
set user "deploy"
set host "vps.example.com"
set port 22
# Keep this expression specific to the target account’s prompt.
set prompt_re {(^|rn)[^rn]*[#$>] $}
proc read_secret {} {
stty -echo
send_user "SSH password: "
expect_user -re "(.*)n"
stty echo
send_user "n"
return $expect_out(1,string)
}
set password ""
# An environment variable is convenient for a controlled test, but it can
# be visible to processes or job logs. Prefer an approved secret mechanism.
if {[info exists env(SSH_PASSWORD)]} {
set password $env(SSH_PASSWORD)
}
spawn ssh -p $port $user@$host
expect {
-re {Are you sure you want to continue connecting.*} {
# Accept this only when the fingerprint was verified out of band.
send -- "yesr"
exp_continue
}
-re {(?i)password:} {
if {$password eq ""} {
set password [read_secret]
}
send -- "$passwordr"
exp_continue
}
-re {(?i)permission denied} {
puts stderr "SSH authentication was rejected"
exit 1
}
-re $prompt_re {
send -- "uname -ar"
expect {
-re $prompt_re {}
timeout {
puts stderr "The command did not return to the shell prompt"
exit 1
}
eof {
puts stderr "SSH closed while the command was running"
exit 1
}
}
send -- "exitr"
expect eof
}
timeout {
puts stderr "SSH connection timed out"
exit 1
}
eof {
puts stderr "SSH closed before a shell prompt appeared"
exit 1
}
}
Make it executable and run it:
chmod 700 vps-login.exp
./vps-login.exp
The read_secret procedure turns terminal echo off while a person types. Restore echo if an interrupted run leaves the terminal blank with stty echo. For unattended jobs, do not rely on a human prompt: retrieve a secret from an approved runtime mechanism and ensure the job system does not print its environment or Expect’s transcript.
Free tools Windows power users keep installed
One-click scans. No signup required.
Tailor the prompt and command handling
Use a prompt that is distinctive
The sample expression accepts a line ending in $, #, or > followed by a space. That is only a starting point. A command can print the same characters, and a customized shell may use another ending. A safer approach is to arrange a recognizable prompt for the automation account and match that exact marker, then restore or terminate the session when the work is complete.
Do not match a short fragment such as $ anywhere in the stream. It can cause the script to send the next command before the previous command has finished.
Run several commands without losing synchronization
After each send, wait for the prompt that proves the command completed. Quote shell arguments for the remote shell, and avoid building a command by concatenating untrusted input. For a repeatable operation, a single remote command or a server-side script is generally easier to reason about than a long interactive session.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
send -- "systemctl is-active nginxr"
expect {
-re $prompt_re { }
timeout { puts stderr "status check timed out"; exit 1 }
eof { puts stderr "session ended during status check"; exit 1 }
}
Handle keyboard-interactive prompts separately
A keyboard-interactive exchange can contain a username, an OTP, a confirmation, or several questions. Add a pattern for each known prompt and send only the corresponding response. Never answer every line containing a question mark with the same secret. If the challenge is one-time or context-sensitive, design the retrieval and audit process around that challenge rather than storing the response in the script.
Host-key confirmation: convenient but security-sensitive
On a first connection, OpenSSH may ask whether to continue connecting after presenting the server’s host-key fingerprint. The example handles that text with yes, but automatic acceptance is safe only after you have verified the fingerprint through a trusted channel. Otherwise a hostile endpoint could be recorded as the VPS.
For a managed fleet, pre-populate the client’s known-hosts file after verification and let an unexpected key produce an error. Keep host-key changes visible to operators; do not hide them by redirecting all SSH output to a log that nobody reviews.
Make unattended runs fail safely
- Set a finite Expect
timeoutand use SSH’s connection timeout options where appropriate. - Return a non-zero status for
timeout,eof, authentication failure, and a missing command prompt. - Use
-o BatchMode=yesfor key-only jobs when an unexpected prompt should fail instead of waiting. Do not combine it with a workflow that intentionally needs Expect to answer prompts. - Keep private keys readable only by the account that runs the job, and never share a private key with the VPS or another operator.
- Do not place passwords in source control, process arguments, debug output, or copied transcripts.
- Log the host, operation, exit status, and failure category, but redact passwords, private keys, tokens, and sensitive command output.
- Test with a non-production account and a disposable command before granting the script administrative privileges.
If a key-based job is possible, invoke SSH directly with the identity file and an explicit command. This removes the password branch and makes an unexpected prompt a visible failure rather than an opportunity for the script to send the wrong data.
Troubleshoot by the state where the script stops
| Symptom | Likely cause | Fix |
|---|---|---|
| “expect: command not found” | Expect is not installed or is outside PATH |
Install the distribution package and verify with expect -v and command -v expect. |
| The script fails before starting | The shebang points to a different Expect location | Change the first line to the path reported by command -v expect. |
| It times out at the first connection | Network reachability, firewall, wrong port, or a pattern that does not match the host-key question | Run a normal verbose SSH connection, confirm the port, and capture the exact prompt text before changing the regular expression. |
| It sends a password but receives “Permission denied” | Wrong account, wrong secret, disabled password login, or a keyboard-interactive method that uses different prompts | Test the account manually, inspect the server’s allowed authentication methods, and add a branch for the actual challenge instead of repeating the password branch. |
| It logs in but hangs after a command | The prompt expression does not match the shell, or command output contains a misleading fragment | Make the remote prompt distinctive, anchor the expression to a complete line, and wait for that prompt after every command. |
| The terminal stops showing typed characters | The no-echo password read was interrupted before echo was restored | Run stty echo, then fix the error path or use a controlled secret-injection method. |
| The script accepts a changed host key | The host-key branch blindly answered the confirmation | Stop accepting automatically, verify the fingerprint, and maintain a trusted known-hosts entry. |
Testing and maintenance checklist
- Run the equivalent SSH command manually and record the exact host-key, authentication, and shell-prompt text.
- Test a successful login with a harmless command such as
uname -a. - Test a wrong hostname or blocked port and confirm the script exits within the configured timeout.
- Test an invalid account or revoked key and confirm that the exit status is non-zero.
- Test a command that fails and decide whether the remote exit status, output, or both determine success.
- Inspect logs to ensure they contain status and context but no password, private key, token, or unnecessary command output.
- Re-test after changing the shell, OpenSSH package, authentication policy, host key, or account prompt.
- Keep an alternate administrative session open while changing server-side SSH settings.
Learning the language beyond a single login script
The Expect manual is the authoritative reference for pattern matching, timeouts, exp_continue, user input, and terminal control. It identifies Don Libes’s Exploring Expect as the best introduction to the language; that book is useful when a workflow grows beyond a short SSH wrapper. Keep the automation focused: if the remote task can be expressed as a key-authenticated, non-interactive command, removing the prompt is usually a better maintenance improvement than adding another Expect branch.
When Expect is the wrong tool
Do not use Expect to conceal a weak credential policy, to bypass host-key verification, or to automate a workflow whose provider already exposes a non-interactive API. A public-key-only SSH command is normally easier to rotate, monitor, and review. Expect earns its place when an interactive exchange is unavoidable, the prompts are stable enough to match precisely, and the script treats every timeout, authentication error, and unexpected end of session as a failure.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

