Expect in Alias

2019-08-12 17:11发布

问题:

I am using a Bash alias that allows me to shorten the SSH command in order for me to log into my routers. Quite trivial, but a time saver! What I would now like to do is take this a step further and fully automate the logging-in of the routers.

For example in my ~/.bashrc file I have the following entry:

sshFuncB()
{
    ssh -o StrictHostKeyChecking=no superuser@$1 - | /usr/bin/expect<<EOF  
    set timeout 5
    set send_human {.1 .3 1 .05 2}

    expect {
        "password: " { send -h "MYPASSWORD\r" }
        "No route to host" { exit 1 }
        timeout { exit 1 }
    }
    set timeout 2
    sleep 1
    expect { 
        "N]?" { send "y\r"; exp_continue }
        timeout { exit 1 }
    }
    expect eof
EOF
}

alias z=sshFunc

However, when I type z myrouterhostname this does not give the desired output. I must find a way to start the SSH connection and have expect automate logging in before returning control to user.

Any ideas?

回答1:

This can be done as follows,

sshFuncB()
{
    expect -c "
    spawn ssh -o StrictHostKeyChecking=no superuser@$1   
    set timeout 5
    set send_human {.1 .3 1 .05 2}

    expect {
        \"password: \" { send -h \"MYPASSWORD\r\" }
        \"No route to host\" { exit 1 }
        timeout { exit 1 }
    }
    set timeout 2
    sleep 1
    expect { 
        \"N]?\" { send \"y\r\"; exp_continue }
        timeout { exit 1 }
    }
    expect eof
   "
}

alias z=sshFuncB

Note the use of -c flag in expect which you can refer from here of you have any doubts.

If we use double quotes for the expect code with -c flag, it will allow the bash substitutions. If you use single quotes for the same, then bash substitutions won't work. (You have used @1 inside expect, which is why I used double quotes) Since I have used double quotes for the whole expect code, we have to escape the each double quotes with backslash inside the expect statement like as follows,

   expect {
        # Escaping the double quote with backslash
        \"password: \" {some_action_here}
   }

One more update. Since this is about connecting to the router and do some of your manual operations, then it is better to have interact at the end.



标签: bash ssh expect