【问题标题】:File transmission between two computers via ssh两台电脑之间通过 ssh 传输文件
【发布时间】:2018-08-22 04:31:36
【问题描述】:

我有两台装有 linux 的计算机(让它们命名为 A 和 B)(两个 raspberry pi 3 )。 我需要从 B 获取文件并在 A 上查看。 所以我用 ssh 连接它们。

B代码文件包含:

import rospy
from clever import srv
rospy.init_node('telemetry')  
file = open("telemetry", "w+")
while True:
  get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry) 
  position = get_telemetry(frame_id='aruco_map')
  f.write(get_telemetry)

在这里调用一个 rospy 服务代理,然后编写
必要的信息到文件“遥测”中,我 在两个覆盆子上创建。这部分工作正常。

A 上的代码文件包含

import subprocess
while True:
  subprocess.call(["ssh","pi@B", "'cat telemetry'", ">", "telemetry"])

B 是树莓派 ip,pi 是登录名

但是当我在 A 上运行代码文件时,它显示“bash: cat telemetry: command not found” 我究竟做错了什么? 感谢您的帮助。

【问题讨论】:

  • 你试图在远程主机上运行程序cat telemetry,它显然不存在。要复制文件,请使用 scp,而不是 ssh。
  • 请注意,ssh 只是将其所有参数连接到一个命令中并在远程 shell 中调用它。 ['ssh', 'pi@B', 'cat telemetry >telemetry.copy']['ssh', 'pi@B', 'cat', 'telemetry', '>telemetry.copy'] 之间绝对没有任何区别。
  • ...相比之下,cat 将文件添加到自身将始终只删除文件,因为输出重定向发生在 之前 cat 的版本应该阅读甚至开始了!
  • ...更准确地说,您当前的代码等同于['ssh', 'pi@B', "'cat telemetry' > telemetry"]——> 仍然是ssh 的参数。如果您想知道与之等效的 shell 命令是什么样的,下面的 Python 将生成一个:import pipes; print(' '.join(pipes.quote(x) for x in ['ssh', 'pi@B', "'cat telemetry' > telemetry"]))
  • NB 您应该考虑使用 SFTP 来获取文件,而不是通过普通 SSH 的命令。

标签: python linux ssh


【解决方案1】:

当使用subprocess.call 时,您不需要添加额外的引号,因为空格不是分隔符。此外,由于本地不涉及 shell,使用> 的输出重定向不起作用。 > 将被发送到远程主机并远程运行。要将实际的本地命令重定向到文件,您必须通过传递名为 stdout 的参数来使用子进程 PIPE 输出捕获:

with open('telemetry', 'wb') as f:
    subprocess.call(["ssh", "pi@B", "cat telemetry"], stdout=f)

这应该可以解决您的问题并回答您的问题“我做错了什么?” - 但是,正如其他人在 cmets 中指出的那样,您应该考虑使用scpsshfs 甚至paramiko 会话,而不是运行远程cat 来复制文件。

【讨论】:

  • 涉及一个shell -- 一个由ssh 在远程端启动。因此,重定向根本不是小事——它的作用是在cat 可以读取之前截断telemetry 文件!
  • @CharlesDuffy 很好,为答案添加了说明。
【解决方案2】:

我可以建议使用 Python Fabric (HERE)。它很容易配置。您只需建立一个连接调用一个函数:

from fabric import Connection
C = fabric.Connection('IP', user='pi', connect_kwargs={"password": "raspberry"})
result = C.put('myfile', remote='/home/pi')

我用它来做同样的事情。

【讨论】:

  • 谢谢,试试看