0

the short of it is that i need a program to upload all txt files from a local directory via sftp, to a specific remote directory. if i run mput *.txt from sftp command line, while im already in the right local directory, then that was what i was shooting for.

Here is the code im trying. No errors when i run it, but no results either when i sftp to the server and ls the upload directory, its empty. i may be barking up the wrong tree all together. i see other solutions like lftp using mget in bash...but i really want this to work with python. either way i have a lot to learn still. this is what ive come up with after a few days reading about what some stackoverflow users suggested, a few libraries that might help. im not sure i can do the "for i in allfiles:" with subprocess.

import os
import glob
import subprocess 

os.chdir('/home/submitid/Local/Upload') #change pwd so i can use mget *.txt and glob similarly 

pwd = '/Home/submitid/Upload' #remote directory to upload all txt files to

allfiles = glob.glob('*.txt') #get a list of txt files in lpwd

target="user@sftp.com"


sp = subprocess.Popen(['sftp', target], shell=False, stdin=subprocess.PIPE)


sp.stdin.write("chdir %s\n" % pwd) #change directory to pwd

for i in allfiles:
    sp.stdin.write("put %s\n" % allfiles) #for each file in allfiles, do a put %filename to pwd

sp.stdin.write("bye\n")       


sp.stdin.close()
A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
Dogbyte
  • 99
  • 2
  • 10

2 Answers2

0

When you iterate over allfiles, you are not passing the iterator variable sp.stdin.write, but allfiles itself. It should be

for i in allfiles:
    sp.stdin.write("put %s\n" % i) #for each file in allfiles, do a put %filename to pwd

You may also need to wait for sftp to authenticate before issuing commands. You could read stdout from the process, or just put some time.sleep delays in your code.

But why not just use scp and build the full command line, then check if it executes successfully? Something like:

result = os.system('scp %s %s:%s' % (' '.join(allfiles), target, pwd))
if result != 0:
    print 'error!'
Peter Gibson
  • 19,086
  • 7
  • 60
  • 64
  • DANG that worked! Now if i can only get rid of the password prompt. i will have to read up on the time.sleep...thank you!! – Dogbyte May 16 '14 at 03:01
  • @Dogbyte you might be better off just using SSH public key authentication to bypass the need for a password. See http://stackoverflow.com/questions/7260/how-do-i-setup-public-key-authentication – Peter Gibson May 16 '14 at 03:03
  • about the SSH public key auth, im not sure i have that level of access to the remote server, this is an EDI transaction to a healthcare provider. they only allow the basic sftp commands. – Dogbyte May 16 '14 at 03:14
  • im not sure what the scp line is doing, i just started coding a few weeks ago, is that result line only handling connecting to the sftp server? ' '.join(allfiles) is just passing the list of files? – Dogbyte May 16 '14 at 03:20
  • `sftp` and `scp` both transfer files using SSH, so you should be able to get it to work. `' '.join(allfiles)` joins a list of strings with a space `' '`. – Peter Gibson May 16 '14 at 03:26
  • The `scp` command expands to `scp 1.txt 2.txt user@sftp.com:/Home/submitid/Upload`. This just instructs `scp` to copy the text files to the remote server in one simple command. – Peter Gibson May 16 '14 at 03:29
0

You dont need to iterate over allfiles

sp.stdin.write("put *.txt\n")

is enough. You instruct sftp to put all files at once, instead of one by one.

chapelo
  • 2,519
  • 13
  • 19