Expect not accepting negative values - expect

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

Related

expect exiting after expect{send} statement

when I run this script that I wrote to help installing AUR packages:
enter #!/bin/bash
#bash
function GO() {
pack="$1"
cower -ddf $pack
cd "/home/$USER/applications/$pack"
expect -c " set timeout -1
eval spawn makepkg -Ascfi --noconfirm
expect -nocase \"password for $USER:\" {send \"$pass\r\"}
interact;"
cd "../"
}
package="$1"
echo "I need your password for this, can I have it please?"
read -s pass
cd "/home/$USER/applications"
if [ "$package" == "update" ]
then
file="/home/$USER/applications/update.pkgs"
cower -u > file
while IFS= read -r line
do
package=$(echo $line | cut -d " " -f2)
GO $package
done <"$file"
else
GO $package
fi
echo "have a good day."
exit 0
sometimes interact just stoppes after it enters the password and it just echos "have a good day." and exits. am I doing something wrong? timeout is < 0, I have interact aftet the expect statement, anything I am missing?
The only thing I can see is that the password might have a quote in it. You might want to do this:
env _user="$USER" _pass="$pass" expect <<'END'
set timeout -1
spawn makepkg -Ascfi --noconfirm
expect -nocase "password for $env(_user):" {
send -- $env(_pass)
send "\r"
}
interact
END
No need to eval spawn here.
Using the quoted heredoc makes the code easier to read too.

bash read does not wait for input

I have this code:
#!/bin/bash
for some_host in $(cat some_list); do
echo $some_host
ssh $some_host sudo cat /etc/some.conf |grep -i something_to_grep
printf "\nPut the input: " read some_input
echo $some_input
done
When I run it, it just continues without waiting for my input. I need to copy/past something form ssh output for further action :/
Change
printf "\nPut the input: " read some_input
to
read -p "Put the input: " some_input
Example
for host in '1.1.1.100' '1.1.1.101' '1.1.1.102'
do
read -p "Enter your input for ${host} " host_input
echo "${host} says ${host_input}"
done

Expect Script for CLI

UPDATE: I am really frustrated at this point. I've tried moving the expect code to its own file and calling it from the bash script.
...
if [[ "$okay" == "OK" ]]
then
echo "PASSWORD ACCEPTED"
echo "Modifying User Passwords..."
COUNTER=0
while [ $COUNTER -lt $num ]; do
let index=COUNTER+1
tmp=user_$index
echo "Changing Password for " ${!tmp}
tmp2=$(${!tmp})
echo $tmp2
sh ./input.sh ${current_user} ${pass} ${password} ${tmp2}
let COUNTER=COUNTER+1
done
...
input.sh
expect -f
#------------------------------------------------------
set current_user [lindex $argv 0]
set pass [lindex $argv 1]
set password [lindex $argv 2]
set tmp2 [lindex $argv 3]
echo "EXPECT SCRIPT RUNNING"
sudo passwd ${!tmp2}
expect -exact "[sudo] password for $current_user: "
send "$pass\r"
expect -exact "New password: "
send "$password\r"
I would greatly, greatly appreciate it if someone could help me out.
I am writing a script that will allow a Linux admin to quickly change passwords of its users.
#!/usr/bin/expect
# Check password for strength
# ----------------------------------------------
read -p "What's your username?" current_user
read -p "What's the root password?" pass
read -p "How many users?" num
COUNTER=0
while [ $COUNTER -lt $num ]; do
let index=COUNTER+1
read -p "Enter username$index : " user_$index
let COUNTER=COUNTER+1
done
read -p "Enter password : " password
echo
echo "Tesing password strength..."
echo
result="$(cracklib-check <<<"$password")"
okay="$(awk -F': ' '{ print $2}' <<<"$result")"
if [[ "$okay" == "OK" ]]
then
echo "PASSWORD ACCEPTED"
echo "Modifying User Passwords..."
COUNTER=0
while [ $COUNTER -lt $num ]; do
let index=COUNTER+1
tmp=user_$index
echo "Changing Password for " ${!tmp}
echo ${!tmp}
sudo passwd ${!tmp}
expect -exact "[sudo] password for $current_user: "
send "$pass\r"
expect -exact "New password: "
send "$password\r"
let COUNTER=COUNTER+1
done
#echo "$user:$password" | usr/sbin/chpasswd
else
echo "Your password was rejected - $result"
echo "Try again."
fi
However, the expect portion, which would automate the inputting of passwords, is not highlighted in my editor and does not work. I keep getting prompts to manually enter text. This is especially surprising since the script is sourcing expect, not bash. I've been trying to fix this for the past 2 hours. Can anyone please lend me a hand?
I see some issues in your code. At first, you have tried adding #!/usr/bin/expect in the code, which should throw you an error about the read command as,
wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"
while executing
"read -p "What's your username?" current_user"
The reason is simply because the script will be treated as Expect script and it is not following it's syntax for read. I wonder how it worked for you. :)
When it is called as shell script, in that it should be enclosed withing expect -c not simply with expect -f
When expect -c is enclosed with single quotes, it won't allow bash substitutions. So, I am going to use double quotes. (but, it we have to escape the Expect's double quotes with backslashes.)
admin="dinesh"
admin_pwd="root"
user="satheesh"
user_pwd="Hello#12E"
OUTPUT=$(expect -c "
# To suppress any other form of output generated by spawned process
log_user 0
spawn sudo passwd $user
expect {
timeout { send_user \"Timeout happened\n\";exit 0}
\"Sorry, try again\" {send_user \"Incorrect admin password\";exit 0}
\"password for $admin: $\" {send \"$admin_pwd\r\";exp_continue}
\"password: $\" {send \"$user_pwd\r\";exp_continue}
\"successfully\" {send_user \"Success\"; exit 1}
}
")
echo "Expect's return value : $?"
echo "-----Expect's response-----"
echo $OUTPUT
The Expect's return value will be available in the variable $?. This will help us to know whether the password update is successful or not. The variable OUTPUT, will have the output generated by spawned process.
Use the #!/bin/bash, not #!/usr/bin/expect, since it is actually a bash script.

How to 'expect' something multiple times?

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
}
}'

Exporting a variable with a backslash

I am working on an install script, of the following form:
# get username
echo "Please enter your oracle username:"
read -p "> " username
stty -echo
# get password
echo "Please enter your oracle password:"
read -r -p "> " password; echo
stty echo
# -- Create all text to output to config
finaluser=$usernamelabel$username
finalpassword=$passwordlabel$password
echo -e $finaluser"\n"$finalpassword > $configfile
The problem is, if a password of the form like 'z\2z', it is outputted to $configfile as:
z^Bz
Is there any easy way to avoid this?
Don't embed the \n, and then you don't need the -e option which is also interpreting the \2.
echo "$finaluser" >$configfile
echo "$finalpassword" >>$configfile
or
cat >$configfile <<EOF
$finaluser
$finalpassword
EOF
or a third way if you really want to use a single command
printf '%s\n%s\n' "$finaluser" "$finalpassword"

Resources