For my own amusement, I've cooked up a python script that allows me to use python for bash one-liners; Supply a python generator expression; and the script iterates over it. Here's the script:
DEFAULT_MODULES = ['os', 're', 'sys']
_g = {}
for m in DEFAULT_MODULES:
_g[m] = __import__(m)
import sys
sys.stdout.writelines(eval(sys.argv[1], _g))
And here's how you might use it.
$ groups | python pype.py '(l.upper() for l in sys.stdin)'
DBORNSIDE
$
For the intended use, it works perfectly!
But when I don't feed it with pipe and just invoke it directly, for instance: [emphasis added to show what I type]
$ python pype.py '("%r\n" % (l,) for l in sys.stdin)' fooEnter barEnter bazEnter Ctrl DCtrl D'foo\n' 'bar\n' 'baz\n' $
In order to stop accepting input and produce any output, I have to type either Enter - Ctrl D - Ctrl D or Ctrl D - Ctrl D - Ctrl D. This violates my expectations, that each line should be processed as entered, and that typing Ctrl D at any time will end the script. Where is the gap in my understanding?
EDIT: I've updated the interactive example to show that I'm not seeing the quoting wim describes in his answer, and some more examples too.
$ python pype.py '("%r\n" % (l,) for l in sys.stdin)' fooCtrl DCtrl DbarEnter Ctrl DCtrl D'foobar\n' $ python pype.py '("%r\n" % (l,) for l in sys.stdin)' fooCtrl VCtrl D^DbarEnter Ctrl DCtrl D'foo\x04bar\n' $