{"id":19413097,"url":"https://github.com/joknarf/ssh-para","last_synced_at":"2025-12-29T14:27:42.264Z","repository":{"id":245809830,"uuid":"819255143","full_name":"joknarf/ssh-para","owner":"joknarf","description":"Parallel SSH jobs manager interactive CLI","archived":false,"fork":false,"pushed_at":"2024-09-14T09:06:18.000Z","size":81,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-15T12:37:50.437Z","etag":null,"topics":["admin-tools","command-line-tool","curses","parallel","parallel-ssh","remote","shell","ssh","tools"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joknarf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-24T06:37:07.000Z","updated_at":"2024-09-14T09:04:45.000Z","dependencies_parsed_at":"2024-06-24T09:46:58.583Z","dependency_job_id":"1a219d91-f0a9-4f5b-ad4b-e26f6de904a0","html_url":"https://github.com/joknarf/ssh-para","commit_stats":null,"previous_names":["joknarf/ssh-para"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fssh-para","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fssh-para/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fssh-para/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fssh-para/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joknarf","download_url":"https://codeload.github.com/joknarf/ssh-para/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223952568,"owners_count":17230915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin-tools","command-line-tool","curses","parallel","parallel-ssh","remote","shell","ssh","tools"],"created_at":"2024-11-10T12:30:45.846Z","updated_at":"2025-12-26T17:03:30.879Z","avatar_url":"https://github.com/joknarf.png","language":"Python","readme":"[![Joknarf Tools](https://img.shields.io/badge/Joknarf%20Tools-Visit-darkgreen?logo=github)](https://joknarf.github.io/joknarf-tools)\n[![Pypi version](https://img.shields.io/pypi/v/ssh-para.svg)](https://pypi.org/project/ssh-para/)\n[![example](https://github.com/joknarf/ssh-para/actions/workflows/python-publish.yml/badge.svg)](https://github.com/joknarf/ssh-para/actions)\n[![Licence](https://img.shields.io/badge/licence-MIT-blue.svg)](https://shields.io/)\n[![](https://pepy.tech/badge/ssh-para)](https://pepy.tech/project/ssh-para)\n[![Python versions](https://img.shields.io/badge/python-3.6+-blue.svg)](https://shields.io/)\n[![bash](https://img.shields.io/badge/OS-%20Windows%20|%20Linux%20|%20macOS%20...-blue.svg)]()\n\n\n\n# ssh-para\nParallel SSH jobs manager CLI (alternative to parallel-ssh)\n\n* POSIX/Linux/MacOS/Windows compatible (with openssh client installed)\n* Launch parallel ssh jobs/scripts on remote hosts, with interactive display of the running commands outputs\n* Keep all output in log files\n* Interactive pause/resume/abort jobs, kill stuck ssh connection interactively.\n\nTake a look at [run-para](https://github.com/joknarf/run-para) if you need to run parallel jobs parameterized\n\n![ssh-para3](https://github.com/joknarf/ssh-para/assets/10117818/aef84de2-d15c-44f6-b6ff-74dc5f6f7b08)\n\n\n## installation\n```shell\npip install ssh-para\n```\nBy default, `ssh-para` uses Nerd Fonts glyphs, modern terminals can now render the glyphs without installing specific font (the symbols can be overridden with SSHP_SYM_* environment variables, see below)\n\n## quick start\n\n```\nRun command on multiple hosts:\n$ ssh-para -H host1 host2 host3 -- echo connection ok\nReview last run results:\n$ ssh-para -l\nReview hosts statuses for last run:\n$ ssh-para -L *.status\nView failed hosts list:\n$ ssh-para -L failed.status\nShow output of command on all hosts:\n$ ssh-para -L *.out\nShow output of command for failed hosts:\n$ ssh-para -L *.failed\nShow output of command for host1:\n$ ssh-para -L host1.out\n```\n\n## usage\n```\nssh-para -h\n```\n```\nusage: ssh-para [-h] [-V] [-j JOB] [-d DIRLOG] [-m MAXDOTS] [-p PARALLEL] [-t TIMEOUT] [-r] [-v] [-D DELAY]\n                [-f HOSTSFILE | -H HOSTS [HOSTS ...] | -C {bash,zsh,powershell} | -l | -L LOGS [LOGS ...]] [-s SCRIPT]\n                [-a ARGS [ARGS ...]]\n                [ssh_args ...]\n\nssh-para v1.ssh-para.dev\n\npositional arguments:\n  ssh_args\n\noptions:\n  -h, --help            show this help message and exit\n  -V, --version         ssh-para version\n  -j JOB, --job JOB     Job name added subdir to dirlog\n  -d DIRLOG, --dirlog DIRLOG\n                        directory for ouput log files (default: ~/.ssh-para)\n  -m MAXDOTS, --maxdots MAXDOTS\n                        hostname domain displaylevel (default:1 =\u003e short hostname, -1 =\u003e fqdn)\n  -p PARALLEL, --parallel PARALLEL\n                        parallelism (default 4)\n  -t TIMEOUT, --timeout TIMEOUT\n                        timeout of each job\n  -r, --resolve         resolve fqdn in SSHP_DOMAINS\n  -v, --verbose         verbose display (fqdn + line for last output)\n  -D DELAY, --delay DELAY\n                        initial delay in seconds between ssh commands (default=0.3s)\n  -f HOSTSFILE, --hostsfile HOSTSFILE\n                        hosts list file\n  -H HOSTS [HOSTS ...], --hosts HOSTS [HOSTS ...]\n                        hosts list\n  -C {bash,zsh,powershell}, --completion {bash,zsh,powershell}\n                        autocompletion shell code to source\n  -l, --list            list ssh-para results/log directories\n  -L LOGS [LOGS ...], --logs LOGS [LOGS ...]\n                        get latest/current ssh-para run logs\n                        -L[\u003crunid\u003e/]*.out          : all hosts outputs\n                        -L[\u003crunid\u003e/]\u003chost\u003e.out     : command output of host\n                        -L[\u003crunid\u003e/]*.\u003cstatus\u003e     : command output of hosts \u003cstatus\u003e\n                        -L[\u003crunid\u003e/]*.status       : hosts lists with status\n                        -L[\u003crunid\u003e/]\u003cstatus\u003e.status: \u003cstatus\u003e hosts list\n                        -L[\u003crunid\u003e/]hosts.list     : list of hosts used to connect (resolved if -r)\n                        default \u003crunid\u003e is latest ssh-para run (use -j \u003cjob\u003e -d \u003cdir\u003e to access logs if used for run)\n                        \u003cstatus\u003e: [success,failed,timeout,killed,aborted]\n  -s SCRIPT, --script SCRIPT\n                        script to execute\n  -a ARGS [ARGS ...], --args ARGS [ARGS ...]\n                        script arguments\n```    \nDuring run, use :\n\n* k: to kill ssh command held by a thread (but remote command can still be running on remote host)\n* p: pause all remaining jobs to be scheduled\n* r: resume scheduling of jobs\n* a: abort all remaining jobs\n* ctrl-c: stop all/exit (but remote commands launched by ssh can still be running on remote servers)\n\nEnvironment variables:\n\n* SSHP_OPTS: ssh default options (Eg: \"-F /home/user/.ssh/myconfig\")\n* SSHP_DOMAINS: dns domains to search when short hostname given (with -r/--resolve option)\n* SSHP_SYM_BEG: Symbol character for begin decorative (default: \"\\ue0b4\")\n* SSHP_SYM_END: Symbol character for end decorative (default: \"\\ue0b6\")\n* SSHP_SYM_PROG: Symbol character for progress bar fill (default: \"\\u25a0\")\n* SSHP_SYM_RES: Symbol character before ssh output line (default: \"\\u25b6\")\n\nActivate autocompletion:\n\n* `. \u003c(ssh-para -C bash)`\n* `ssh-para -C powershell | Out-String | Invoke-Expression`\n\n## Example\n\nPatch redhat family hosts:\n```shell\nssh-para -p 20 -f hostlist.txt -- 'sudo yum update -y;sudo shutdown -r +1'\n```\nUse specific ssh options / config (everything after `--` will be passed to ssh command as is):\n```shell\nssh-para -p 20 -H host1 host2 -- -F ~/.ssh/myconfig echo connect ok\n```\nLaunch local script with argument on remote hosts:\n```shell\nssh-para -p 20 -f hosts.txt -s ./myscript -a status\n```\nExtend limited resolv.conf search domains (try to resolve host in each domain, first resolved in the domain list is used as fqdn):\n```shell\nSSHP_DOMAINS=\"domain1.com domain2.com\" ssh-para -r -H host1 host2 -- echo connect ok\n```\n\n## Tips\n\n* ssh-para uses ssh BatchMode, no interactive password/passphrase will be asked, so you need to have a ssh authorized key to connect to servers (ssh-agent...)\n* you need to configure your ssh for StrictHostKeyChecking/UserKnownHostsFile if you need to connect to unknown servers\n* to connect as different user use ssh -l option or define everything in your ssh config file\n  * *you can use user@host as hostname but not if you need to resolve host (-r/--resolve)*\n* if you are using ssh ProxyJump server to reach hosts, you may need to tweak the sshd MaxStartups setting on the ssh Proxy server with high parallelism\n  * *when ssh-para starts, a delay of 0.3 seconds is applied between threads starting ssh jobs to avoid flooding, (can be tweaked with -D \u003cdelay\u003e)*\n* if you are using remote connexion to launch the ssh-para, use `screen` to launch ssh-para, as if you lose your connection, ssh-para will be still running and you can re-attach to `screen` to continue follow-up.\n* Be very carefull when launching massive commands on servers... Always first test on non production.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoknarf%2Fssh-para","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoknarf%2Fssh-para","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoknarf%2Fssh-para/lists"}