spawn - command not found!
Your script is attempting to combine two interpreters. You have both #!/bin/bash
and #!/usr/bin/expect
. That won't work. You can only use one of the two. Since bash
was first, your script is being run as a bash script.
However, within your script, you have expect
commands such as spawn
and send
. Since the script is being read by bash
and not by expect
, this fails. You could get around this by writing different expect
scripts and calling them from your bash
script or by translating the whole thing to expect
.
The best way though, and one that avoids the horrible practice of having your passwords in plain text in a simple text file, is to set up passwordless ssh instead. That way, the scp
won't need a password and you have no need for expect
:
First, create a public ssh key on your machine:
ssh-keygen -t rsa
You will be asked for a passphrase which you will be asked to enter the first time you run any ssh command after each login. This means that for multiple ssh or scp commands, you will only have to enter it once. Leave the passphrase empty for completely passwordless access.
Once you have generated your public key, copy it over to each computer in your network :
while read ip; do ssh-copy-id -i ~/.ssh/id_rsa.pub user1@$ip done < IPlistfile.txt
The
IPlistfile.txt
should be a file containing a server's name or IP on each line. For example:host1 host2 host3
Since this is the first time you do this, you will have to manually enter the password for each IP but once you've done that, you will be able to copy files to any of these machines with a simple:
scp file user@host1:/path/to/file
Remove the expect from your script. Now that you have passwordless access, you can use your script as:
#!/bin/bash echo "I will fail if you give junk values!!" echo " " echo "Enter file name: " read filePath echo " " echo "Where you want to copy?" echo "Enter" echo "1. if Host1" echo "2. if Host2" echo "3. if Host3" read choice echo " " if [ $choice -eq "1" ] then scp filePath uname@host1:/usr/tmp elif [ $choice -eq "2" ] then scp filePath uname@host2:/usr/tmp elif [ $choice -eq "3" ] then scp filePath uname@host3:/usr/tmp else echo "Wrong input" fi
Your code can be a lot more concise:
#!/bin/bash
read -p "Enter file name: " filePath
if ! [[ -r $filePath ]]; then
echo "cannot read $filePath"
exit 1
fi
PS3="Where you want to copy? "
select host in host1 host2 host3; do
if [[ -n $host ]]; then
expect <<END
spawn scp "$filePath" uname@$host:/usr/tmp
expect "password"
send "MyPassword\r"
expect eof
END
break
fi
done
If you set up ssh keys as suggested, it's even better:
if [[ -n $host ]]; then
scp "$filePath" uname@$host:/usr/tmp
break
fi
spawn
is an expect
command. It will not work if your interpreter is /bin/bash
.