spawn - comando non trovato!


15

Sto usando Mac OS X 10.9.4, di seguito è riportato il mio script per copiare i file dalla macchina locale a host diversi

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

quando eseguo questo script sto seguendo

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

Nel mio caso avevo bisogno di marcatori EOD attorno al codice di attesa. stackoverflow.com/questions/26125036/...
AnneTheAgile

Risposte:


20

La tua sceneggiatura sta tentando di combinare due interpreti. Hai entrambi #!/bin/bashe #!/usr/bin/expect. Non funzionerà Puoi usare solo uno dei due. Dal momento che bashera il primo, il tuo script viene eseguito come script bash.

Tuttavia, all'interno del tuo script, hai expectcomandi come spawne send. Poiché lo script viene letto da bashe non da expect, questo non riesce. Puoi aggirare questo problema scrivendo diversi expectscript e chiamandoli dal tuo bashscript o traducendo il tutto in expect.

Il modo migliore, però, e quello che evita la terribile pratica di avere le tue password in testo semplice in un semplice file di testo, è invece impostare ssh senza password. In questo modo, scpnon sarà necessaria una password e non sarà necessario expect:

  1. Innanzitutto, crea una chiave ssh pubblica sul tuo computer:

    ssh-keygen -t rsa

    Ti verrà chiesto un passphrase che ti verrà chiesto di inserire la prima volta che esegui un comando ssh dopo ogni accesso. Ciò significa che per più comandi ssh o scp, dovrai inserirlo solo una volta. Lasciare vuota la passphrase per un accesso completamente senza password.

  2. Dopo aver generato la chiave pubblica, copiarla su ciascun computer della rete:

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

    L' IPlistfile.txtdovrebbe essere un file che contiene il nome di un server o IP su ogni linea. Per esempio:

    host1
    host2
    host3
    

    Poiché questa è la prima volta che lo fai, dovrai inserire manualmente la password per ciascun IP, ma una volta fatto, sarai in grado di copiare i file su una di queste macchine con un semplice:

    scp file user@host1:/path/to/file
  3. Rimuovi l'attesa dal tuo script. Ora che hai accesso senza password, puoi usare il tuo script come:

    #!/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
Se avvii un agente ssh, dovrai solo inserire la passphrase una volta. Altrimenti, dovrai inserirlo ogni volta.
Glenn Jackman,

5

Il tuo codice può essere molto più conciso:

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

Se si impostano i tasti ssh come suggerito, è ancora meglio:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.