OpenSSH scp
l'utility richiama il ssh
programma per effettuare la connessione SSH all'host remoto e il processo ssh gestisce l'autenticazione. Il ssh
l'utilità non accetta una password sulla riga di comando o sul suo input standard. Credo che questa sia una decisione deliberata da parte degli sviluppatori di OpenSSH, perché ritengono che le persone dovrebbero utilizzare meccanismi più sicuri come l'autenticazione basata su chiave. Qualsiasi soluzione per invocare ssh seguirà uno di questi approcci:
- Utilizza una chiave SSH per l'autenticazione, invece di una password.
- Utilizza sshpass, wait o uno strumento simile per automatizzare la risposta alla richiesta della password.
- Usa (abusa) della funzionalità SSH_ASKPASS per ottenere
ssh
per ottenere la password invocando un altro comando, descritto qui o qui, o in alcune delle risposte qui. - Chiedi all'amministratore del server SSH di abilitare l'autenticazione basata su host e utilizzala. Si noti che l'autenticazione basata su host è adatta solo per determinati ambienti di rete. Vedi note aggiuntive qui e qui.
- Scrivi il tuo client ssh usando perl, python, java o il tuo linguaggio preferito. Sono disponibili librerie client ssh per la maggior parte dei linguaggi di programmazione moderni e avresti il pieno controllo su come il client ottiene la password.
- Scarica il codice sorgente ssh e crea una versione modificata di
ssh
che funziona nel modo desiderato. - Usa un client ssh diverso. Sono disponibili altri client ssh, sia gratuiti che commerciali. Uno di questi potrebbe soddisfare le tue esigenze meglio del client OpenSSH.
In questo caso particolare, dato che stai già invocando scp
da uno script Python, sembra che uno di questi sarebbe l'approccio più ragionevole:
- Usare pexpect, il modulo di attesa di Python, per invocare
scp
e inserisci la password. - Usa paramiko, l'implementazione ssh di Python, per eseguire questa operazione ssh invece di invocare un programma esterno.
Ecco una funzione per ssh
con una password usando pexpect
:
import pexpect
import tempfile
def ssh(host, cmd, user, password, timeout=30, bg_run=False):
"""SSH'es to a host using the supplied credentials and executes a command.
Throws an exception if the command doesn't return 0.
bgrun: run command in the background"""
fname = tempfile.mktemp()
fout = open(fname, 'w')
options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'
if bg_run:
options += ' -f'
ssh_cmd = 'ssh %[email protected]%s %s "%s"' % (user, host, options, cmd)
child = pexpect.spawn(ssh_cmd, timeout=timeout) #spawnu for Python 3
child.expect(['[pP]assword: '])
child.sendline(password)
child.logfile = fout
child.expect(pexpect.EOF)
child.close()
fout.close()
fin = open(fname, 'r')
stdout = fin.read()
fin.close()
if 0 != child.exitstatus:
raise Exception(stdout)
return stdout
Qualcosa di simile dovrebbe essere possibile usando scp
.
La seconda risposta che hai collegato suggerisce di utilizzare Pexpect (che di solito è il modo giusto per interagire con i programmi a riga di comando che si aspettano input). C'è un fork che funziona per python3 che puoi usare.