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
スクリプトが2つのインタープリターを結合しようとしています。両方あります#!/bin/bash
および#!/usr/bin/expect
。それはうまくいきません。 2つのうち1つしか使用できません。 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
あなたのコードはもっと簡潔にすることができます:
#!/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
spawn
はexpect
コマンドです 。インタープリターが/bin/bash
の場合は機能しません。