spawn - komut bulunamadı!


15

Mac OS X 10.9.4 kullanıyorum, dosyaları yerel makineden farklı ana bilgisayara kopyalamak için komut dosyam

#!/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

Bu komut dosyasını çalıştırırken takip ediyorum

./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

Benim durumumda beklemek kodu etrafında EOD işaretleyicileri gerekiyordu. stackoverflow.com/questions/26125036/…
AnneTheAgile

Yanıtlar:


20

Senaryonuz iki tercümanı birleştirmeye çalışıyor. Sen ikisine de sahip #!/bin/bashve #!/usr/bin/expect. Bu işe yaramaz. İkisinden yalnızca birini kullanabilirsiniz. Dan beribash , betiğiniz bash betiği olarak çalıştırılıyor.

Ancak, komut dosyası içinde, sahip expectgibi komutları spawnve send. Komut dosyası tarafından okunuyor bashve okunmuyor expect, bu başarısız oluyor. Farklı expectkomut dosyaları yazıp komut bashdosyanızdan çağırarak veya her şeyi şu dile çevirerek bu sorunu çözebilirsiniz expect.

Yine de en iyi yol ve basit bir metin dosyasında düz metin parola sahip olmak korkunç bir uygulama önler, bunun yerine parolasız ssh kurmaktır. Bu şekilde, scpbir parolaya ihtiyaç duymazsınız ve şunlara ihtiyacınız yoktur expect:

  1. İlk olarak, makinenizde genel bir ssh anahtarı oluşturun:

    ssh-keygen -t rsa

    Her girişten sonra herhangi bir ssh komutunu ilk çalıştırdığınızda girmeniz istenecek bir parola girmeniz istenecektir. Bu, birden fazla ssh veya scp komutu için yalnızca bir kez girmeniz gerektiği anlamına gelir. Tamamen şifresiz erişim için parolayı boş bırakın.

  2. Genel anahtarınızı oluşturduktan sonra, ağınızdaki her bilgisayara kopyalayın:

    while read ip; do 
     ssh-copy-id -i ~/.ssh/id_rsa.pub user1@$ip 
    done < IPlistfile.txt

    IPlistfile.txtHer satıra bir sunucunun adını veya IP içeren bir dosya olmalıdır. Örneğin:

    host1
    host2
    host3

    Bunu ilk kez yaptığınızdan, her IP için şifreyi manuel olarak girmeniz gerekecektir, ancak bunu yaptıktan sonra, bu makinelerin herhangi birine basit bir şekilde dosya kopyalayabilirsiniz:

    scp file user@host1:/path/to/file
  3. Beklentiyi betiğinizden kaldırın. Artık şifresiz erişime sahip olduğunuza göre, komut dosyanızı şu şekilde kullanabilirsiniz:

    #!/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

1
Bir ssh aracısı başlatırsanız, parolayı yalnızca bir kez girmeniz gerekir. Aksi takdirde, her seferinde girmeniz gerekir.
glenn jackman

5

Kodunuz çok daha kısa ve öz olabilir:

#!/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 anahtarlarını önerilen şekilde ayarlarsanız, daha da iyidir:

    if [[ -n $host ]]; then
        scp "$filePath" uname@$host:/usr/tmp   
        break
    fi

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.