0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Paramikoで多段ssh(入れ子)してコマンド実行するサンプル

Posted at

いきなりサンプルです。

import paramiko

def nested_ssh(address1, account1, address2, account2, commands, pre_command=None):
    """
    多段SSHを実行する関数
    
    :param address1: 最初のホストのアドレス
    :param account1: 最初のホストのアカウント情報 (username, password)
    :param address2: 2番目のホストのアドレス
    :param account2: 2番目のホストのアカウント情報 (username, password)
    :param commands: 実行するコマンドとその期待される出力のリスト
                     [{"command": "cmd1", "expected": "exp1"}, ...]
    :param pre_command: コマンド実行前に実行するコマンド(オプション)
    :return: コマンドの実行結果と期待値との比較結果のリスト
    """
    # 最初のホストに接続
    ssh1 = paramiko.SSHClient()
    ssh1.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh1.connect(address1, username=account1[0], password=account1[1])

    # 2番目のホストへのチャンネルを開く
    transport = ssh1.get_transport()
    dest_addr = (address2, 22)
    local_addr = ('127.0.0.1', 1234)
    channel = transport.open_channel("direct-tcpip", dest_addr, local_addr)

    # 2番目のホストに接続
    ssh2 = paramiko.SSHClient()
    ssh2.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh2.connect(address2, username=account2[0], password=account2[1], sock=channel)

    # pre_commandがある場合は実行
    if pre_command:
        stdin, stdout, stderr = ssh2.exec_command(pre_command)
        stdout.channel.recv_exit_status()  # コマンドの完了を待つ

    results = []
    # コマンドを順次実行し、結果を確認
    for cmd in commands:
        stdin, stdout, stderr = ssh2.exec_command(cmd["command"])
        output = stdout.read().decode().strip()
        expected = cmd["expected"].strip()
        match = output == expected
        results.append({
            "command": cmd["command"],
            "output": output,
            "expected": expected,
            "match": match
        })

    # 接続を閉じる
    ssh2.close()
    ssh1.close()

    return results

# 使用例
address1 = 'host1'
account1 = ('user1', 'pass1')
address2 = 'host2'
account2 = ('user2', 'pass2')
commands = [
    {"command": "pwd", "expected": "/home/user2"},
    {"command": "ls", "expected": "file1\nfile2\nfile3"},
    {"command": "echo 'Hello'", "expected": "Hello"}
]
pre_command = 'cd /some/directory'

results = nested_ssh(address1, account1, address2, account2, commands, pre_command)
for result in results:
    print(f"Command: {result['command']}")
    print(f"Output: {result['output']}")
    print(f"Expected: {result['expected']}")
    print(f"Match: {result['match']}")
    print("---")
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?