send: spawn id exp7 not open - bash

When I try to execute autoexpect file I get an error send: spawn id exp7 not open
Here is my file sh.exp:
#!/usr/bin/expect
# mysql credentials and connection data
db_host='localhost'
db_name='webui_dev'
db_user='root'
db_pass=''
new_db_name='db_2011'
expect <<EOF
log_user 0
spawn mysql -h $db_host -u $db_user -p $db_pass 'create database $new_db_name'
expect "password:"
send "$db_pass\r"
log_user 1
expect eof
EOF
Can't find where is an error.

Try quoting your variables properly:
spawn mysql -h "$db_host" -u "$db_user" -p "$db_pass" "create database $new_db_name"
Variables not quoted in double quotes are subject to word splitting and pathname expansion. And variables under single quotes don't expand. Read more about shell quoting here.
Update: It seems that you're actually expanding it through a here document, but it would still apply since your arguments still need to be quoted in expect. This is what it would appear as input to expect:
log_user 0
spawn mysql -h "localhost" -u "root" -p "" "create database db_2011"
expect "password:"
send "\r"
log_user 1
expect eof
This is how it would appear if you haven't quoted it yet:
...
spawn mysql -h localhost -u root -p 'create database db_2011'
...
UPDATE:
The cause of the problem actually is because mysql ends quickly without showing a prompt for password due to the extra argument. The solution is to send the command manually. It's also preferable to just run the whole script as an expect script, not an embedded one for lesser confusion
#!/usr/bin/expect
# mysql credentials and connection data
set db_host "localhost"
set db_name "webui_dev"
set db_user "root"
set db_pass ""
set new_db_name "db_2011"
log_user 0
spawn mysql -h "$db_host" -u "$db_user" -p
expect "password:"
send "$db_pass\r"
expect "mysql>"
send "create database $new_db_name; exit; \r"
log_user 1
expect eof
Save the script as an expect file and run it with expect -f expect_file.

Related

