0

i want to send text files via ssh to 2 servers. My servers have the same name and ip but different ports.

I can do it with 1 server but not with 2 how do I do this (normally there should be a port next to -p).

import subprocess

with open("hosts_and_ports.txt") as hp_fh:
    hp_contents = hp_fh.readlines()
    for hp_pair in hp_contents: 
        with open("commands.txt") as fh:
            completed = subprocess.run("ssh ubuntussh@127.0.0.1 -p ", capture_output=True, text=True, shell=True, stdin=hp_pair)

My text file hosts_and_ports.txt contains the ports of my servers

2222;
2224;
exit;

My text file commands.txt contains the files I want to forward via ssh

touch demofile1.txt;
touch demofile2.txt;
exit;
KingVince
  • 23
  • 5

2 Answers2

0

ssh is always only to one (1) single port only. In your scenario you need to define the port with -p 2222 OR -p 2224 e.g. `ssh user@192.168.1.1 -p 2224 for one (1) and the same again for the other connection.

ssh user@192.168.1.1 -p 2224 "command1 && command2" #executes a remote command.

To send a local file:scp -p 2224 local_file user@192.168.1.1:/remote/directory

Olaf
  • 1
  • 2
  • can i do `ssh ubuntussh@127.0.0.1 -p 2222 and 2224`? – KingVince Sep 07 '20 at 13:28
  • No, there is no sane way to run multiple sessions in a single command. What would you do in an interactive session if one of the servers says "command not found" and the other says "ha ha, removing all your files (check for aliases next time)"? – tripleee Sep 07 '20 at 13:45
0

Your attempt obviously doesn't pass in the port number at all.

As a simplification, I'll assume that you can remove the silly exit; line from both files, and just keep on reading as long as there are lines in both files. Also, trim the semicolon from the end of each line; it is simply in the way. (It's not hard to ignore in the Python program, either, but why put such chaff in the file in the first place?)

import subprocess

with open("commands.txt") as cmd:
    cmds = cmd.readlines()

with open("hosts_and_ports.txt") as hp_fh:
    for line in hp_fh:
        port = line.rstrip('\n')
        for cmd in cmds:
            completed = subprocess.run(
                ["ssh", "ubuntussh@127.0.0.1", "-p", port, cmd],
                capture_output=True, text=True, check=True)

We don't need a shell here, and we are better off without it.

Actually probably also rename the file which only contains port numbers, as its name is currently misleading.

Tangentially, touch demofile1.txt demofile2.txt will create both files with a single remote SSH command. I'm guessing maybe you will have other commands you want to add to the file later on, so this runs all commands in the file on all the servers in the other file. Generally speaking, you will probably want to minimize the number of remote connections because there is a fair bit of overhead with each login ... so in fact it would make more sense to send the entire command.txt to each server in one go:

import subprocess

with open("commands.txt") as cmd:
    cmds = cmd.read()

with open("hosts_and_ports.txt") as hp_fh:
    for line in hp_fh:
        port = line.rstrip('\n')
        completed = subprocess.run(
            ["ssh", "ubuntussh@127.0.0.1", "-p", port, cmds],
            capture_output=True, text=True, check=True)
tripleee
  • 175,061
  • 34
  • 275
  • 318