I'm Morgan McGuire (@CasualEffects). I've been working on computer graphics and games for 20 years at great places including NVIDIA, University of Waterloo, Williams College, Brown University, Roblox, Unity, and Activision.

See my home page for a full index of my blog posts, books, research, and projects.

Saturday, May 4, 2013

SSH with command-line password on OS X and Linux

Sometimes you have to connect via SSH or SCP to another machine inside of a script.  For example, when I update the codeheart.js website, I do so by running a script that builds the site, examples, and documentation, and then uploads them via SCP with multiple commands. Since the connection is launched by a script, it is inefficient..and annoying...to repeatedly type the password for SSH each time that the script needs it.  There are some common solutions to this problem, which don't happen to work well if your environment is OS X or Linux, or you don't have permission (or inclination) to modify the accounts to which you are connecting, or the accounts that you're connecting to have remotely-hosted file systems. Those common solutions are kerberos authentication forwarding/sshagent, TortoisePlink's windows SSH password option, and editing the known_hosts + authorized_keys files.

My solution is to use the Unix "expect" domain-specific language to trick SSH into communicating with a virtual terminal, and then programming the input that it receives until the connection is established.  The script below runs on OS X and Linux and allows you to supply a password on the command line.  I implemented this script to terminate with an interactive prompt, but you could instead close the connection after the remote command executes.

#!/usr/bin/expect -f
#
# syntax: sshnopassword password host command

set password [lindex $argv 0]
set host     [lindex $argv 1]
set command  [lindex $argv 2]

spawn ssh $host $command
expect {
  # Agree to modify known_hosts if prompted
  "(yes/no)?"   { 
      send -- "yes\r"
      exp_continue 
  }

  # Enter the password
  "*?assword:*" { 
     send -- "$password\r" 
  }
}

interact




Morgan McGuire is a professor of Computer Science at Williams College and a professional game developer. He is the author of The Graphics Codex, an essential reference for computer graphics that runs on iPhone, iPad, and iPod Touch.