Compare commits
	
		
			No commits in common. "105839d8cfabc4e5250f1922868d009a242304e4" and "988a4aac4c00ae0f7512ccb0697a520bb1ec9fc9" have entirely different histories.
		
	
	
		
			105839d8cf
			...
			988a4aac4c
		
	
		
					 2 changed files with 8 additions and 61 deletions
				
			
		
							
								
								
									
										54
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								README.md
									
										
									
									
									
								
							| 
						 | 
					@ -1,54 +0,0 @@
 | 
				
			||||||
# impatient
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A general purpose utility for estimating when a task will complete
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Overview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`impatient` is sort of like `pv` for tasks where you can't insert
 | 
					 | 
				
			||||||
extra commands into a pipeline, and sort of like `progress` for tasks
 | 
					 | 
				
			||||||
that aren't reading/writing a specific file on the local system.  If
 | 
					 | 
				
			||||||
you give it any shell command that outputs a number (possibly with a
 | 
					 | 
				
			||||||
K/M/G/T suffix), it will repeatedly run the command and show you how
 | 
					 | 
				
			||||||
fast that number is changing.  If you give it the expected final value
 | 
					 | 
				
			||||||
of the number, it'll also estimate how much longer you have to wait.
 | 
					 | 
				
			||||||
It also has a specific option for tracking the total size of a
 | 
					 | 
				
			||||||
file or directory as given by `du`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For example, here's `impatient` tracking an in-progress `zfs send` to
 | 
					 | 
				
			||||||
a remote machine:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
$ impatient -f "$(zfs list -pH -o used pool/home)" -c 'ssh remote-server zfs list -pH -o used remote-pool/backups/pool/home' -i 60
 | 
					 | 
				
			||||||
109.8G - 2.8M/s - 263.7G total - 41.6% complete - 15h03m remaining - ETA 2021-11-23 11:34
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Note that `-f` is given the value output by `zfs list`; we could
 | 
					 | 
				
			||||||
give it a number directly, this just simplifies things in this
 | 
					 | 
				
			||||||
particular scenario.  The `-p` flag for `zfs list` isn't strictly
 | 
					 | 
				
			||||||
necessary, `impatient` can parse values like `50.7G`, but
 | 
					 | 
				
			||||||
using the exact byte value provides more precision.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`-c`, on the other hand, is given a quoted string containing a
 | 
					 | 
				
			||||||
command, which will output the current progress value each time it's
 | 
					 | 
				
			||||||
run. The command given to `-c` can be an arbitrary shell one-liner,
 | 
					 | 
				
			||||||
use responsibly.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Usage
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
usage: impatient [-h] [-f FINAL] [-i INTERVAL] [-w WINDOW] (-p PATH | -c COMMAND)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Display progress and time estimates for arbitrary tasks
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
optional arguments:
 | 
					 | 
				
			||||||
  -h, --help            show this help message and exit
 | 
					 | 
				
			||||||
  -f FINAL, --final FINAL
 | 
					 | 
				
			||||||
                        Expected final size/value at completion, optionally with a K/M/G/T suffix
 | 
					 | 
				
			||||||
  -i INTERVAL, --interval INTERVAL
 | 
					 | 
				
			||||||
                        Interval in seconds between samples (default 10)
 | 
					 | 
				
			||||||
  -w WINDOW, --window WINDOW
 | 
					 | 
				
			||||||
                        Number of samples to keep for the sliding window (default 100)
 | 
					 | 
				
			||||||
  -p PATH, --path PATH  Track total disk usage of a given path
 | 
					 | 
				
			||||||
  -c COMMAND, --command COMMAND
 | 
					 | 
				
			||||||
                        Track value returned by a shell command; this should return a single number, optionally with a K/M/G/T suffix
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
							
								
								
									
										15
									
								
								impatient
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								impatient
									
										
									
									
									
								
							| 
						 | 
					@ -6,15 +6,16 @@ import subprocess
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WINDOW_SIZE = 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SUFFIXES = 'KMGT'
 | 
					SUFFIXES = 'KMGT'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
parser = argparse.ArgumentParser(description='Display progress and time estimates for arbitrary tasks')
 | 
					parser = argparse.ArgumentParser(description='Display progress and time estimates for arbitrary tasks')
 | 
				
			||||||
parser.add_argument('-f', '--final', type=str, help='Expected final size/value at completion, optionally with a K/M/G/T suffix')
 | 
					parser.add_argument('-f', '--final', type=str, help='Expected final size/value at completion.')
 | 
				
			||||||
parser.add_argument('-i', '--interval', type=int, default=10, help='Interval in seconds between samples (default 10)')
 | 
					parser.add_argument('-i', '--interval', type=int, default=10, help='Interval in seconds between samples (default 10)')
 | 
				
			||||||
parser.add_argument('-w', '--window', type=int, default=100, help='Number of samples to keep for the sliding window (default 100)')
 | 
					 | 
				
			||||||
tracker_types = parser.add_mutually_exclusive_group(required=True)
 | 
					tracker_types = parser.add_mutually_exclusive_group(required=True)
 | 
				
			||||||
tracker_types.add_argument('-p', '--path', type=str, help='Track total disk usage of a given path')
 | 
					tracker_types.add_argument('-p', '--path', type=str, help='Track total disk usage of a given path')
 | 
				
			||||||
tracker_types.add_argument('-c', '--command', type=str, help='Track value returned by a shell command; this should return a single number, optionally with a K/M/G/T suffix')
 | 
					tracker_types.add_argument('-c', '--command', type=str, help='Track value returned by a shell command; this should return a single number, optionally followed by K/M/G/T')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
args = parser.parse_args()
 | 
					args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,9 +23,9 @@ def parse_value(v):
 | 
				
			||||||
    suffix = v[-1].upper()
 | 
					    suffix = v[-1].upper()
 | 
				
			||||||
    if suffix in SUFFIXES:
 | 
					    if suffix in SUFFIXES:
 | 
				
			||||||
        exponent = 3*(SUFFIXES.find(suffix)+1)
 | 
					        exponent = 3*(SUFFIXES.find(suffix)+1)
 | 
				
			||||||
        return float(v[:-1])*(10**exponent)
 | 
					        return int(v[:-1])*(10**exponent)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return float(v)
 | 
					        return int(v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def display_value(v):
 | 
					def display_value(v):
 | 
				
			||||||
    suffix = ''
 | 
					    suffix = ''
 | 
				
			||||||
| 
						 | 
					@ -66,8 +67,8 @@ while True:
 | 
				
			||||||
    samples.append(current)
 | 
					    samples.append(current)
 | 
				
			||||||
    if len(samples) < 2:
 | 
					    if len(samples) < 2:
 | 
				
			||||||
        continue
 | 
					        continue
 | 
				
			||||||
    if len(samples) > args.window:
 | 
					    if len(samples) > WINDOW_SIZE:
 | 
				
			||||||
        samples = samples[-args.window:]
 | 
					        samples = samples[-WINDOW_SIZE:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rate = (current - samples[0])/((len(samples)-1)*args.interval)
 | 
					    rate = (current - samples[0])/((len(samples)-1)*args.interval)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue