#!/usr/bin/python3 import os import sys #def no_eol(line): # if sys.line[-1:] == '\n': # return line[:-1] # else: # return line def usage(retval): sys.stderr.write('%s sets up multiple pipes and sends a copy of stdin to each of them\n' % sys.argv[0]) sys.stderr.write('\n') sys.stderr.write('Usage: %s [-f file_of_commands1] [-f file_of_commands2] ... [-f file_of_commandsn] [-h] [--] command1 command2 ... commandn\n' % sys.argv[0]) sys.stderr.write('\n') sys.stderr.write('-h shows this help message\n') sys.stderr.write('-- signals the end of options, so that commands may start with a "-"\n') sys.stderr.write('-f filename reads commands to set up pipes with, one command per line\n') sys.stderr.write('-q says to operate quietly\n') sys.stderr.write('commandx says to use commandx to set up a pipe\n') sys.exit(retval) commands = [] quiet = 0 class Pipe(object): def __init__(self, command): self.command = command self.pipe = os.popen(self.command, 'w') self.active = True def write(self, string): return self.pipe.write(string) while sys.argv[1:] and sys.argv[1][0:1] == '-': if sys.argv[1] == '--': del sys.argv[1] break elif sys.argv[1] == '-f' and sys.argv[2:]: filename = sys.argv[2] commands += open(filename, 'r').readlines() del sys.argv[1] elif sys.argv[1] == '-h': usage(0) elif sys.argv[1] == '-q': quiet = 1 else: sys.stderr.write('%s: Illegal option: %s\n' % (sys.argv[0], sys.argv[1])) usage(1) del sys.argv[1] commands += sys.argv[1:] # Bourne shell (or bash, as the case may be) doesn't care about leading and trailing whitespace anyway commands = [ command.strip() for command in commands ] pipes=[] if not quiet: sys.stderr.write('Creating %d pipes\n' % len(commands)) for index, command in enumerate(commands): if not quiet: sys.stderr.write('popening command %d: %s\n' % (index, command)) pipes.append(Pipe(command)) eof = False while True: at_least_one_pipe_remains=False buf = sys.stdin.read(1024 * 1024) if not buf: eof = True break for pipeno, pipe in enumerate(pipes): if pipe.active: try: pipe.write(buf) at_least_one_pipe_remains = True except: if not quiet: sys.stderr.write('terminated: %s\n' % commands[pipeno]) pipes[pipeno].active = False if not at_least_one_pipe_remains: break if eof: for pipe in pipes: if pipe.active: pipe.pipe.close()