multiSSH3 5.80__tar.gz → 5.82__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.

Potentially problematic release.


This version of multiSSH3 might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multiSSH3
3
- Version: 5.80
3
+ Version: 5.82
4
4
  Summary: Run commands on multiple hosts via SSH
5
5
  Home-page: https://github.com/yufei-pan/multiSSH3
6
6
  Author: Yufei Pan
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: multiSSH3
3
- Version: 5.80
3
+ Version: 5.82
4
4
  Summary: Run commands on multiple hosts via SSH
5
5
  Home-page: https://github.com/yufei-pan/multiSSH3
6
6
  Author: Yufei Pan
@@ -55,10 +55,10 @@ except AttributeError:
55
55
  # If neither is available, use a dummy decorator
56
56
  def cache_decorator(func):
57
57
  return func
58
- version = '5.80'
58
+ version = '5.82'
59
59
  VERSION = version
60
60
  __version__ = version
61
- COMMIT_DATE = '2025-07-09'
61
+ COMMIT_DATE = '2025-07-16'
62
62
 
63
63
  CONFIG_FILE_CHAIN = ['./multiSSH3.config.json',
64
64
  '~/multiSSH3.config.json',
@@ -934,7 +934,7 @@ def compact_hostnames(Hostnames,verify = True):
934
934
  if not __global_suppress_printout:
935
935
  eprint(f"Error compacting hostnames: {hostSet} -> {compact_hosts}")
936
936
  compact_hosts = hostSet
937
- return compact_hosts
937
+ return sorted(compact_hosts)
938
938
 
939
939
  #%% ------------ Expanding Hostnames ----------------
940
940
  @cache_decorator
@@ -2298,11 +2298,8 @@ def curses_print(stdscr, hosts, threads, min_char_len = DEFAULT_CURSES_MINIMUM_C
2298
2298
  #time.sleep(0.25)
2299
2299
 
2300
2300
  #%% ------------ Generate Output Block ----------------
2301
- def generate_output(hosts, usejson = False, greppable = False):
2302
- global __keyPressesIn
2303
- global __global_suppress_printout
2304
- global __encoding
2305
- if __global_suppress_printout:
2301
+ def generate_output(hosts, usejson = False, greppable = False,quiet = False,encoding = _encoding,keyPressesIn = [[]]):
2302
+ if quiet:
2306
2303
  # remove hosts with returncode 0
2307
2304
  hosts = [dict(host) for host in hosts if host.returncode != 0]
2308
2305
  if not hosts:
@@ -2334,8 +2331,8 @@ def generate_output(hosts, usejson = False, greppable = False):
2334
2331
  rtnList.append(['','','',''])
2335
2332
  rtnStr += pretty_format_table(rtnList)
2336
2333
  rtnStr += '*'*80+'\n'
2337
- if __keyPressesIn[-1]:
2338
- CMDsOut = [''.join(cmd).encode(encoding=_encoding,errors='backslashreplace').decode(encoding=_encoding,errors='backslashreplace').replace('\\n', '↵') for cmd in __keyPressesIn if cmd]
2334
+ if keyPressesIn[-1]:
2335
+ CMDsOut = [''.join(cmd).encode(encoding=encoding,errors='backslashreplace').decode(encoding=encoding,errors='backslashreplace').replace('\\n', '↵') for cmd in keyPressesIn if cmd]
2339
2336
  rtnStr += 'User Inputs: '+ '\nUser Inputs: '.join(CMDsOut)
2340
2337
  #rtnStr += '\n'
2341
2338
  else:
@@ -2355,25 +2352,23 @@ def generate_output(hosts, usejson = False, greppable = False):
2355
2352
  outputs.setdefault(hostPrintOut, set()).add(host['name'])
2356
2353
  rtnStr = ''
2357
2354
  for output, hostSet in outputs.items():
2358
- compact_hosts = sorted(compact_hostnames(hostSet))
2355
+ compact_hosts = compact_hostnames(hostSet)
2359
2356
  rtnStr += '*'*80+'\n'
2360
- if __global_suppress_printout:
2357
+ if quiet:
2361
2358
  rtnStr += f'Abnormal returncode produced by {",".join(compact_hosts)}:\n'
2362
2359
  rtnStr += output+'\n'
2363
2360
  else:
2364
2361
  rtnStr += f'These hosts: "{",".join(compact_hosts)}" have a response of:\n'
2365
2362
  rtnStr += output+'\n'
2366
- if not __global_suppress_printout or outputs:
2363
+ if not quiet or outputs:
2367
2364
  rtnStr += '*'*80+'\n'
2368
- if __keyPressesIn[-1]:
2369
- CMDsOut = [''.join(cmd).encode(encoding=_encoding,errors='backslashreplace').decode(encoding=_encoding,errors='backslashreplace').replace('\\n', '↵') for cmd in __keyPressesIn if cmd]
2370
- #rtnStr += f"Key presses: {''.join(__keyPressesIn).encode('unicode_escape').decode()}\n"
2371
- #rtnStr += f"Key presses: {__keyPressesIn}\n"
2365
+ if keyPressesIn[-1]:
2366
+ CMDsOut = [''.join(cmd).encode(encoding=encoding,errors='backslashreplace').decode(encoding=encoding,errors='backslashreplace').replace('\\n', '↵') for cmd in keyPressesIn if cmd]
2372
2367
  rtnStr += "User Inputs: \n "
2373
2368
  rtnStr += '\n '.join(CMDsOut)
2374
2369
  rtnStr += '\n'
2375
- __keyPressesIn[-1].clear()
2376
- if __global_suppress_printout and not outputs:
2370
+ keyPressesIn[-1].clear()
2371
+ if quiet and not outputs:
2377
2372
  rtnStr += 'Success'
2378
2373
  return rtnStr
2379
2374
 
@@ -2389,7 +2384,10 @@ def print_output(hosts,usejson = False,quiet = False,greppable = False):
2389
2384
  Returns:
2390
2385
  str: The pretty output generated
2391
2386
  '''
2392
- rtnStr = generate_output(hosts,usejson,greppable)
2387
+ global __global_suppress_printout
2388
+ global _encoding
2389
+ global __keyPressesIn
2390
+ rtnStr = generate_output(hosts,usejson,greppable,quiet=__global_suppress_printout,encoding=_encoding,keyPressesIn=__keyPressesIn)
2393
2391
  if not quiet:
2394
2392
  print(rtnStr)
2395
2393
  return rtnStr
@@ -2473,7 +2471,7 @@ def processRunOnHosts(timeout, password, max_connections, hosts, returnUnfinishe
2473
2471
  print_output(hosts,json,greppable=greppable)
2474
2472
 
2475
2473
  #%% ------------ Stringfy Block ----------------
2476
- @cache_decorator
2474
+
2477
2475
  def formHostStr(host) -> str:
2478
2476
  """
2479
2477
  Forms a comma-separated string of hosts.
@@ -2493,8 +2491,7 @@ def formHostStr(host) -> str:
2493
2491
  if 'local_shell' in host:
2494
2492
  host.remove('local_shell')
2495
2493
  host.add('localhost')
2496
- host = ','.join(host)
2497
- return host
2494
+ return ','.join(compact_hostnames(host))
2498
2495
 
2499
2496
  @cache_decorator
2500
2497
  def __formCommandArgStr(oneonone = DEFAULT_ONE_ON_ONE, timeout = DEFAULT_TIMEOUT,password = DEFAULT_PASSWORD,
@@ -2777,7 +2774,7 @@ def run_command_on_hosts(hosts = DEFAULT_HOSTS,commands = None,oneonone = DEFAUL
2777
2774
  skipHostsDic = expand_hostnames(skipHostStr.split(','))
2778
2775
  skipHostSet = set(skipHostsDic).union(skipHostsDic.values())
2779
2776
  if skipHostSet:
2780
- eprint(f"Skipping hosts: \"{' '.join(sorted(compact_hostnames(skipHostSet)))}\"")
2777
+ eprint(f"Skipping hosts: \"{' '.join(compact_hostnames(skipHostSet))}\"")
2781
2778
  if copy_id:
2782
2779
  if 'ssh-copy-id' in _binPaths:
2783
2780
  # we will copy the id to the hosts
@@ -3227,12 +3224,12 @@ def main():
3227
3224
  if __mainReturnCode > 0:
3228
3225
  if not __global_suppress_printout:
3229
3226
  eprint(f'Complete. Failed hosts (Return Code not 0) count: {__mainReturnCode}')
3230
- eprint(f'failed_hosts: {",".join(sorted(compact_hostnames(__failedHosts)))}')
3227
+ eprint(f'failed_hosts: {",".join(compact_hostnames(__failedHosts))}')
3231
3228
  else:
3232
3229
  if not __global_suppress_printout: eprint('Complete. All hosts returned 0.')
3233
3230
 
3234
3231
  if args.success_hosts and not __global_suppress_printout:
3235
- eprint(f'succeeded_hosts: {",".join(sorted(compact_hostnames(succeededHosts)))}')
3232
+ eprint(f'succeeded_hosts: {",".join(compact_hostnames(succeededHosts))}')
3236
3233
 
3237
3234
  if threading.active_count() > 1 and not __global_suppress_printout:
3238
3235
  eprint(f'Remaining active thread: {threading.active_count()}')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes