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 [email protected] -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 [email protected] -p 2224 for one (1) and the same again for the other connection.

ssh [email protected] -p 2224 "command1 && command2" #executes a remote command.

To send a local file:scp -p 2224 local_file [email protected]:/remote/directory

Olaf
  • 1
  • 2
  • can i do `ssh [email protected] -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", "[email protected]", "-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", "[email protected]", "-p", port, cmds],
            capture_output=True, text=True, check=True)
tripleee
  • 175,061
  • 34
  • 275
  • 318