Exit status code for Expect script called from Bash

I created a Bash script that uses a script to automate ssh logins. The script connects to multiple servers and runs some commands. The bash script asks for login credentials once.

I want to include a feature where the script terminates if login fails for the first server, to avoid checking the script for the following servers, resulting in the user account being locked out. Account lockout occurs for 3 consecutive failed login attempts and the number of servers the script is trying to connect to is over 3.

This is a snippet in a Bash script that invokes the wait script.

countu=0
for servername in $(cat $linux_host_list)
do
./script.expect $LUSERNAME $LPASS $servername Linux >> linux_log_file.txt & < /dev/null
let countl=countl+1
done

      

and here is the wait for the script ( script.expect

) fragment

#!/usr/bin/expect -f
set timeout 30
set username [lindex $argv 0]
set SPASS [lindex $argv 1]
set servername [lindex $argv 2]
set case [lindex $argv 3]
set prompt "(%|#|\\$|%\]) $"
switch $case {
    Linux {
        log_user 0
        spawn ssh -o StrictHostKeyChecking=no $username@$servername
        expect  {
            "assword:" {
                send "$SPASS\r"
                expect -re "$prompt"
            }
            expect -re "$prompt"
        }
        send "sudo su -\r"
        expect {
            "assword:" { send "$SPASS\r" }
        }
        expect -re "$prompt"
        log_user 1
        send "opcagt -status ; opctemplate -l ; cat watch.cf 2> /dev/null\r"
        expect -re "$prompt"
        log_user 0
        send "exit\r"
        expect -re "$prompt"
        log_user 1
    }

      

I tried capturing the output of the Bash ( $?

) command , assuming the Bash command would return nonzero if login fails for an invalid password while waiting for the script, but that didn't work. Any suggestions would be much appreciated.

+2


source to share


5 answers


For error checking pending script there is a decent example at http://systeminetwork.com/article/handle-errors-expect-scripts

What you should do is something like this:

proc do_exit {msg} {
    puts stderr $msg
    exit 1
}

switch -exact -- $case {
    Linux {
        spawn ssh ...
        expect {
            -re {assword: $} {
                send -- "$SPASS\r"
                exp_continue 
                # remain in this expect block and look for the next matching pattern
            }
            "some message about incorrect password" {
                do_exit "incorrect password"
            }
            timeout {do_exit "timed out waiting for prompt"}
            default {do_exit "something else happened"}
            -re $prompt
        }
        # ... rest of your script
    }
}

      



I assume you don't need to know about the exit status of the "opcagt ..." command (you just want to see the contents of the watch.cf file. If you don't care, you need the shell to tell you:

send -- "opcagt -status 2>&1 || echo "non-zero return from opcagt: $?"
expect {
    "non-zero return" { handle error and exit? }
    -re $prompt
}
# ... continue

      

+2


source


You should take a serious look at Fabric .



+1


source


Section:

    expect  {
        "assword:" {
            send "$SPASS\r"
            expect -re "$prompt"
        }
        expect -re "$prompt"
    }

      

Looks very suspicious to me. In particular, I really expected this to lead to confusion. A more idiomatic way of writing:

    expect  {
        "assword:" {
            send "$SPASS\r"
            exp_continue
        }
        -re "$prompt"
    }

      

+1


source


I am not very scripting and everything so I cannot write the exact steps or script to prove what I meant - kindly sorry

Well, I read that bash provides for a thing called exit status

The exit status is state 0 for true and 1 or whatever for false

You can see this by running the command and then checking its exit status by typing "echo $?"

What I suggest, when you try to ssh to one server and authentication fails, there should be an exit status due to something other than 0

Getting an if-then-else loop here and checking the status for 0 to execute the script and any other value to complete the script termination with a suitable error message

0


source


You run the wait scripts in the background ( &

), so you can't get the results of the first before continuing.

As your wait script is written, it will get a 30 second timeout on the second password prompt if the first password fails. Instead, you can make an alternative expect

to see if you have another prompt assword

and exit immediately.

Then change your shell script to not put the wait calls in the background, instead grab the output with $?

and test it.

0


source







All Articles