forked from Imagelibrary/littlefs
This seems like a more fitting name now that this script has evolved
into more of a general purpose high-level CSV tool.
Unfortunately this does conflict with the standard csv module in Python,
breaking every script that imports csv (which is most of them).
Fortunately, Python is flexible enough to let us remove the current
directory before imports with a bit of an ugly hack:
# prevent local imports
__import__('sys').path.pop(0)
These scripts are intended to be standalone anyways, so this is probably
a good pattern to adopt.
78 lines
2.1 KiB
Python
Executable File
78 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# tee, but for pipes
|
|
#
|
|
# Example:
|
|
# ./scripts/tee.py in_pipe out_pipe1 out_pipe2
|
|
#
|
|
# Copyright (c) 2022, The littlefs authors.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
# prevent local imports
|
|
__import__('sys').path.pop(0)
|
|
|
|
import os
|
|
import io
|
|
import time
|
|
import sys
|
|
|
|
|
|
def openio(path, mode='r', buffering=-1):
|
|
# allow '-' for stdin/stdout
|
|
if path == '-':
|
|
if 'r' in mode:
|
|
return os.fdopen(os.dup(sys.stdin.fileno()), mode, buffering)
|
|
else:
|
|
return os.fdopen(os.dup(sys.stdout.fileno()), mode, buffering)
|
|
else:
|
|
return open(path, mode, buffering)
|
|
|
|
def main(in_path, out_paths, *, keep_open=False):
|
|
out_pipes = [openio(p, 'wb', 0) for p in out_paths]
|
|
try:
|
|
with openio(in_path, 'rb', 0) as f:
|
|
while True:
|
|
buf = f.read(io.DEFAULT_BUFFER_SIZE)
|
|
if not buf:
|
|
if not keep_open:
|
|
break
|
|
# don't just flood reads
|
|
time.sleep(0.1)
|
|
continue
|
|
|
|
for p in out_pipes:
|
|
try:
|
|
p.write(buf)
|
|
except BrokenPipeError:
|
|
pass
|
|
except FileNotFoundError as e:
|
|
print("error: file not found %r" % in_path,
|
|
file=sys.stderr)
|
|
sys.exit(-1)
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
import argparse
|
|
parser = argparse.ArgumentParser(
|
|
description="tee, but for pipes.",
|
|
allow_abbrev=False)
|
|
parser.add_argument(
|
|
'in_path',
|
|
help="Path to read from.")
|
|
parser.add_argument(
|
|
'out_paths',
|
|
nargs='+',
|
|
help="Path to write to.")
|
|
parser.add_argument(
|
|
'-k', '--keep-open',
|
|
action='store_true',
|
|
help="Reopen the pipe on EOF, useful when multiple "
|
|
"processes are writing.")
|
|
sys.exit(main(**{k: v
|
|
for k, v in vars(parser.parse_intermixed_args()).items()
|
|
if v is not None}))
|