How to use expect inside bash script [duplicate] - bash

This question already has an answer here:
Embedding an Expect script inside a Bash script
(1 answer)
Closed 5 years ago.
Could anybody please tell me why this is not working?
#!/bin/bash
cd /home
touch somefile
/usr/bin/expect<<FILETRANSFER
spawn scp -r -P remoteServerPort somefile remoteServerIP:/home
expect "assword:"
send "MyPassWord\r"
interact
FILETRANSFER
echo "It's done"
It doesn't give any error but file is not transferred to remote server.I have tried many ways still couldn't find any solution.

The bash script you have defined is passing the expect commands on the standard input of expect. However, the expect command requires its arguments on a file or as an argument using the -c option.
You have several options but to add the less modifications on your script you just need to use the process substitution to create a here-document (temporary) for the expect command.
#!/bin/bash
echo "[DEBUG] INIT BASH"
cd /home
touch somefile
/usr/bin/expect <(cat << EOF
spawn scp -r -P remoteServerPort somefile remoteServerIP:/home
expect "Password:"
send "MyPassWord\r"
interact
EOF
)
echo "[DEBUG] END BASH"

Related

Testing account existence using expect

I have a list of 400 servers and I like to check unix account existence with expect to loop it
I wrote a bash script that uses expect command but it returns me error message that I don't understand the meaning
#!/bin/bash
fic_serv="test.txt"
echo "Passwd"
stty -echo
read -s passwd
stty echo
suffix="suffix"
account="acc"
for server in `cat $fic_serv`
do
prompt="[$acc#$server ~]$ "
expect -c "
spawn ssh -o StrictHostKeyChecking=no $account#$server.$suffix
expect "Password: "
send "$passwd\r"
expect $prompt
send "logout\r"
"
done
[acc#serv ~]$ couldn't read file "
send "passwd\r"
expect [acc#server ~]$
send "logout\r"
": no such file or directory
(I modified the value)
You should use while, not for, to parse files in Bash. Use a "redirect" to treat a file as standard input and read one line at a time.
while read server; do
...
done < $fic_serv
Your major problem is Expect interprets your "s as "end of script". Escape them, as in \", or use {}, as in:
expect -c "
spawn ssh -o StrictHostKeyChecking=no $account#$server.$suffix
expect {Password: }
send {$passwd\r}
expect $prompt
send {logout\r}
"
If you have 400 servers to manage, I strongly recommend you use ansible.
You could just put the list of hosts into a file, let's call it inventory, and run the following command:
ansible -i inventory -m shell -a "id acc" all
Using here-docs in the shell to embed code for another language is usually better than quoting hell, and sharing variables through the environment is easier and safer than parameter expansion:
export account passwd
while IFS= read -r server; do
export prompt="[$acc#$server ~]$ "
export host="$server.$suffix"
expect << 'END_EXPECT'
spawn ssh -o StrictHostKeyChecking=no $env(account)#$env(host)
expect "Password: "
send "$env(passwd)\r"
expect $env(prompt)
send "logout\r"
expect eof
END_EXPECT
done < "$fic_serv"
As shown, I like to indent the heredoc to make it more obvious.
And depending on the error message or login prompt, there can be more logic to indicate that the account name and/or password are incorrect.

expect not taking ssh arguments while/for loop [duplicate]

I have list of filenames in a text file,need to transfer each file into server using scp command.I am reading filenames from Read.sh and passing each file name to transfer.sh script but scp is not executing command in this transfer script.If I run transfer.sh alone with passing args its working fine.
List.txt
/home/kittu/file1.txt
/home/kittu/file2.txt
/home/kittu/file3.txt
Read.sh
#!/bin/bash
while read p; do
echo $p
./transfer.sh "$p"
done <List.txt
transfer.sh
#!/usr/bin/expect -f
# get filename from command-line
set f [lindex $argv 0]
spawn scp "$f" user#192.168.4.151:/home/user/Desktop/
expect "password"
send "123\r"
interact
I just run Read.sh as
>./Read.sh
Output:
/home/user/Desktop/file1.txt
spawn scp /home/mbox140/Desktop/test.sh mbox140#192.168.4.151:/home/mbox140/Desktop/videos/
user#192.168.4.151's password:
Its not executing next statement.Please suggest me any solution.
Try the below script , The changes are that the Transfer.sh is wrapped into bash.sh.
and the reason it waits in the password may be because you are expecting a wrong pattern , try "Password" instead of "password" and after send command, expect for the terminal pattern so that the scp finishes
#!/bin/bash
while read p; do
echo $p
{
/usr/bin/expect << EOF
spawn scp $p user#192.168.4.151:/home/user/Desktop/
expect "Password"
send "123\r"
expect "*#*"
EOF
}
done <List.txt

expect sudo ssh login issue [duplicate]

This question already has answers here:
How can I escape a double quote inside double quotes?
(9 answers)
Closed 5 years ago.
i wrote an expect script to ssh remotely to multiple linux boxes and running this command chmod -R o-w /etc/
But i am getting an error expect: invalid option -- 'R'
Please find the script below
#!/bin/bash
username=$1
userpass=$2
rootpass=$3
cat server_list | while read host
do
expect -c "
set timeout 5
spawn ssh -o StrictHostKeyChecking=no -tq ${username}#${host} sudo su - root
expect "ssword" { send "${userpass}r" }
expect "ssword" { send "{rootpass}r" }
expect "#"
send "chmod -R o-w /etc"
expect "#" { send "exitr" }
expect eof"
done
i am running the script like this
./test1.sh test test#123 test#123
Kindly help
Use "--" flags in the send command which will force the next argument to be read as string.
send -- "chmod -R o-w /etc"
Read more in Expect manpage

Expect Script - bash script file not found

My expect script
#!/usr/bin/expect -f
#I tried replacing sh - with bash -s still no positive results
spawn ssh xxxx#yyyy "sh -" < test.sh
expect "password: "
send "zzzzz\r"
expect "$ "
This command works well if executed in the terminal
ssh xxxx#yyyy "sh -" < test.sh
But if I execute it via expect script; it fails.
This is the output if I execute it via the expect script. May I know where I am going wrong
bash: test.sh: No such file or directory
P.S : Yes, the file exists and the credentials are right.
Expect script was unable to read the contents of the file, that was the issue. Solved it by reading the contents of the file and passing that variable instead of the file name,
set fh [open test.sh r]
set contents [read $fh]
close $fh
and replacing the sh- with bash -c '$contents'
Thank you everyone for the valuable comments.

how to use expect inside shell script

I have a bash+expect script which has to connect normal user, i want
to read the specific file and store into the variable to be used
after while that specific file in root user. How can i get the value ?
My script is:
#!/bin/bash
set prompt ">>> "
set command ls /root/test1
expect << EOF
spawn su root
expect "password:"
send "rootroot\r"
expect "$prompt\r"
send "$command\r"
expect "$prompt\r"
expect -re "(.*)\r\n$prompt\r\n"
EOF
echo "$command"
if [ ! -f "$command" ]; then
echo "file is not exist"
else
echo "file is exist"
fi
whenever i'm execute my shell script it show following output:
ls: /root/: Permission denied
file is not exist
basically test is there but it is showing "file is not exist"
This question is very old but i hope someone gets help from this answer.
--> You should use #!/usr/bin/expect or #!/bin/expect to use expect properly, expect<<EOF might work but thats not conventional way to write script.
--> You script should end with EOF statement . Ex.
#!/usr/bin/expect << EOF
<some stuff you want to do>
EOF
--> Some basic thing about spawn. Whatever you write in spawn will execute but it will not have effect on entire script. Its not like environment variables.
In short, spawn will start new process and your command is not under spawn process.
Ex.
#!/usr/bin/expect
spawn bash -c "su root '<your-cmd-as-root>'"
<some-expect-send-stuff-etc>
Now in your script, $command should be write inside spawn like i showed in above example.

Resources