【问题标题】:Paramiko: calling "cd" command with exec_command does nothingParamiko:用 exec_command 调用“cd”命令什么都不做
【发布时间】:2023-06-13 16:48:01
【问题描述】:

我有以下使用 Paramiko 的程序:

#!/usr/bin/env python

import paramiko

hostname = '192.168.1.12'
port = 22
username = 'root'
password = 'whatl0ol'

if __name__ == "__main__":
    paramiko.util.log_to_file('paramiko.log')
    ssh = paramiko.SSHClient()
    ssh.load_system_host_keys()
    ssh.connect(hostname, port, username, password)             

while True:
      pick = raw_input("sshpy: ")
      stdin, stdout, stderr = ssh.exec_command(pick)
      print stdout.readlines() 

但是当我连接并尝试使用cd 时,它不起作用。我该如何解决这个问题?

【问题讨论】:

    标签: python ssh paramiko


    【解决方案1】:

    看起来您正在实现某种交互式程序,允许在服务器上执行一系列命令。

    SSHClient.exec_command 在单独的“exec”通道中执行每个命令。各个命令在它们自己的环境中运行。所以如果你执行cd 命令,它对后续命令完全没有影响。它们将再次从用户的主目录开始。

    如果要实现交互式 shell 会话,请使用 SSHClient.invoke_shell
    示例见how to interact with Paramiko's interactive shell session?

    另见Execute multiple commands in Paramiko so that commands are affected by their predecessors

    【讨论】:

      【解决方案2】:

      Paramiko SSH_Client 打开一个新会话并在该会话中执行命令,一旦命令执行完成,会话通道就会关闭。

      执行“cd”命令将在第一个会话中完成,稍后,对于下一个命令,会话将从主目录重新开始。

      如果您想保持会话,请使用 invoke_shell 进行交互式会话。

      【讨论】:

      • 启动一个交互式会话有点过分——对于简单的情况,exec_command('cd /foo && command_to_run_in_foo')(理想情况下使用shlex.quote()pipes.quote() 用于使目录名称安全地替换为解析为shell 命令)就足够了。
      【解决方案3】:

      我需要更改目录并运行可执行文件。我必须在一个命令中完成这一切。客户端单元是一台 Windows 10 机器。 windows 中的 cmd shell 太有问题了!命令不同。 ';'命令之间不起作用。您需要使用“&”。 cd d:/someDirectory 不起作用。你需要'/d'。 “密码”不起作用。此外, echo%cd% to pwd 不能可靠地工作。没有 pwd 参数的“cd”确实可以可靠地工作。我希望不工作的清单可以节省您的时间。这是它降落的地方。

      cmd = 'cd /d D:\someDirectory & SomeExecutable.exe 
            someParameter'
      ssh_stdin, ssh_stdout, ssh_stderr = 
      ssh.exec_command(cmd_1_to_execute)
      

      要检查目录更改,请使用以下命令:

      cmd = 'cd /d D:\someDirectory & cd'
      ssh_stdin, ssh_stdout, ssh_stderr = 
      ssh.exec_command(cmd_1_to_execute)
      
      output = ssh_stdout.readline()
      error = ssh_stderr.readline()
      print("output: " + output)
      print("error: " + error)
      

      【讨论】: