【问题标题】:paramiko ssh source ~/.bashrcparamiko ssh 源 ~/.bashrc
【发布时间】:2021-12-29 16:43:24
【问题描述】:

我需要在运行 ROS 的远程机器上自动化一些启动过程。为此,我尝试使用 paramiko 通过 ssh 登录远程机器并启动启动文件。

我遇到的问题是我的 ~/.bashrc 文件没有来源。

我可以获取源 /opt/ros/noetic/setup.bash 并让 roscore 工作,但我找不到任何启动文件,因为我的工作空间没有源:

command = 'source /opt/ros/noetic/setup.bash && roscore'

我的 bashrc 文件同时包含 source /opt/ros/noetic/setup.bash 和源代码 source /home/ben/catkin_ws/devel/setup.bash 但每当我像以前一样获取此文件时,我什至无法让 roscore 工作 -

command = 'source ~/.bashrc && roscore'

Connected to 192.168.XX.XX
bash: roscore: command not found

一个最小的工作示例 -

#! /usr/bin/env python3
import paramiko
import numpy as np
import os

class Paramiko():

    def __init__(self, hostname, username, password, port):
        self.hostname = hostname
        self.username = username
        self.password = password
        self.port = port
        paramiko.util.log_to_file("paramiko.log")

    
    
    def ExecuteCommand(self, command):
        try:
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(self.hostname, username = self.username, password = self.password)
            print("Connected to %s" % self.hostname)
        except paramiko.AuthenticationException:
            print("Failed to connect to %s due to wrong username/password" %self.hostname)
            exit(1)
        except Exception as e:
            print(e.message)    
            exit(2)

        try:
            stdin, stdout, stderr = ssh.exec_command(command)
        except Exception as e:
            print(e.message)

        err = ''.join(stderr.readlines())
        out = ''.join(stdout.readlines())
        final_output = str(out)+str(err)
        print(final_output)
    
        return final_output

def main():
    hostname = "192.168.XX.XX"
    username = "ben"
    password = "lol_nice_try"
    port = 22
    command = 'source ~/.bashrc && roslaunch some_package some_launchfile.launch'


    para = Paramiko(hostname, username, password, port)
    answer = para.ExecuteCommand(command)


if __name__ == "__main__":
    main()

我正在考虑使用 bash 脚本来执行此操作,或者可能使用 os.system 执行此操作,但这将是一个全新的开始,并且有它自己的问题。

对想法持开放态度。在做一些阅读时,我会相信 paramiko ssh 实际上不是登录会话?

我尝试在按照Problems with python interpertor after ssh with paramiko into a remote machine 调用 exec_command 时设置 try get_pty=true,但这没有任何作用。我什至不确定该选项实际上做了什么,因为 paramiko 文档似乎没有任何关于它的内容。

关于该线程的另一条评论说有一个专门的配置文件,但这不就是 ~/.bashrc 吗?

【问题讨论】:

    标签: python ssh ros paramiko


    【解决方案1】:

    不是原始问题的答案,但解决方法是使用 pexpect 和 pxssh -

    from pexpect import pxssh
    try:
        s = pxssh.pxssh()
        hostname = '192.168.XX.XX'
        username = 'ben'
        password = 'cmon_guy'
        s.login(hostname, username, password)
        s.sendline('roslaunch system_diagnostics system_diagnostics_example_node.launch') # run a command
        s.prompt()             # match the prompt
        print(s.after)        # print everything before the prompt. 
        s.logout()
    except pxssh.ExceptionPxssh as e:
        print("pxssh failed on login.")
        print(e)
    

    不太清楚如何让它在发送到终端时输出 ROS_INFO,而不关闭连接,但现在这是另一个问题。

    【讨论】:

      【解决方案2】:

      启动交互式会话后运行命令。

      修改如下命令:

      command = 'bash --login -c "roscore"'
      

      然后使用 paramiko 执行。

      来自man bash

      当 bash 作为交互式登录 shell 或作为 带有 --login 选项的非交互式 shell,它首先读取并 从执行命令 文件 /etc/profile,如果该文件存在。读取该文件后,它会在其中查找 ~/.bash_profile、~/.bash_login 和 ~/.profile 该命令,并读取 并从第一个存在且可读的命令中执行命令。 --noprofile 选项可以在 shell 是 开始抑制这个 行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-12
        • 2012-05-31
        • 1970-01-01
        • 2010-10-23
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多