2010-09-21 35 views
40

Trong Python, làm thế nào để bạn kiểm tra xem sys.stdin có dữ liệu hay không?Làm cách nào để kiểm tra xem liệu stdin có một số dữ liệu?

Tôi thấy rằng os.isatty(0) không chỉ có thể kiểm tra xem stdin có được kết nối với thiết bị TTY hay không, mà còn nếu có sẵn dữ liệu.

Nhưng nếu ai đó sử dụng mã như

sys.stdin = cStringIO.StringIO("ddd") 

và sau đó sử dụng os.isatty(0), nó vẫn trả về True. Tôi cần phải làm gì để kiểm tra xem liệu stdin có dữ liệu?

+3

chính xác bạn muốn đạt được điều gì? – shahjapan

+0

Điều đó xảy ra vì 'os.isatty (0)' kiểm tra xem tệp có liên quan đến bộ mô tả tệp (fd) 0 là TTY hay không. Khi bạn thay đổi biến 'sys.stdin', bạn không thay đổi tệp được liên kết với fd0. fd0 vẫn trỏ đến stdin gốc (đó là một TTY trong trường hợp của bạn). –

+2

Kiểm tra [câu trả lời này] (http://stackoverflow.com/questions/3731681/capturing-user-input-at-arbitrary-times-in-python/3732001#3732001). Nó có liên quan đến câu hỏi của bạn không? –

Trả lời

49

Trên hệ thống UNIX bạn có thể làm như sau:

import sys 
import select 

if select.select([sys.stdin,],[],[],0.0)[0]: 
    print "Have data!" 
else: 
    print "No data" 

Trên Windows các chọn mô-đun chỉ có thể được sử dụng với ổ cắm mặc dù vậy bạn sẽ cần phải sử dụng một cơ chế thay thế.

+0

đây chính xác là những gì tôi cần, cảm ơn – mlzboy

+0

Tôi xin lỗi tôi phải xóa chấp nhận vì tôi sử dụng sys.stdin = cStringIO .StringIO ("ddd") chuyển hướng stdin vào một tệp giả, nhưng nó không có phương thức fileno, nó tôi sử dụng mã bạn sẽ tăng nếu không select.select ([sys.stdin], [], [], 0.0) [0]: LoạiError: đối số phải là int hoặc có phương thức fileno(). – mlzboy

+0

@mlzboy: chỉ các tệp "thực", được mở bởi hệ điều hành có số mô tả tệp (btw trên ổ cắm hoặc đường dẫn Unix là tệp quá). 'select' gọi hàm select của hệ điều hành chỉ có thể làm việc với các tệp đó.'StringIO' là một tệp ảo chỉ được biết đến với trình thông dịch Python do đó nó không có bộ mô tả tệp và bạn không thể sử dụng' select' trên nó. –

1

Tùy thuộc vào mục tiêu ở đây:

import fileinput 
for line in fileinput.input(): 
    do_something(line) 

cũng có thể hữu ích.

+0

AFAIK, tệp tin có một nhược điểm mà giới hạn các args phải tên tập tin, nhưng args của tôi có thể là một số lệnh kiểm soát, – mlzboy

+0

Công bằng đủ! Tôi đã cố gắng để xử lý các thành ngữ phổ biến của "làm điều gì đó để một loạt các dòng, có thể từ stdin" :) –

39

Tôi đã sử dụng

if not sys.stdin.isatty() 

Dưới đây là một ví dụ:

4 import sys 
5 
6 def main(): 
7  if not sys.stdin.isatty(): 
8   print "not sys.stdin.isatty" 
9  else: 
10   print "is sys.stdin.isatty" 

>echo "asdf" | stdin.py 
not sys.stdin.isatty 

sys.stdin.isatty() trả về false nếu có điều gì đó trong stdin.

isatty(...) 
    isatty() -> true or false. True if the file is connected to a tty device. 
+3

Cảm ơn! Điều này dễ hơn rất nhiều so với việc sử dụng 'select'. –

+0

Cảm ơn. Điều đó giải quyết của tôi: echo 'có thể ống' | stdin.py + maybe_args trên linux. Giải pháp của melancholynaturegirl có hoạt động trên các cửa sổ không? –

+0

vậy có vẻ như ... C: \ Users \ naturegirl \ Desktop> C: \ Python27 \ python.exe isatty.py là sys.stdin.isatty C: \ Users \ naturegirl \ Desktop> C: \ Users \ naturegirl \ Desktop> echo "foo" | C: \ Python27 \ python.exe isatty.py không sys.stdin.isatty – liang

1

Như mentionned bởi những người khác, không có cách nào hoàn hảo để làm điều đó, bởi vì UNIX không cho phép nó. Luôn đợi stdin, ngay cả khi có thể không có gì (đó là những gì grep, v.v.) hoặc yêu cầu người dùng tham số -.

+1

Vì vậy, bạn đang trả lời một câu hỏi bằng cách đề cập đến câu hỏi rất giống nhau? WTF ?? – ForceBru

+0

@ForceBru Điều này thực sự rất khó hiểu, haha. Có vẻ như một câu hỏi khác đã được sáp nhập ở đây. Tôi đã chỉnh sửa. –

+0

Quá trình sẽ là gì - đợi stdin và đọc cho đến khi EOF, sau đó xử lý dữ liệu? Đó là, làm thế nào để grep et al. biết khi nào cần xử lý dữ liệu và khi nào thì bỏ? – Matt

Các vấn đề liên quan