Expect in Alias

2019-08-12 16:25发布

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?

标签: bash ssh expect
1条回答
地球回转人心会变
2楼-- · 2019-08-12 17:12

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.

查看更多
登录 后发表回答