Quoting issue with expect script -


i have script automatically connect vpn, because have connect , disconnect several times day. (certain things screenhero , gotomeeting fail on vpn, , mail servers , other things blocked while on vpn, but can't connect git server unless i'm on vpn, , app i'm working on can't reach back-end services unless i'm on vpn, development limited when disconnected.)

the script lessens hassle, have $ in password (which available in environment through environment variable vpn_password1), , password value gets interpolated before passed vpn program expect.

#!/bin/bash  {   /usr/bin/expect << end_of_login_session   set timeout 30   spawn /opt/cisco/anyconnect/bin/vpn -s connect blah.blahblah.com   expect "username:*"   send "\r"   expect "password:*"   send "$vpn_password\r"   expect "accept? \[y/n\]:*"   send "y\r"   expect eof end_of_login_session } 

how pass password literally, without letting subject string interpolation?

changing password cop-out. saving \ cop-out (and horrible ux, since have enter every time source .project file project2).

it seems expect must have solution this.


  1. yes know steals laptop try log in, (a) they'd have account first, , (b) they'd fail without pin, entered phone, anyway.

  2. no, password not saved disk. enter once per shell session related project.

you have shell variable $vpn_password in unquoted heredoc, shell substitute value. suppose vpn_password='foo$bar' => expect see: send "foo$bar\r" , you'll can't read "bar": no such variable. solution use {braces} instead of double quotes, expect not attempt expand "inner" variable.

send {$vpn_password}; send "\r" 

you need separate send "\r" because putting \r inside braces remove special meaning, , tcl won't let send {$vpn_password}"\r"

here's demo:

$ vpn_password='foo$bar' $ expect <<end send_user "$vpn_password\n" end can't read "bar": no such variable     while executing "send_user "foo$bar\n"" $ expect <<end send_user {$vpn_password}; send_user "\n" end foo$bar 

in tcl, braces act single quotes in shell: inside them literal characters.


it might cleaner use environment pass values. here implemented shell function

vpnconnect() {     expect <<'end'         set timeout 30         spawn /opt/cisco/anyconnect/bin/vpn -s connect $env(vpn_host)         expect "username:*"         send "\r"         expect "password:*"         send "$env(vpn_password)\r"         expect {accept? [y/n]:*}         send "y\r"         expect eof end } 

Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo