Выполнить команду / скрипт, используя другую оболочку в SSH / Paramiko

1

Я новичок в Linux и Paramiko, но проблема, с которой я сталкиваюсь, - это когда я пытаюсь изменить оболочку, которую удалит сеанс удаленного Pariko.

Удаленный хост находится в /etc/csh по умолчанию. Я запускаю различные скрипты, некоторые требуют csh а другие требуют bash. Любой из моих скриптов, работающих в csh работает должным образом, поскольку удаленный хост по умолчанию находится в csh.

Чтобы запустить другие скрипты, мне нужно быть в bash. Всякий раз, когда я пытаюсь изменить оболочку с помощью bash или /bin/bash paramiko, соединение просто зависает. Я использую следующую команду для проверки оболочек перед подключением и после попытки временно изменить оболочку, чтобы увидеть, что работает, но ничего не имеет. Это использует Paramiko и Python 3.6.5. Примечание: это также не работает наоборот; если я поместил удаленный хост в bash по умолчанию, он не сможет переключиться на csh

main.py

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

Это также было проверено как просто bash и chsh

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.")
Теги:
ssh
paramiko

1 ответ

1
Лучший ответ

Ваш вопрос не имеет ничего общего с Парамико. Попробуйте вставить свою команду в терминал SSH - он тоже не будет работать.


Синтаксис aaa; bbb aaa; bbb выполняет команды один за другим. bbb не будет выполняться до тех пор, пока не закончится aaa. Аналогично, /bin/bash; echo $shell /bin/bash; echo $shell выполняет bash и echo не будет выполняться до тех пор, пока bash не завершится, что он никогда не сделает, поэтому зависает.

Вы действительно не хотите выполнять echo после bash - вы хотите выполнить echo в bash.

Если вы хотите выполнить скрипт/команды в другой оболочке, у вас есть три варианта:

  • Укажите оболочку, которая требуется скрипту в скрипте, используя shebang. Это правильный способ для скриптов.

    #!/bin/bash
    
  • Выполните скрипт/команды с помощью командной строки оболочки:

    /bin/bash script.sh
    

    или же

    /bin/bash -c "command1 ; command2 ; ..."
    
  • Напишите сценарий/команду, которая будет выполнена для ввода оболочки, как я показал вам в вашем предыдущем вопросе:

    Передать ввод/переменные в скрипт bash через SSH с помощью Python Paramiko

  • 0
    Спасибо за ответ, Мартин - я продолжил и проверил его непосредственно в SSH, как вы упомянули. Вы правы, это все еще висит на bash как вы упоминали. Вы упомянули идею использования; это выполнить один за другим, но я хочу выполнить WITHIN Bash. connection.changeShell('echo $0 ; echo $shell; bash ; /bin/bash -c "echo $shell" ; /bin/bash -c "echo $0"')
  • 0
    Это то, что вы подразумеваете под третьим вариантом? Проблема в том, что это paramiko, мне нужно передать все команды / аргументы в одной строке. Удаленный сеанс начинается в csh и мне нужно перейти на bash а затем на source ./.bashrc прежде чем запускать скрипт, который находится на хосте. Использование shebang не помогло бы, так как у меня ошибка с source ./.bashrc
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню