Created
March 20, 2016 08:15
-
-
Save mknecht/293166f0338e517b50d7 to your computer and use it in GitHub Desktop.
switched: A tool to recognize state changes in a command-line pipe.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
import os | |
import re | |
import sys | |
if sys.stdin.isatty(): | |
print("""Outputs a line if the input changed. | |
Usage: {scriptname} [<switch regex>] [<custom message prefix>] [-print0] | |
Example: | |
ping google.com | {scriptname} 'time=\d+' 'Internet is ' | xargs -0 -n 1 notify-send | |
# Notifies you with a Desktop notification | |
# when pings start failing or succeeding. | |
echo -e "hello\n\n\nx" | ./switch.py "" "Empty region is " | |
# Outputs a message if for every switch in empty to non-empty lines | |
# and vice versa. | |
Makes only sense as part of a pipe, hence if stdin is connected to a TTY | |
this message will be output. | |
The start state is OFF. | |
switch regex: Determines if input changes (match vs non-match). | |
Default: non-whitespace. | |
custom message prefix: On flipping the message is output that | |
made the switch change. If this prefix is given, it will be output instead | |
and the word “ON” and “OFF” will be appended. | |
-print0: Terminates lines with 0, for usage with xargs. See `man find`. | |
""".format(scriptname=sys.argv[0])) | |
sys.exit(0) | |
regex = sys.argv[1] if len(sys.argv) > 1 and sys.argv[1] else r"\S+" | |
messageprefix = sys.argv[2] if len(sys.argv) > 2 else None | |
pattern = re.compile(regex) | |
# Possible clash with a message prefix or regex … but don't care. | |
end = "\x00" if '-print0' in sys.argv else os.linesep | |
def print_on_change(line, state): | |
message = line if not messageprefix else (messageprefix + state) | |
print(message, end=end) | |
sys.stdout.flush() | |
def main(): | |
is_on = False | |
while True: | |
rawline = sys.stdin.readline() | |
if rawline == "": | |
sys.exit(0) | |
line = rawline.strip() | |
match = pattern.match(line) | |
if bool(match) ^ bool(is_on): | |
is_on = not is_on | |
print_on_change(line, "ON" if is_on else "OFF") | |
try: | |
main() | |
except KeyboardInterrupt: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment