स्पष्ट रूप से यह लगभग Bad pipe filedescriptor when reading from stdin in python - Stack Overflow "का डुप्लिकेट है; हालांकि, मेरा मानना है कि यह मामला थोड़ा अधिक जटिल है (और यह विंडोज विशिष्ट नहीं है, क्योंकि उस धागे का निष्कर्ष था)।लिनक्स: पायथन में पाइप (एनसीआरएसईएस) स्क्रिप्ट, stdin और टर्मियो
मैं वर्तमान में पाइथन में एक साधारण स्क्रिप्ट के साथ प्रयोग करने की कोशिश कर रहा हूं: मैं स्क्रिप्ट में इनपुट आपूर्ति करना चाहता हूं - या तो कमांड लाइन तर्कों के माध्यम से; या इस स्क्रिप्ट के लिए एक स्ट्रिंग को 'पाइप' करके - और स्क्रिप्ट को curses
टर्मिनल इंटरफ़ेस का उपयोग करके इस इनपुट स्ट्रिंग को दिखाएं।
पूर्ण स्क्रिप्ट, जिसे testcurses.py
कहा जाता है, नीचे दिया गया है। समस्या यह है कि जब भी मैं वास्तविक पाइपिंग का प्रयास करता हूं, तो यह गड़बड़ हो जाता है, और curses
विंडो कभी नहीं दिखाती है। यहाँ एक टर्मिनल आउटपुट है:
## CASE 1: THROUGH COMMAND LINE ARGUMENT (arg being stdin):
##
$ ./testcurses.py -
['-'] 1
stdout/stdin (obj): <open file '<stdout>', mode 'w' at 0xb77dc078> <open file '<stdin>', mode 'r' at 0xb77dc020>
stdout/stdin (fn): 1 0
env(TERM): xterm xterm
stdin_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', ... '\x00']]
stdout_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', ... '\x00']]
opening -
obj <open file '<stdin>', mode 'r' at 0xb77dc020>
TYPING blabla HERE
wr TYPING blabla HERE
at end
before curses TYPING blabla HERE
#
# AT THIS POINT:
# in this case, curses window is shown, with the text 'TYPING blabla HERE'
# ################
## CASE 2: THROUGH PIPE
##
## NOTE I get the same output, even if I try syntax as in SO1057638, like:
## python -c "print 'TYPING blabla HERE'" | python testcurses.py -
##
$ echo "TYPING blabla HERE" | ./testcurses.py -
['-'] 1
stdout/stdin (obj): <open file '<stdout>', mode 'w' at 0xb774a078> <open file '<stdin>', mode 'r' at 0xb774a020>
stdout/stdin (fn): 1 0
env(TERM): xterm xterm
stdin_termios_attr <class 'termios.error'>::(22, 'Invalid argument')
stdout_termios_attr [27906, 5, 1215, 35387, 15, 15, ['\x03', '\x1c', '\x7f', '\x15', '\x04', '\x00', '\x01', '\xff', '\x11', '\x13', '\x1a', '\xff', '\x12', '\x0f', '\x17', '\x16', '\xff', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00']]
opening -
obj <open file '<stdin>', mode 'r' at 0xb774a020>
wr TYPING blabla HERE
at end
before curses TYPING blabla HERE
#
# AT THIS POINT:
# script simply exits, nothing is shown
# ################
जहां तक मैं देख सकता हूँ, मुद्दा है: - जब भी अजगर स्क्रिप्ट में हम पाइप तार, अजगर स्क्रिप्ट संदर्भ टर्मिनल करने के लिए stdin
और सूचनाओं की के रूप में खो देता है कि प्रतिस्थापित stdin
termios
संरचना अब और नहीं है - और stdin
अब टर्मिनल नहीं है, curses.initscr()
कुछ भी प्रस्तुत किए बिना तत्काल बाहर निकलता है।
तो, मेरी सवाल है - संक्षेप में: मैं किसी भी तरह प्राप्त कर सकते हैं, कि वाक्य रचना echo "blabla" | ./testcurses.py -
curses
में पाइप स्ट्रिंग दिखा समाप्त होता है? अधिक विशेष रूप से: क्या यह स्क्रिप्ट एक पाइथन स्क्रिप्ट से कॉलिंग टर्मिनल के stdin
के संदर्भ को पुनर्प्राप्त करना संभव है, भले ही यह स्क्रिप्ट "पाइप" हो रही हो?
किसी भी संकेत दिए गए के लिए अग्रिम धन्यवाद,
चीयर्स!
पुनश्च: testcurses.py
स्क्रिप्ट:
#!/usr/bin/env python
# http://www.tuxradar.com/content/code-project-build-ncurses-ui-python
# http://diveintopython.net/scripts_and_streams/stdin_stdout_stderr.html
# http://bytes.com/topic/python/answers/42283-curses-disable-readline-replace-stdin
#
# NOTE: press 'q' to exit curses - Ctrl-C will screw up yer terminal
# ./testcurses.py "blabla" # works fine (curseswin shows)
# ./testcurses.py - # works fine, (type, enter, curseswins shows):
# echo "blabla" | ./testcurses.py "sdsd" # fails to raise curses window
#
# NOTE: when without pipe: termios.tcgetattr(sys.__stdin__.fileno()): [27906, 5, 1215, 35387, 15, 15, ['\x03',
# NOTE: when with pipe | : termios.tcgetattr(sys.__stdin__.fileno()): termios.error: (22, 'Invalid argument')
import curses
import sys
import os
import atexit
import termios
def openAnything(source):
"""URI, filename, or string --> stream
http://diveintopython.net/xml_processing/index.html#kgp.divein
This function lets you define parsers that take any input source
(URL, pathname to local or network file, or actual data as a string)
and deal with it in a uniform manner. Returned object is guaranteed
to have all the basic stdio read methods (read, readline, readlines).
Just .close() the object when you're done with it.
"""
if hasattr(source, "read"):
return source
if source == '-':
import sys
return sys.stdin
# try to open with urllib (if source is http, ftp, or file URL)
import urllib
try:
return urllib.urlopen(source)
except (IOError, OSError):
pass
# try to open with native open function (if source is pathname)
try:
return open(source)
except (IOError, OSError):
pass
# treat source as string
import StringIO
return StringIO.StringIO(str(source))
def main(argv):
print argv, len(argv)
print "stdout/stdin (obj):", sys.__stdout__, sys.__stdin__
print "stdout/stdin (fn):", sys.__stdout__.fileno(), sys.__stdin__.fileno()
print "env(TERM):", os.environ.get('TERM'), os.environ.get("TERM", "unknown")
stdin_term_attr = 0
stdout_term_attr = 0
try:
stdin_term_attr = termios.tcgetattr(sys.__stdin__.fileno())
except:
stdin_term_attr = "%s::%s" % (sys.exc_info()[0], sys.exc_info()[1])
try:
stdout_term_attr = termios.tcgetattr(sys.__stdout__.fileno())
except:
stdout_term_attr = `sys.exc_info()[0]` + "::" + `sys.exc_info()[1]`
print "stdin_termios_attr", stdin_term_attr
print "stdout_termios_attr", stdout_term_attr
fname = ""
if len(argv):
fname = argv[0]
writetxt = "Python curses in action!"
if fname != "":
print "opening", fname
fobj = openAnything(fname)
print "obj", fobj
writetxt = fobj.readline(100) # max 100 chars read
print "wr", writetxt
fobj.close()
print "at end"
sys.stderr.write("before ")
print "curses", writetxt
try:
myscreen = curses.initscr()
#~ atexit.register(curses.endwin)
except:
print "Unexpected error:", sys.exc_info()[0]
sys.stderr.write("after initscr") # this won't show, even if curseswin runs fine
myscreen.border(0)
myscreen.addstr(12, 25, writetxt)
myscreen.refresh()
myscreen.getch()
#~ curses.endwin()
atexit.register(curses.endwin)
sys.stderr.write("after end") # this won't show, even if curseswin runs fine
# run the main function - with arguments passed to script:
if __name__ == "__main__":
main(sys.argv[1:])
sys.stderr.write("after main1") # these won't show either,
sys.stderr.write("after main2") # (.. even if curseswin runs fine ..)
धन्यवाद, महोदय, संक्षिप्त और कामकाजी उत्तर के लिए! :) मैं वास्तव में 'बाश' का उपयोग करता हूं, क्योंकि मैं उबंटू ल्यूसिड पर हूं। मेरा उदाहरण, आपके परिवर्तनों के साथ अपडेट किया गया है, [testcurses-stdin.py] के रूप में पाया जा सकता है (http://sdaaubckp.svn.sourceforge.net/viewvc/sdaaubckp/single-scripts/testcurses-stdin.py?revision=75&content- type = पाठ% 2Fplain और pathrev = 75); और इसे ''(echo" blabla "|/testcurses-stdin.py -) 3 <& 0'' ... – sdaau
_PS के साथ बुलाया जाना चाहिए: मुझे स्वीकार करना होगा कि मैंने [I/O पुनर्निर्देशन] देखा है (http: //www.faqs.org/docs/abs/HTML/io-redirection.html) सैकड़ों बार - मैंने इसे पोस्ट करने से पहले - और यह हमेशा मुझे भ्रमित करने के समाप्त होता है; मुझे उचित समाधान का पता लगाना मुश्किल था। साथ ही, जैसा कि मैं एक-लाइनर का बहुत शौकिया हूं, "कमांड लाइन पर बदसूरत वाक्यविन्यास" वास्तव में ** अधिक ** सराहना की गई है - मुझे जो चीजें पसंद नहीं हैं उनमें से एक चल रहा है '' exec 3 < & 0' 'कुछ ऐसा करने से पहले, अनिवार्य रूप से, एक liner_। उत्तर के लिए फिर से धन्यवाद, Frédéric - और चीयर्स! – sdaau