-
-
Save mamaj/a7b378a5c969e3e32a9e4f9bceb0c5eb to your computer and use it in GitHub Desktop.
import subprocess | |
import os | |
from pathlib import Path | |
from typing import Union | |
class SshClient(): | |
""" Perform commands and copy files on ssh using subprocess | |
and native ssh client (OpenSSH). | |
""" | |
def __init__(self, | |
user: str, | |
remote: str, | |
key_path: Union[str, Path]) -> None: | |
""" | |
Args: | |
user (str): username for the remote | |
remote (str): remote host IP/DNS | |
key_path (str or pathlib.Path): path to .pem file | |
""" | |
self.user = user | |
self.remote = remote | |
self.key_path = str(key_path) | |
def cmd(self, | |
cmds: list[str], | |
check=True, | |
strict_host_key_checking=False, | |
**run_kwargs) -> subprocess.CompletedProcess: | |
"""runs commands consecutively, ensuring success of each | |
after calling the next command. | |
Args: | |
cmds (list[str]): list of commands to run. | |
strict_host_key_checking (bool, optional): Defaults to True. | |
""" | |
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no' | |
cmd = ' && '.join(cmds) | |
return subprocess.run( | |
[ | |
'ssh', | |
'-i', self.key_path, | |
'-o', f'StrictHostKeyChecking={strict_host_key_checking}', | |
'-o', 'UserKnownHostsFile=/dev/null', | |
'-o', 'LogLevel=ERROR', | |
f'{self.user}@{self.remote}', | |
cmd | |
], | |
check=check, | |
**run_kwargs | |
) | |
def scp(self, | |
sources: list[Union[str, bytes, os.PathLike]], | |
destination: Union[str, bytes, os.PathLike], | |
check=True, | |
strict_host_key_checking=False, | |
recursive=False, | |
**run_kwargs) -> subprocess.CompletedProcess: | |
"""Copies `srouce` file to remote `destination` using the | |
native `scp` command. | |
Args: | |
source (Union[str, bytes, os.PathLike]): List of source files path. | |
destination (Union[str, bytes, os.PathLike]): Destination path on remote. | |
""" | |
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no' | |
return subprocess.run( | |
list(filter(bool, [ | |
'scp', | |
'-i', self.key_path, | |
'-o', f'StrictHostKeyChecking={strict_host_key_checking}', | |
'-o', 'UserKnownHostsFile=/dev/null', | |
'-o', 'LogLevel=ERROR', | |
'-r' if recursive else '', | |
*map(str, sources), | |
# sources, | |
f'{self.user}@{self.remote}:{str(destination)}', | |
])), | |
check=check, | |
**run_kwargs | |
) | |
def validate(self): | |
return self.cmd([f'echo " "'], check=False).returncode == 0 | |
def ssh_connect_cmd(self) -> str: | |
return f'ssh -i {self.key_path} {self.user}@{self.remote}' | |
usage:
from ssh_utils import SshClient
client = SshClient(user='username', remote='remote_addr', key_path='/path/to/key.pem')
# run a list of commands
client.cmd(['mkdir ~/testdir', 'ls -la', 'echo done!'])
# copy files/dirs
client.scp('my_file.txt', '~/testdir')
Is there a way to pass in the user's password and not use the key ?
Not with the native ssh command. Probably need to install sshpass on the remote and modify client.cmd function accordingly.
Thanks
Thanks for this gist, I got the link to here from Stackoverflow.
I pretty much prefer your tiny SSH client code rather than importing an entire module just for running something remotely via ssh.
Well done!
For my project I removed the key_path
as I deploy the ssh key in the standard user directory.
Search Gists
Search...
All gists
Back to GitHub
@mamaj
mamaj/ssh-utils.py
Last active 2 months ago • Report abuse
Code
Revisions
10
Stars
5
Forks
1
Clone this repository at <script src="https://gist.github.com/mamaj/a7b378a5c969e3e32a9e4f9bceb0c5eb.js"></script>
Python: simple class to perform commands and copy files (scp) on ssh using subprocess and native ssh client (OpenSSH).
ssh-utils.py
import subprocess
import os
from pathlib import Path
from typing import Union
class SshClient():
""" Perform commands and copy files on ssh using subprocess
and native ssh client (OpenSSH).
"""
def __init__(self,
user: str,
remote: str,
key_path: Union[str, Path]) -> None:
"""
Args:
user (str): username for the remote
remote (str): remote host IP/DNS
key_path (str or pathlib.Path): path to .pem file
"""
self.user = user
self.remote = remote
self.key_path = str(key_path)
def cmd(self,
cmds: list[str],
check=True,
strict_host_key_checking=False,
**run_kwargs) -> subprocess.CompletedProcess:
"""runs commands consecutively, ensuring success of each
after calling the next command.
Args:
cmds (list[str]): list of commands to run.
strict_host_key_checking (bool, optional): Defaults to True.
"""
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no'
cmd = ' && '.join(cmds)
return subprocess.run(
[
'ssh',
'-i', self.key_path,
'-o', f'StrictHostKeyChecking={strict_host_key_checking}',
'-o', 'UserKnownHostsFile=/dev/null',
'-o', 'LogLevel=ERROR',
f'{self.user}@{self.remote}',
cmd
],
check=check,
**run_kwargs
)
def scp(self,
sources: list[Union[str, bytes, os.PathLike]],
destination: Union[str, bytes, os.PathLike],
check=True,
strict_host_key_checking=False,
recursive=False,
**run_kwargs) -> subprocess.CompletedProcess:
"""Copies `srouce` file to remote `destination` using the
native `scp` command.
Args:
source (Union[str, bytes, os.PathLike]): List of source files path.
destination (Union[str, bytes, os.PathLike]): Destination path on remote.
"""
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no'
return subprocess.run(
list(filter(bool, [
'scp',
'-i', self.key_path,
'-o', f'StrictHostKeyChecking={strict_host_key_checking}',
'-o', 'UserKnownHostsFile=/dev/null',
'-o', 'LogLevel=ERROR',
'-r' if recursive else '',
*map(str, sources),
# sources,
f'{self.user}@{self.remote}:{str(destination)}',
])),
check=check,
**run_kwargs
)
def validate(self):
return self.cmd([f'echo " "'], check=False).returncode == 0
def ssh_connect_cmd(self) -> str:
return f'ssh -i {self.key_path} {self.user}@{self.remote}'
@mamaj
Author
mamaj commented on Aug 25, 2022
Feedbacks are welcome!
@mamaj
Author
mamaj commented on Aug 25, 2022 •
usage:
from ssh_utils import SshClient
client = SshClient(user='username', remote='remote_addr', key_path='/path/to/key.pem')
run a list of commands
client.cmd(['mkdir ~/testdir', 'ls -la', 'echo done!'])
copy files/dirs
client.scp('my_file.txt', '~/testdir')
@linuxguy123
linuxguy123 commented on Jan 1, 2023
Is there a way to pass in the user's password and not use the key ?
@mamaj
Author
mamaj commented on Jan 2, 2023
Not with the native ssh command. Probably need to install sshpass on the remote and modify client.cmd function accordingly.
@linuxguy123
linuxguy123 commented on Jan 3, 2023
Thanks
@larsblumberg
larsblumberg commented on Dec 12, 2024 •
Thanks for this gist, I got the link to here from Stackoverflow.
I pretty much prefer your tiny SSH client code rather than importing an entire module just for running something remotely via ssh.
Well done!
For my project I removed the key_path as I deploy the ssh key in the standard user directory.
@istockmarket
Comment
Leave a comment
Footer
© 2025 GitHub, Inc.
Footer navigation
Terms
Privacy
Security
Status
Docs
Contact
Manage cookies
Do not share my personal information
Search Gists
Search...
All gists
Back to GitHub
@mamaj
mamaj/ssh-utils.py
Last active 2 months ago • Report abuse
Code
Revisions
10
Stars
5
Forks
1
Clone this repository at <script src="https://gist.github.com/mamaj/a7b378a5c969e3e32a9e4f9bceb0c5eb.js"></script>
Python: simple class to perform commands and copy files (scp) on ssh using subprocess and native ssh client (OpenSSH).
ssh-utils.py
import subprocess
import os
from pathlib import Path
from typing import Union
class SshClient():
""" Perform commands and copy files on ssh using subprocess
and native ssh client (OpenSSH).
"""
def __init__(self,
user: str,
remote: str,
key_path: Union[str, Path]) -> None:
"""
Args:
user (str): username for the remote
remote (str): remote host IP/DNS
key_path (str or pathlib.Path): path to .pem file
"""
self.user = user
self.remote = remote
self.key_path = str(key_path)
def cmd(self,
cmds: list[str],
check=True,
strict_host_key_checking=False,
**run_kwargs) -> subprocess.CompletedProcess:
"""runs commands consecutively, ensuring success of each
after calling the next command.
Args:
cmds (list[str]): list of commands to run.
strict_host_key_checking (bool, optional): Defaults to True.
"""
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no'
cmd = ' && '.join(cmds)
return subprocess.run(
[
'ssh',
'-i', self.key_path,
'-o', f'StrictHostKeyChecking={strict_host_key_checking}',
'-o', 'UserKnownHostsFile=/dev/null',
'-o', 'LogLevel=ERROR',
f'{self.user}@{self.remote}',
cmd
],
check=check,
**run_kwargs
)
def scp(self,
sources: list[Union[str, bytes, os.PathLike]],
destination: Union[str, bytes, os.PathLike],
check=True,
strict_host_key_checking=False,
recursive=False,
**run_kwargs) -> subprocess.CompletedProcess:
"""Copies `srouce` file to remote `destination` using the
native `scp` command.
Args:
source (Union[str, bytes, os.PathLike]): List of source files path.
destination (Union[str, bytes, os.PathLike]): Destination path on remote.
"""
strict_host_key_checking = 'yes' if strict_host_key_checking else 'no'
return subprocess.run(
list(filter(bool, [
'scp',
'-i', self.key_path,
'-o', f'StrictHostKeyChecking={strict_host_key_checking}',
'-o', 'UserKnownHostsFile=/dev/null',
'-o', 'LogLevel=ERROR',
'-r' if recursive else '',
*map(str, sources),
# sources,
f'{self.user}@{self.remote}:{str(destination)}',
])),
check=check,
**run_kwargs
)
def validate(self):
return self.cmd([f'echo " "'], check=False).returncode == 0
def ssh_connect_cmd(self) -> str:
return f'ssh -i {self.key_path} {self.user}@{self.remote}'
@mamaj
Author
mamaj commented on Aug 25, 2022
Feedbacks are welcome!
@mamaj
Author
mamaj commented on Aug 25, 2022 •
usage:
from ssh_utils import SshClient
client = SshClient(user='username', remote='remote_addr', key_path='/path/to/key.pem')
run a list of commands
client.cmd(['mkdir ~/testdir', 'ls -la', 'echo done!'])
copy files/dirs
client.scp('my_file.txt', '~/testdir')
@linuxguy123
linuxguy123 commented on Jan 1, 2023
Is there a way to pass in the user's password and not use the key ?
@mamaj
Author
mamaj commented on Jan 2, 2023
Not with the native ssh command. Probably need to install sshpass on the remote and modify client.cmd function accordingly.
@linuxguy123
linuxguy123 commented on Jan 3, 2023
Thanks
@larsblumberg
larsblumberg commented on Dec 12, 2024 •
Thanks for this gist, I got the link to here from Stackoverflow.
I pretty much prefer your tiny SSH client code rather than importing an entire module just for running something remotely via ssh.
Well done!
For my project I removed the key_path as I deploy the ssh key in the standard user directory.
@istockmarket
Comment
Leave a comment
Footer
© 2025 GitHub, Inc.
Footer navigation
Terms
Privacy
Security
Status
Docs
Contact
Manage cookies
Do not share my personal information
Feedbacks are welcome!