【发布时间】:2019-03-12 14:15:00
【问题描述】:
我在实现 ssh 和 rsync 时遇到了麻烦,包括 python 中的私钥,包括 Popen(子进程)。
基本上使用的 rsync 语法应该是:
$ rsync -az -e --log-file=$logdir/logfile.out \
'ssh -e /home/user/.ssh/id_rsa' user@server:/target-directory
我拥有的是这样的:
import subprocess
首先,我使用变量构建我的 logdir 路径:
logdir = [basedir + '/' + 'log' + '/' + today + '/' + 'pfdcopy_' \
+ typ + '_' + ts + '.log.txt']
然后我建立目标目录:
target= ['jboss' + '@' + targetsvr + ':' + /data']
最后,我尝试运行这段代码
p1 = subprocess.Popen(['rsync', '-az', '--log-file=%s' % \
logdir/logfile.out , '-e', 'ssh', '-i', \
'/home/user/.ssh/id_rsa', target])
我知道这很复杂,主要是因为变量和引号。
运行这个程序,我总是遇到与 p1 不同的语法错误。
非常感谢任何帮助。谢谢!
已编辑(2018 年 8 月 10 日):
这是我完整的可运行代码 sn-p -
from datetime import datetime
import subprocess
import os
import fnmatch
now = datetime.now()
today = now.strftime("%Y-%m-%d")
ts = now.strftime("%Y-%m-%d-%H-%M-%S")
sign_output_dir = '/Users/fanta4/Documents/python-files/outgoing'
mandator = 'BTV'
formsize = 'A4'
basedir = '/Users/fanta4/Documents'
pdf_to_send = []
targetsvr = 'nas1'
doktyp = (
'WPGEBUEHR', 'WPDURCHFU', 'WPABR', 'WPABRKF', 'WPABRVK', 'WPABRTILG', 'WPABRERTR', 'WPAMIS', 'WPSTREP',
'WPABLAUF', 'WPAVISO', 'WPAUSZUG', 'WPERTRAEG', 'WPSIKTEST', 'WPTRANS', 'WPANSCHAFF', 'KKKONTOMIT', 'KRKURSUEW',
'WPVERLUSTA', 'WPVERLUSTG')
os.chdir(sign_output_dir)
for file in os.listdir(sign_output_dir):
if fnmatch.fnmatch(file, '*.pdf'):
pdf_to_send.append(file)
os.chdir(sign_output_dir)
print('debug: doktyp ist: {}'.format(formsize))
for typ in doktyp:
if typ in str(pdf_to_send):
ts = now.strftime("%Y-%m-%d-%Hh-%Mm-%Ss")
print('typ: {:12s} exists -> will be transfered to nas1'.format(typ))
logdir = [basedir + '/' + 'log' + '/' + mandator + '/' + today + '/' + 'pfdcopy_' + typ + '_' + ts + '.log.txt']
target = ['jboss' + '@' + targetsvr + '/data' + '/' + mandator + typ]
p1 = subprocess.Popen(
['rsync', '-az', '--log-file=%s' % logdir, '-e', 'ssh', '-i', '/Users/fanta4/.ssh/id_rsa', typ, '-l', target])
p1.returncode
if p1 > 0:
print('debug: Error with rsync of typ: {} to target: {}'.format(typ, targetsvr))
else:
print('debug: rsync mandator: {:3s} with typ: {:12s} succeeded'.format(mandator, typ))
else:
print('debug: typ: {:12s} does not exist'.format(typ))
logfile = ['/data' + '/' + 'log' + '/' + mandator + '/' + ts]
print('debug: pls see logfile in: {}'.format(logfile))
如果我运行这段代码,我会得到:
/Users/fanta4/anaconda3/bin/python "/Users/fanta4/Library/Mobile Documents/com~apple~CloudDocs/entw/python/prog/rsync-test.py"
Traceback (most recent call last):
/Users/fanta4/Documents/python-files/outgoing
debug: doktyp ist: A4
File "/Users/fanta4/Library/Mobile
Documents/com~apple~CloudDocs/entw/python/prog/rsync-test.py", line 37, in <module>
typ: WPGEBUEHR exists -> will be transfered to nas1
['rsync', '-az', '--log-file=%s' % logdir, '-e', 'ssh', '-i', '/Users/fanta4/.ssh/id_rsa', typ, '-l', target])
File "/Users/fanta4/anaconda3/lib/python3.6/subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "/Users/fanta4/anaconda3/lib/python3.6/subprocess.py", line 1275, in _execute_child
restore_signals, start_new_session, preexec_fn)
TypeError: expected str, bytes or os.PathLike object, not list
Process finished with exit code 1
【问题讨论】:
-
你为什么将
logdir和target设为列表,而不是字符串?参数向量是 one 列表,该列表中的所有条目都必须是字符串;如果您开始在外部列表中嵌套其他列表,那么您所拥有的不再是可以直接传递给操作系统的execv系统调用系列的结构。 -
...也就是说,这里更大的问题是您实际上并没有包括您的精确错误,或生成该错误的代码。请参阅帮助中心中的minimal reproducible example 指南——如果我们没有实际错误,我们只是在猜测;如果我们没有生成错误的代码,我们就无法测试我们(或其他任何人)的答案。
-
感谢您的意见。我忽略了代码,因为我认为编写像我这样的代码通常不是最好的方法,有人可能会说 - 在使用这种复杂的方法解决 rsync 问题之前请使用模块 xy ......但无论如何,没问题我的代码,伙计们。
-
minimal reproducible example 准则要求最短 可运行代码。也就是说,可验证性很重要,但隔离问题也很重要;有关如何满足这两个标准的提示,请参阅sscce.org 上的“修剪技巧”。
-
...也就是说,查看代码——
target是一个列表。作为 argv 传递的列表需要有字符串,而不是其他列表,作为其成员。
标签: python python-3.x ssh subprocess rsync