我使用的是 Mac OS X 10.9.4,以下是我将文件从本地计算机复制到不同主机的脚本
#!/bin/bash
#!/usr/bin/expect
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
spawn scp filePath uname@host1:/usr/tmp
expect "password"
send "MyPassword\r"
interact
elif [ $choice -eq "2" ]
then
spawn scp filePath uname@host2:/usr/tmp
expect "password"
send "MyPassword\r"
interact
elif [ $choice -eq "3" ]
then
spawn scp filePath uname@host3:/usr/tmp
expect "password"
send "MyPassword\r"
interact
else
echo "Wrong input"
fi
运行这个脚本时我正在关注
./rcopy.sh: line 21: spawn: command not found
couldn't read file "password": no such file or directory
./rcopy.sh: line 23: send: command not found
./rcopy.sh: line 24: interact: command not found
答案1
您的脚本正在尝试组合两个解释器。你同时拥有#!/bin/bash
和#!/usr/bin/expect
。那是行不通的。您只能使用两者之一。从bash
一开始,您的脚本就作为 bash 脚本运行。
但是,在您的脚本中,您有expect
诸如spawn
和 之类的命令send
。由于脚本正在被 读取bash
,而不是被 读取expect
,因此失败。您可以通过编写不同的expect
脚本并从bash
脚本中调用它们或将整个脚本转换为expect
.
不过,最好的方法,也是避免将密码以纯文本形式保存在简单文本文件中的糟糕做法的方法,是设置无密码 ssh。这样,就不需要scp
密码,您也不需要expect
:
首先,在您的计算机上创建一个公共 ssh 密钥:
ssh-keygen -t rsa
每次登录后首次运行任何 ssh 命令时,系统都会要求您输入密码。这意味着对于多个 ssh 或 scp 命令,您只需输入一次。将密码留空以实现完全无密码访问。
生成公钥后,将其复制到网络中的每台计算机:
while read ip; do ssh-copy-id -i ~/.ssh/id_rsa.pub user1@$ip done < IPlistfile.txt
该
IPlistfile.txt
文件应该是每行包含服务器名称或 IP 的文件。例如:host1 host2 host3
由于这是您第一次执行此操作,因此您必须手动输入每个 IP 的密码,但完成后,您将能够通过简单的操作将文件复制到任何这些计算机:
scp file user@host1:/path/to/file
从脚本中删除期望。现在您已经有了无密码访问权限,您可以将脚本用作:
#!/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
答案2
您的代码可以更加简洁:
#!/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
如果您按照建议设置 ssh 密钥,那就更好了:
if [[ -n $host ]]; then
scp "$filePath" uname@$host:/usr/tmp
break
fi
答案3
spawn
是一个expect
命令。如果您的口译员是 ,它将不起作用/bin/bash
。