How to match this [admin#MikroTik] > in bash script (expect)?

I am trying to write a script that will auto configure mikrotik router, but some weird character appears as soon as password is sent through the script and logins the router. Below is the script that i wrote,
#!/bin/bash
read -p "Enter IP Address: " Public_IP
read -p "Enter username: " Username
read -sp "Enter Password: " Password
echo
expect -c "
spawn ssh -o StrictHostKeyChecking=no $Username#$Public_IP
set timeout -1
expect "password:"
send "$Password\r"
expect "\[admin*"
sleep 4
expect "\[admin*"
"
While I run this script I see below the following in the image,
So what i want to accomplish is to see the second image and send some commands for example;
/ip arp print
send above commmand for instance.
image after running the script
the actual interface i want to get and send command like that
you need to add +tc after username in ssh command
spawn ssh -o StrictHostKeyChecking=no $Username+tc#$Public_IP
it´s works for me

Establishing password less connection SunOS using expect

The host system from where I am trying to establish remote connection is running on SunOS. There isn't ssh-copy-id available on the system.
After searching, I found that the following command, when executed will mimic the ssh-copy-id function.
cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo "Host Key Copied"'
I am trying to write a script using expect for doing this operation but it is failing with the following error.
Code:
#!/usr/bin/expect -f
#!/bin/bash
set username [lindex $argv 0]
set password [lindex $argv 1]
set host [lindex $argv 2]
cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo \"Host Key Copied\"'
expect "Password:"
send "$password\n"
expect eof
Error:
invalid command name "cat"
while executing
"cat ~/.ssh/id_rsa.pub | ssh remotehost 'cat >>~/.ssh/authorized_keys && echo \"Host Key Copied\"'"
(file "./remote.sh" line 8)
From search, I understood that expect won't entertain shell commands by default. Could someone help in resolving my issue. Thanks in advance.
You're missing the spawn command: spawn launches the process that you're interacting with. You're also missing the ssh-copy-id command:
spawn ssh-copy-id $username#$host
expect ...
However, what you're doing is greatly reducing security. Passing the password in clear text on the command line, where it will likely be stored in your shell's history file.

expect script works while invoking individually but not as a salt state

I'm trying to do scp as well as ssh through expect. Below script works if I invoke it directly from terminal like /usr/bin/expect myexpect.sh but when I ran it using salt, the first scp command works where the second ssh fails.
myexpect.sh
#!/usr/bin/expect -f
set timeout 240
spawn scp apps.tar.gz /srv/salt/integration/serverclass_merged.conf foo#10.10.10.10:/home/foo
expect "password:"
send "password\n";
expect eof
spawn ssh -o StrictHostKeyChecking=no foo#10.10.10.10 "cd /home/foo;tar --strip-components=1 -xzvf apps.tar.gz -C /opt/apps/;cp serverclass_merged.conf /opt/local/serverclass.conf"
expect "assword:"
send "password\r"
interact
Relevant salt state looks like,
st.sls
copy_apps:
cmd.run:
- name: /usr/bin/expect /home/ocdn_adm/myexpect.sh
I know nothing about salt-stack but I suspect it's not running your Expect script from a pty. So replace interact with expect eof (or expect -timeout 12345 eof if necessary). interact works only when stdin is on a tty/pty.

Script with condition

I am a beginner in the development of scripts.I want to do 4 tasks in one script:
1. Connect to machine 1 by ssh
2.Retrieve the data and put it in a CSV file
3.Send the CSV file to a directory
4.connect to machine 2 by ssh and do step 2 and 3
Fisrt test :
#!/bin/bash
#Settings
DATE=$(date +%Y_%m_%d)
DATE1=$(date +%d/%m/%Y)
HIER=$(date -d '1 day ago' "+%Y-%m-%d")
HEURE=$(date +"%T")
#Ip adress of the machine
machine1= IP1
machine2= IP2
#Connexion SSH OLT1
ssh root#IP1
#Command for geting data on machine
enable
config
display XXXX > IP1.csv
#exit connection
exit
I do not have any result so i think
Do i make a loop for executing the task for the 2 machines?
Thanks
I'm trying tu use expect because i find RSA key problem by using SSH and shell script
#spawn ssh $host -l $user
expect "login:"
send "root\r"
expect "passe:"
send "test\r"
expect -re $prompt
send "terminal length 0\r"
expect -re $prompt
send "enable\r"
expect -re $prompt
send "config\r"
expect -re $prompt
send "display .....\r"
expect -re "\r\nend\r\n"
send "exit\r"
I don't know how i can put the result on csv file to a directory?
Besides, can i put the IP on #spawn assume that task should be done on 2 machines
Thanks for your feedback
I try thisaccording to your sample but the ouput file is empty:
#!/usr/bin/expect
spawn ssh X.X.X.X -l root
expect "User password:"
send "admin\n"
expect -re "device>"
send "enable\r"
expect -re "device#"
send "config\r"
expect -re "device(config)#"
send "display .......\r"
expect -re "{ <cr>||<K> }:"
send "\r"
set date [timestamp -format %C%y%m%d]
log_file -noappend /home/device/CSTtest.csv
You can run your command and export to out file in same ssh call like this:
# ...
# first machine command
ssh root#IP1 "<COMMAND>" > /PATH_LOCAL_TO_SAVE_FILE/IP1.csv
# second machine command
ssh root#IP2 "<COMMAND>" > /PATH_LOCAL_TO_SAVE_FILE/IP2.csv

stdout stream redirect in expect scripts

I have the following bash script which wraps an expect script (in here-document form):
#!/bin/bash
PASSWORD_MYSQL_ROOT=root
expect <<- DONE
set timeout -1
spawn mysqldump --all-databases --user=root --password --protocol=TCP --host=localhost --verbose > somebackupfile.sql
expect "*?asswor?:*"
send -- "$PASSWORD_MYSQL_ROOT\r"
expect eof
DONE
When I execute this script, I get the following output:
spawn mysqldump --all-databases --user=root --password --protocol=TCP --host=localhost --verbose > somebackupfile.sql
Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
For more options, use mysqldump --help
send: spawn id exp4 not open
while executing
"send -- "root\r""
So something didn't work right.
After some try and error, I found out that the stdout stream redirect > somebackupfile.sql is the culprit -- the script works once this redirect is removed.
So I am wondering: How do I use stream redirection in expect scripts?
untested, but this should work:
expect <<- DONE
set timeout -1
spawn mysqldump --all-databases --user=root --password --protocol=TCP --host=localhost --verbose
expect "*?asswor?:*"
send -- "$PASSWORD_MYSQL_ROOT\r"
log_file somebackupfile.sql
expect eof
DONE

Resources