barp
barp

Reputation: 6929

expect exception handling for ssh password in bash

VAR=$(expect -c "
     spawn ssh-copy-id -i $SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP    
     expect "*?assword:*"
     send \"$REMOTE_HOST_PASSWD\r\";  
     send -- "\r"
     expect eof
    ")

#echo "$VAR"

Code works in my bash script in a function.I need an exception when the password is wrong. My way is;

VAR=$(expect -c "
     spawn ssh-copy-id -i $SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP    
     expect "*?assword:*"
     send \"$REMOTE_HOST_PASSWD\r\"; 
     expect "Permission denied, please try again."
     send user "Wrong pass"
     exit
     send -- "\r"
     expect eof
    ")

#echo "$VAR"

But it gives the error

couldn't read file "denied,": no such file or directory

I think it is about quotoing.when I change the expect -c " to single quotes expect -c ', this time it gives error that can not find $SSH_KEY_PATH_PUB cause it is a variable in script.SO I think it goes out the scope.what is the solution

EDIT: ok this time it is better to have single quotes and it works.but what it can be done the if clause;

 AR=$(expect -c '
 spawn ssh-copy-id -i '"$SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP"'
 expect "*?assword:*"
 send "'"$REMOTE_HOST_PASSWD"'\r";
 expect "Permission denied, please try again."
 send user "Wrong pass"
 exit
 send -- "\r"
 expect eof

')

this time, if pass is ok it makes job and if pass not correct it does not. but when the pass is correct it writes the "wrong pass" stage. what it can be done so if the pass is correct it must exit and not continue.Sorry I am not familiar with expect and its syntax

Upvotes: 2

Views: 4130

Answers (1)

Austin France
Austin France

Reputation: 2501

You either need to escape your other uses of " characters within the string

AR=$(expect -c "
    spawn ssh-copy-id -i $SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP    
    expect \"*?assword:*\"
    send \"$REMOTE_HOST_PASSWD\r\"; 
    expect \"Permission denied, please try again.\"
    send user \"Wrong pass\"
    exit
    send -- \"\r\"
    expect eof
")

Or you could switch to using single quotes, but you will need to exit the quotes to expand your variables

 AR=$(expect -c '
    spawn ssh-copy-id -i '"$SSH_KEY_PATH_PUB $REMOTE_HOST_USER@$REMOTE_HOST_IP"'
    expect "*?assword:*"
    send "'"$REMOTE_HOST_PASSWD"'\r";
    expect "Permission denied, please try again."
    send user "Wrong pass"
    exit
    send -- "\r"
    expect eof
')

Basically, switching the types of quote used to quote the command within a single command argument. This works because a bash word argument can include a mix of quotes. Simple example

'password='"$password"

and you can combine as many quote switches as you like and as long as there is no space between the two different quotes, it will all be treated as part of the same word or command argument.

Upvotes: 2

Related Questions