I'm trying to run an scp
(secure copy) command using subprocess.Popen
. The login requires that I send a password:
from subprocess import Popen, PIPE
proc = Popen(['scp', "user@10.0.1.12:/foo/bar/somefile.txt", "."], stdin = PIPE)
proc.stdin.write(b'mypassword')
proc.stdin.flush()
This immediately returns an error:
user@10.0.1.12's password:
Permission denied, please try again.
I'm certain the password is correct. I easily verify it by manually invoking scp
on the shell. So why doesn't this work?
Note, there are many similar questions to this, asking about subprocess.Popen
and sending a password for automated SSH or FTP login:
How can I set a users password in linux from a python script?
Use subprocess to send a password
The answer(s) to these questions don't work and/or don't apply because I am using Python 3.
Pexpect has a library for exactly this: pxssh
http://pexpect.readthedocs.org/en/stable/api/pxssh.html
Here's a function to
ssh
with a password usingpexpect
:Something similar should be possible using
scp
.The OpenSSH
scp
utility invokes thessh
program to make the SSH connection to the remote host, and the ssh process handles authentication. Thessh
utility doesn't accept a password on the command line or on its standard input. I believe this is a deliberate decision on the part of the OpenSSH developers, because they feel that people should be using more secure mechanisms like key-based authentication. Any solution for invoking ssh is going to follow one of these approaches:ssh
to get the password by invoking another command, described here or here, or in some of the answers here.ssh
that works the way you want.In this particular case, given that you're already invoking
scp
from a python script, it seems that one of these would be the most reasonable approach:scp
and feed the password to it.The second answer you linked suggests you use Pexpect(which is usually the right way to go about interacting with command line programs that expect input). There is a fork of it which works for python3 which you can use.
I guess some applications interact with the user using stdin and some applications interact using terminal. In this case when we write the password using PIPE we are writing to stdin. But SCP application reads the password from terminal. As subprocess cannot interact with user using terminal but can only interact using stdin we cannot use the subprocess module and we must use pexpect for copying the file using scp.
Feel free for corrections.