2010-07-17 25 views
7

Một kịch bản python tôi cần phải chạy mất đầu vào chỉ từ một tập tin thông qua như là một đối số dòng lệnh, như vậy:Buộc một kịch bản python để có đầu vào từ STDIN

$ markdown.py input_file 

Có cách nào để làm cho nó chấp nhận đầu vào từ STDIN thay thế? Tôi muốn có thể thực hiện điều này thông qua Bash, mà không sửa đổi đáng kể kịch bản python:

$ echo "Some text here" | markdown.py 

Nếu tôi phải sửa đổi tập lệnh Python, tôi sẽ làm thế nào?

(EDIT: Here là kịch bản được phân tích các tùy chọn dòng lệnh.)

Trả lời

11

Tôi không chắc chắn cách cầm tay nó, nhưng trên các hệ thống Unix-y bạn có thể đặt tên /dev/stdin như tập tin của bạn:

$ echo -n hi there | wc /dev/stdin 
     0  2  8 /dev/stdin 
+0

Cảm ơn bạn! điều này thật đúng với gì mà tôi đã tìm kiếm. – Karthik

4

Hãy chắc chắn rằng đây là gần phía trên cùng của file:

import sys 

Sau đó tìm kiếm một cái gì đó như thế này:

filename = sys.argv[1] 
f = open(filename) 

và thay thế nó với điều này:

f = sys.stdin 

Thật khó để cụ thể hơn mà không nhìn thấy tập lệnh bạn đang bắt đầu.

+0

[Đây] (http://codaset.com/repo/python-markdown/source/master/blob/067d88bc41c7924c9087b724ff5247235243ce6b/markdown/commandline.py) là tệp. Nó sử dụng mô-đun optparse, do đó không có sys.argv []. – Karthik

0

Trong đoạn mã bạn có một dòng như thế này:

if not len(args) == 1: 

Bạn có thể làm gì để kiểm tra xem bạn không có tên tệp và thay vào đó sử dụng "/ dev/stdin" (trên hệ thống cho phép nó).

Một giải pháp khác là chỉ cần thay thế:

if not len(args) == 1: 
    parser.print_help() 
    return None, None 
else: 
    input_file = args[0] 

với

if not len(args) == 1: 
    input_file = sys.stdin 
else: 
    input_file = open(args[0]) 

Điều đó có nghĩa tất nhiên là trả lại "input_file" không còn là một tên file nhưng một đối tượng tập tin, điều đó có nghĩa hơn nữa sửa đổi trong chức năng gọi.

Giải pháp đầu tiên là ít thay đổi nhưng cụ thể hơn về nền tảng, thứ hai là công việc nhiều hơn, nhưng nên hoạt động trên nhiều hệ thống hơn.

0

Tôi đoán từ chi tiết câu hỏi của bạn mà bạn đang hỏi về Đánh dấu bằng Python, vì vậy tôi đã theo dõi dòng tương ứng trong mã nguồn cho bạn: để thực hiện theo cách của Daniel, theo dòng 443 của markdown/__init__.py, bạn muốn thay thế

input_file = codecs.open(input, mode="r", encoding=encoding) 

với

input_file = codecs.EncodedFile(sys.stdin, encoding) 

Mặc dù sau đó bạn sẽ không thể thực sự xử lý các file sau đó, như vậy cho một hack hơn thường hữu ích, bạn có thể đặt trong một điều kiện:

if input: 
    input_file = codecs.open(input, mode="r", encoding=encoding) 
else: 
    input_file = codecs.EncodedFile(sys.stdin, encoding) 

và sau đó bạn sẽ phải điều chỉnh markdown/commandline.py để không bỏ nếu nó không được cho một filename: dòng thay đổi 72-73

parser.print_help() 
return None, None 

để

input_file = None 

Vấn đề là , nó không thực sự là một điều đơn giản để làm. Tại thời điểm này tôi sẽ đề nghị sử dụng một tập tin đặc biệt như Mark Rushakoff đã làm, nếu ông đã không đánh đập tôi để nó ;-)

0

Tôi đề nghị đi ở đây:

http://codaset.com/repo/python-markdown/tickets/new

Và nộp một vé yêu cầu họ thêm đối tượng địa lý. Nó nên được đơn giản cho họ và vì vậy họ có thể sẵn sàng để đi trước và làm điều đó.

+0

Trang web đó có vẻ như đã chết, tôi nghĩ rằng đó có thể là một ý tưởng hiệu quả hơn để truy cập [Dự án Gitorious] của họ (http://gitorious.org/python-markdown), thực hiện thay đổi trong chi nhánh và yêu cầu nó được đưa vào dự án. –

0

Trong bash, bạn cũng có thể sử dụng process substitution:

markdown.py <(echo "Some text here") 

Đối với một đầu vào đơn/công trình dev/stdin, nhưng thay thế tiến trình cũng áp dụng cho một số đầu vào (và thậm chí kết quả đầu ra)

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