multiCMD 1.44__tar.gz → 1.46__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {multicmd-1.44 → multicmd-1.46}/PKG-INFO +1 -1
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/PKG-INFO +1 -1
- {multicmd-1.44 → multicmd-1.46}/multiCMD.py +36 -12
- {multicmd-1.44 → multicmd-1.46}/README.md +0 -0
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/SOURCES.txt +0 -0
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/dependency_links.txt +0 -0
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/entry_points.txt +0 -0
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/requires.txt +0 -0
- {multicmd-1.44 → multicmd-1.46}/multiCMD.egg-info/top_level.txt +0 -0
- {multicmd-1.44 → multicmd-1.46}/setup.cfg +0 -0
- {multicmd-1.44 → multicmd-1.46}/setup.py +0 -0
|
@@ -20,11 +20,12 @@ import subprocess
|
|
|
20
20
|
import sys
|
|
21
21
|
import threading
|
|
22
22
|
import time
|
|
23
|
+
from pprint import pformat
|
|
23
24
|
|
|
24
25
|
#%% global vars
|
|
25
|
-
version = '1.
|
|
26
|
+
version = '1.46'
|
|
26
27
|
__version__ = version
|
|
27
|
-
COMMIT_DATE = '2026-
|
|
28
|
+
COMMIT_DATE = '2026-03-05'
|
|
28
29
|
__running_threads = set()
|
|
29
30
|
__variables = {}
|
|
30
31
|
|
|
@@ -45,16 +46,29 @@ class Task:
|
|
|
45
46
|
self.stderr = []
|
|
46
47
|
self.thread = None
|
|
47
48
|
self.stop = False
|
|
49
|
+
|
|
48
50
|
def __iter__(self):
|
|
49
|
-
|
|
51
|
+
yield from (
|
|
52
|
+
('command', self.command),
|
|
53
|
+
('returncode', self.returncode),
|
|
54
|
+
('stdout', self.stdout),
|
|
55
|
+
('stderr', self.stderr)
|
|
56
|
+
)
|
|
57
|
+
|
|
50
58
|
def __repr__(self):
|
|
51
|
-
return f
|
|
59
|
+
return f"""Task(command={pformat(self.command)},
|
|
60
|
+
returncode={self.returncode!r},
|
|
61
|
+
stdout=
|
|
62
|
+
{pformat(self.stdout)},
|
|
63
|
+
stderr=
|
|
64
|
+
{pformat(self.stderr)},
|
|
65
|
+
stop={self.stop!r})"""
|
|
66
|
+
|
|
52
67
|
def __str__(self):
|
|
53
|
-
return
|
|
68
|
+
return pformat(dict(self))
|
|
69
|
+
|
|
54
70
|
def is_alive(self):
|
|
55
|
-
|
|
56
|
-
return self.thread.is_alive()
|
|
57
|
-
return False
|
|
71
|
+
return self.thread is not None and self.thread.is_alive()
|
|
58
72
|
|
|
59
73
|
class AsyncExecutor:
|
|
60
74
|
def __init__(self, max_threads=1,semaphore=...,timeout=0,quiet=True,dry_run=False,parse=False):
|
|
@@ -575,7 +589,8 @@ def ping(hosts,timeout=1,max_threads=0,quiet=True,dry_run=False,with_stdErr=Fals
|
|
|
575
589
|
return results
|
|
576
590
|
|
|
577
591
|
def run_command(command, timeout=0,max_threads=1,quiet=False,dry_run=False,with_stdErr=False,
|
|
578
|
-
return_code_only=False,return_object=False,wait_for_return=True, sem = None
|
|
592
|
+
return_code_only=False,return_object=False,wait_for_return=True, sem = None,
|
|
593
|
+
use_sudo = ..., raise_error = False):
|
|
579
594
|
'''
|
|
580
595
|
Run a command
|
|
581
596
|
|
|
@@ -590,17 +605,20 @@ def run_command(command, timeout=0,max_threads=1,quiet=False,dry_run=False,with_
|
|
|
590
605
|
return_object: Whether to return the Task object
|
|
591
606
|
wait_for_return: Whether to wait for the return of the command
|
|
592
607
|
sem: The semaphore to use for threading
|
|
608
|
+
use_sudo: Whether to use sudo for commands
|
|
609
|
+
raise_error: Whether to raise an error if the command fails
|
|
593
610
|
|
|
594
611
|
@returns:
|
|
595
612
|
None | int | list[str] | Task: The output of the command
|
|
596
613
|
'''
|
|
597
614
|
return run_commands(commands=[command], timeout=timeout, max_threads=max_threads, quiet=quiet,
|
|
598
615
|
dry_run=dry_run, with_stdErr=with_stdErr, return_code_only=return_code_only,
|
|
599
|
-
return_object=return_object,parse=False,wait_for_return=wait_for_return,sem=sem
|
|
616
|
+
return_object=return_object,parse=False,wait_for_return=wait_for_return,sem=sem,
|
|
617
|
+
use_sudo=use_sudo, raise_error=raise_error)[0]
|
|
600
618
|
|
|
601
619
|
def run_commands(commands, timeout=0,max_threads=1,quiet=False,dry_run=False,with_stdErr=False,
|
|
602
620
|
return_code_only=False,return_object=False, parse = False, wait_for_return = True,
|
|
603
|
-
sem : threading.Semaphore = None, use_sudo
|
|
621
|
+
sem : threading.Semaphore = None, use_sudo=..., raise_error = False):
|
|
604
622
|
'''
|
|
605
623
|
Run multiple commands in parallel
|
|
606
624
|
|
|
@@ -616,9 +634,11 @@ def run_commands(commands, timeout=0,max_threads=1,quiet=False,dry_run=False,wit
|
|
|
616
634
|
parse: Whether to parse ranged input
|
|
617
635
|
wait_for_return: Whether to wait for the return of the commands
|
|
618
636
|
sem: The semaphore to use for threading
|
|
637
|
+
use_sudo: Whether to use sudo for commands
|
|
638
|
+
raise_error: Whether to raise an error if the command fails
|
|
619
639
|
|
|
620
640
|
@returns:
|
|
621
|
-
list: The output of the commands ( list[None] | list[int] | list[list[str]] | list[Task] )
|
|
641
|
+
list: The output of the commands ( list[None] | list[int] | list[list[str]] | list[Task] | None )
|
|
622
642
|
'''
|
|
623
643
|
global USE_SUDO
|
|
624
644
|
global SUDO_PATH
|
|
@@ -654,6 +674,10 @@ def run_commands(commands, timeout=0,max_threads=1,quiet=False,dry_run=False,wit
|
|
|
654
674
|
for task in tasks:
|
|
655
675
|
__run_command(task,sem,timeout,quiet,dry_run,identity=None)
|
|
656
676
|
# return the only the output for the tasks
|
|
677
|
+
if raise_error:
|
|
678
|
+
errors = [task for task in tasks if task.returncode != 0]
|
|
679
|
+
if errors:
|
|
680
|
+
raise Exception(f"Commands failed: {pformat(errors)}")
|
|
657
681
|
if return_code_only:
|
|
658
682
|
return [task.returncode for task in tasks]
|
|
659
683
|
elif return_object:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|