Skip to content

Instantly share code, notes, and snippets.

@basinilya
Last active May 18, 2026 10:41
Show Gist options
  • Select an option

  • Save basinilya/da9384ee3f9bbc75c8d8472a2282ac91 to your computer and use it in GitHub Desktop.

Select an option

Save basinilya/da9384ee3f9bbc75c8d8472a2282ac91 to your computer and use it in GitHub Desktop.
Wrapper script for programs that prompt for a password and can't read it from a file/env var, e.g. 7zz
#!/usr/bin/expect -f
set timeout -1
if {$argc < 3} {
send_user "Wrapper script for programs that prompt for a password and can't read it from a file/env var.\n"
send_user "usage: $argv0 PASSWORD_FILE PASSWORD_PROMPT command args...\n"
send_user "Ex: $argv0 ~/7zpass.txt \"Enter password:\" 7zz t encrypted.7z\n"
exit 1
}
# First arg = password file
set password_file [lindex $argv 0]
set password_prompt [lindex $argv 1]
# Remaining args = command to execute
set cmd [lrange $argv 2 end]
# Read password
set fp [open $password_file r]
set password [read $fp]
if {[string index $password end] eq "\n"} {
set password [string range $password 0 end-1]
}
close $fp
spawn {*}$cmd
set child_pid [exp_pid]
trap {
catch {exec kill -STOP $child_pid}
exec kill -STOP [pid]
} SIGTSTP
trap {
exec kill -CONT $child_pid
} SIGCONT
# Challenge
expect {
$password_prompt {
stty -echo < $spawn_out(slave,name)
send_user "\n"
send -- "$password\r"
stty echo < $spawn_out(slave,name)
}
}
# we want to stop both the spawned process and expect itself on ctrl-z
set CTRLZ \032
if { 1 } {
interact {
-reset $CTRLZ {
exec kill -STOP $child_pid
exec kill -STOP [pid]
}
}
} else {
interact
# TODO: let terminal itself generate SIGTSTP for our trap above to handle it
}
catch wait result
exit [lindex $result 3]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment