I am using the following script to handle multiple user inputs with expect:
#!/usr/bin/bash
TEST1="Test text"
TEST2="Hello World"
expect -c '
spawn /home/alexander/read.sh
expect -re "Please enter some input:.*"
send "'"$TEST1"'\r\n"
expect -re "Please enter other input:.*"
send "'"$TEST2"'\r\n"
'
Here is a different version:
#!/usr/bin/bash
TEST1="Test text"
TEST2="Hello World"
expect -c '
spawn /home/alexander/tasks/update/test/Expect/read.sh
expect {
"Please enter some input:" { send "'"$TEST1"'\r" }
exp_continue
}
expect {
"Please enter other input:" { send "'"$TEST2"'\r" }
}
'
The read.sh script looks like follows:
#!/bin/bash
read -p "Please enter some input: " input_variable
echo "You entered: $input_variable"
read -p "Please enter other input: " other_variable
echo "You entered: $other_variable"
When I execute read.sh alone I am asked an input twice, which also is printed to stdout. The expect script, on the other hand, does not seem to handle the second input. The output I get is as follows:
spawn /home/alexander/read.sh
Please enter some input: Test text
You entered: Test text
Please enter other input:
What am I doing wrong, how to fix this?
Remarks:
The script needs to be a bash script with the bash-shebang.
Adding exp_continue in the first script results in an command returned bad code: -101 error.
This works:
#!/bin/bash
TEST1="Test text"
TEST2="Hello World"
expect -c '
spawn /tmp/read.sh
expect {
"Please enter some input:" { send "'"$TEST1"'\r"
exp_continue
}
"Please enter other input:" { send "'"$TEST2"'\r"
exp_continue
}
}'
Related
I have the following expect statement within my bash script:
/usr/bin/expect << EOF
spawn -noecho lucli users add -username user -role admin -email
user#user.com
expect "password:" { send "password\n" }
expect "password:" { send "password\n" }
expect eof
EOF
I want the expect script to validate that the correct output is returned from the CLI command after it passes the passwords and creates the user.
The message I want to validate that gets returned is "added to the system successfully"
I can't figure out how to do that from within the bash script using expect.
Can anyone help?
You could try something like this:
# note the quoted here-doc word
status=$(/usr/bin/expect << 'EOF'
spawn -noecho lucli users add -username user -role admin -email
user#user.com
expect "password:" { send "password\r" }
expect "password:" { send "password\r" }
expect eof
set status [string match "*added to the system successfully*" $expect_out(buffer)]
# $status will be the C-like boolean 0 or 1
exit $status
EOF
)
if [[ $status -eq 1 ]]; then
echo "user added OK"
else
echo "user not added"
fi
ref: https://tcl.tk/man/tcl8.6/TclCmd/string.htm
I am trying to implement an expect script into a bash script. Bear with me since I am fairly new to bash/expect.
Here is the expect script that works as intended:
log_user 0
file delete foo.txt
set fh [open foo.txt a]
set servers {xxx#server1 xxx#server2}
foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}
close $fh
Now, I am hoping to include this expect script in a bash script but it is not working as intended.
Here is what I have so far:
#!/bin/bash
XYZ=$(expect -c "
file delete foo.txt
set fh [open foo.txt a]
set servers {xxx#server1 xxx#server2}
foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}
close $fh
")
echo "$XYZ"
The error I am getting is:
command substitution: line 42: syntax error near unexpected token `('
command substitution: line 42: `expect "$ " { puts $fh "$expect_out(buffer)"}'
I'm open to any other ways to implement this! :)
You can use /usr/bin/expect -c to execute expect commands :
#!/bin/bash
/usr/bin/expect -c '
file delete foo.txt
set fh [open foo.txt a]
set servers {xxx#server1 xxx#server2}
foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep "something" /some/log/file.log"
expect "$ " { puts $fh "$expect_out(buffer)"}
send "exit\r"
}
close $fh
'
Bertrand's answer is one way to solve your question, but does not explain the problem with what you were doing.
Bash attempts to expand variables inside double quoted strings, so your expect script will see blank spaces where you want to see $servers, $s, and $fh. Further, you have triply-nested sets of double-quoted strings going on that will cause all sorts of problems with parsing the arguments to expect.
It's a matter of opinion, but I think when something gets to a certain point where it's considered a program of its own, it should be separated into a separate file.
#!/usr/bin/expect
log_user 0
file delete foo.txt
set fh [open foo.txt a]
set servers {xxx#server1 xxx#server2}
foreach s $servers {
spawn ssh $s
expect "password: "
send "PASSWORD\r"
expect "$ "
send "grep 'something' /some/log/file.log"
expect "$ " {
puts $fh "$expect_out(buffer)"
}
send "exit\r"
}
close $fh
Make sure it's executable, and then call it from your bash script:
#!/bin/bash
/usr/local/bin/my_expect_script
(To do this really properly, you should set up public key authentication and then you can get rid of expect altogether by running ssh server "grep 'something' /some/log/file.log" directly from bash)
I am trying to run expect with negative values. But I'm getting bad flag error.
Test File:
echo "Enter Number:"
read num
echo $num
Expect File:
spawn sh test.sh
expect -- "Enter Number:" {send "-342345"}
I even tried to escape negative values with \ option still it's not working.
You can try this as well
# cat expectscript
#!/usr/bin/expect
spawn sh test.sh
expect "Enter Number:" {send -- "-2394\r"}
expect eof
Try this
$ cat test.sh
echo "Enter number"
read num
echo $num
and
$ cat test.exp
spawn sh test.sh
set value "-342345"
expect "Enter number" {
send -- "$value\r"
}
interact
Run above command as
$ expect test.exp
I have function who is calling expect , but expect is not matching second line, it is matching first match match, I tried all sort of thinks, please help
function login_ssh_user {
logger $FUNCNAME "start"
if [ -z "${LDAPPWD}" ]; then
get_ldap_pwd
fi
echo "\n ${LDAPUSR} \n\n"
echo "\n ${LDAPPWD} \n"
echo "\n ${SOESYS} \n"
export U1="${LDAPUSR}"
export S1="${SOESYS}"
export P1="${LDAPPWD}"
expect << EOF
spawn ssh "$U1#$S1";
expect "password:" { send $P1\r }
expect "$ " { send_user "Login Success ... PASS\n"; send exit\r }
**expect "denied" { send_user "Login Failure ... Fail\n";** send "^C" }
EOF
logger $FUNCNAME "end"
}
Your code indicates you expect to see the password prompt, then you expect to see a shell prompt, then you expect to see Denied. Clearly you will either see the prompt or the denied message:
function login_ssh_user {
#...
export U1="${LDAPUSR}"
export S1="${SOESYS}"
export P1="${LDAPPWD}"
expect << 'EOF'
spawn ssh $env(U1)#$env(S1)
expect "password:" { send $env(P1)\r }
expect {
"$ " { send_user "Login Success ... PASS\n"; send exit\r }
denied" { send_user "Login Failure ... Fail\n"; send \x03 }
}
EOF
logger $FUNCNAME "end"
}
Notes:
I've quoted the EOF in the redirection. That effectively single quotes the whole expect script body
you export your variables, so expect can fetch them out of the env array
both the shell prompt and "denied" are branches in a single expect command. Whichever one expect sees first will "win".
Ctrl+C is \x03
I am new to scripting. How can I write an Expect script to ssh into a device and prompt the user for password? We use a pin + RSA token code as the password so I can't store the password.
#!/usr/bin/expect -f
spawn ssh device1
You will need to use the interact command to type in the password yourself.
The below skeleton should get you on your way:
set prompt "$"
spawn ssh user#host
set timeout 10
expect {
timeout {
puts "Unable to connect"
exit 1
}
#Authenticty Check
"*(yes/no)?" {
send "yes\r"
exp_continue
}
"assword: " {
#Hand control back to user
interact -o "\r" exp_continue
}
"$prompt" {
puts "Cool by the pool"
}
}
I have used this code before to achieve what you wish to achieve. You can take it as a reference point to write your own version of the code.
#!/usr/bin/env expect -f
set passw [lindex $argv 0]
#timeout is a predefined variable in expect which by default is set to 10 sec
set timeout 60
spawn ssh $user#machine
while {1} {
expect {
eof {break}
"The authenticity of host" {send "yes\r"}
"password:" {send "$password\r"}
"*\]" {send "exit\r"}
}
}
wait
#spawn_id is another default variable in expect.
#It is good practice to close spawn_id handle created by spawn command
close $spawn_id
Source: Expect Wiki
The below code will ask the user to enter the password and will use it further in the script where a password will be asked. Just as $pass.
Grabbing password to be used in script further
stty -echo
send_user -- "Enter the password: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)