Transmit commands via ssh with password using expect

399 views Asked by At

I need to iterate on a sequence of servers(many type of servers, each type of servers stored in separate files), run on them some commands(stored in different files accordingly to server type) and log the output on the local machine, using ssh with password. Since sshpass, ssh key authentication is not a solution for my case please don't recommend them.

Here is my code:

#!/usr/local/bin/expect -f
#Set path to nodes files
NODES=nodes/*
#Set path to commands files
CMD=commands/*

for fn in $NODES
do
echo "Working in $fn"
    for fc in $CMD
    do
    echo "Working in $fc"
        if [ ${fn:6:3} = ${fc:9:3} ]
        then
            # read Nodes from file
            while read fn_line; do
                #extracting substrings of user, host, password separated by comma
                IFS=', ' read -a uhp <<< $fn_line
                #establish ssh session to the node
                eval spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no ${uhp[0]}@${uhp[1]}
                echo ${uhp[0]} ${uhp[1]} ${uhp[2]}
                #use correct prompt
                set prompt "assword:*"
                interact -o -nobuffer -re $prompt return
                send "${uhp[2]}\r"
                set prompt ":|#|\\\$"
                interact -o -nobuffer -re $prompt return
                #execute and logging HC commands on the node
                while read fc_line; do
                    #set prompt ":|#|\\\$"
                    #interact -o -nobuffer -re $prompt return
                    echo "$fc_line\r" >> logs/${fn:6:3}.log
                    $fc_line\r >> logs/${fn:6:3}.log
                    #interact -o -nobuffer -re $prompt return
                done < $fc
            done < $fn
        fi
      #cat $f
    done
done

I know in my code the problem is combination of bash and expect interpreter. Please help me to do it only in expect style or show me how can i combine bash with expect. Other problem is the while after establishing of ssh connection, but i think it can be solved by storing it previously in an array and looping through it after establishing of ssh connection.

1

There are 1 answers

0
ppro On

How about writing a small utility in expect which spawns ssh command:

#!/usr/bin/expect
set HOST [lindex $argv 0]
set PORT [lindex $argv 1]
set USER [lindex $argv 2]
set PASSWORD [lindex $argv 3]
set COMMAND [join [lrange $argv 4 end] " "]
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no -p $PORT $USER@$HOST $COMMAND
expect "assword:"
send "$PASSWORD\r"
expect eof
exit

and using it in a Bash script like this:

ssh-util <host> <port> <user> <pass> <command>
e.g.
ssh-util 10.0.0.10 22 root s3cr3t ls -la