def main(argv): ap = argparse.ArgumentParser() ap.add_argument("-f", default=0, type=int) ap.add_argument("-a", "--arg", action='append', default=[]) ap.add_argument("--log", help="Log file", type=argparse.FileType("w")) ns, rest = ap.parse_known_args(argv) if ns.log is not None: logging.basicConfig(level=logging.INFO, stream=ns.log) log = logging.getLogger(__name__) if ns.f is not None: readfd = int(ns.f) else: readfd = 0 # read form readfd (an os.pipe read end) until EOF indicating parent # closed the pipe (i.e. did exit) log.info("Blocking on read from fd: %d", readfd) c = os.read(readfd, 1) if c != b"": log.error("Unexpected content %r from parent", c) else: log.info("Parent closed fd; %d") if ns.arg: log.info("Starting new process with cmd: %r", ns.arg) p = sh.create_process( ns.arg, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) main.p = p return 0
def run_command(command, raise_on_fail=True, **kwargs): # type: (List[str], bool, Any) -> Tuple[int, List[AnyStr]] """ Run command in a subprocess. Return `process` return code and output once it completes. """ log.info("Running %s", " ".join(command)) if command[0] == "python": process = python_process(command[1:], **kwargs) else: process = create_process(command, **kwargs) output = [] while process.poll() is None: try: line = process.stdout.readline() except IOError as ex: if ex.errno != errno.EINTR: raise else: output.append(line) print(line, end="") # Read remaining output if any line = process.stdout.read() if line: output.append(line) print(line, end="") if process.returncode != 0: log.info("Command %s failed with %s", " ".join(command), process.returncode) log.debug("Output:\n%s", "\n".join(output)) if raise_on_fail: raise CommandFailed(command, process.returncode, output) return process.returncode, output