【问题标题】:Execute command/script using different shell in SSH/Paramiko在 SSH/Paramiko 中使用不同的 shell 执行命令/脚本
【发布时间】:2018-12-04 05:58:07
【问题描述】:

我对 Linux 和 Paramiko 还很陌生,但我遇到的问题是,每当我尝试更改 shell 时,远程 Paramiko 会话就会挂起。

远程主机默认在/etc/csh 我正在运行各种脚本,有些需要csh,有些需要bash。我在csh 中运行的任何脚本都可以正常工作,因为默认情况下远程主机在csh 中。

要运行其他脚本,我需要在bash 中。 每当我尝试使用bash/bin/bash 更改外壳时,paramiko 连接都会挂起。我正在使用以下命令在连接之前验证 shell,并在尝试临时更改 shell 以查看什么有效,但什么都没有。这是使用 ParamikoPython 3.6.5注意:反之亦然;如果我默认将远程主机放在bash,它将无法切换到csh

ma​​in.py

connection = SSH.SSH(hostname, username, password)
connection.changeShell('echo $0 ; echo $shell; /bin/bash ; echo $shell ; echo $0')

这也被尝试为 bashchsh

SSH.py

class SSH:
    client = None

    def __init__(self, address, username, password):
        print("Login info sent.")
        print("Connecting to server.")
        self.client = client.SSHClient()    # Create a new SSH client
        self.client.set_missing_host_key_policy(client.AutoAddPolicy())
        self.client.connect(address, username=username,
                password=password, look_for_keys=False) # connect

    def changeShell(self, command):
        print("Sending your command")
        # Check in connection is made previously
        if (self.client):
            stdin, stdout, stderr = self.client.exec_command(command)
            while not stdout.channel.exit_status_ready():
                # Print stdout data when available
                if stdout.channel.recv_ready():
                    # Retrieve the first 1024 bytes
                    alldata = stdout.channel.recv(2048)
                    while stdout.channel.recv_ready():
                        # Retrieve the next 1024 bytes
                        alldata += stdout.channel.recv(2048)

                    # Print as string with utf8 encoding
                    print(str(alldata, "utf8"))

            stdin.close()
            stdout.close()
            stderr.close()

        else:
            print("Connection not opened.")

【问题讨论】:

    标签: python bash shell ssh paramiko


    【解决方案1】:

    您的问题与 Paramiko 无关。尝试将您的命令粘贴到 SSH 终端中 - 它也不起作用。


    语法aaa ; bbb 依次执行命令。在aaa 完成之前,bbb 不会被执行。同样,/bin/bash ; echo $shell 执行 bashecho 将在 bash 完成之前执行,它永远不会执行,因此挂起。

    你实际上不想执行echo after bash - 你想执行echo within bash

    如果您想在不同的 shell 中执行脚本/命令,您有以下三种选择:

    • 使用 shebang 在脚本本身中指定脚本所需的 shell - 这是脚本的正确方法。

      #!/bin/bash
      
    • 使用 shell 命令行执行脚本/命令:

      /bin/bash script.sh
      

      /bin/bash -c "command1 ; command2 ; ..."
      
    • 将要执行的脚本/命令写入 shell 输入,就像我在上一个问题中向您展示的那样:

      Pass input/variables to bash script over SSH using Python Paramiko

    【讨论】:

    • 感谢 martin 的回答 - 正如您所提到的,我直接在 SSH 中对其进行了测试。你是对的,正如你提到的,它仍然挂在bash 上。你提到了使用的想法;是一个接一个地执行,但我想在bash中执行。 connection.changeShell('echo $0 ; echo $shell; bash ; /bin/bash -c "echo $shell" ; /bin/bash -c "echo $0"')
    • 第三个选项就是这个意思吗?问题是因为这是 paramiko 我需要在一行中传递所有命令/参数。远程会话从csh 开始,我需要先更改为bash,然后再更改为source ./.bashrc,然后才能启动主机上的实际脚本。使用 shebang 无济于事,因为我遇到了 source ./.bashrc 的错误
    • 你可以做/bin/bash -c "source ./.bashrc ; ./script.sh"
    • 哈,我刚刚按照您所说的那样做了,而且效果很好!非常感谢!
    猜你喜欢
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 2016-12-20
    • 1970-01-01
    • 2014-11-24
    • 2018-11-15
    • 1970-01-01
    相关资源
    最近更新 更多