Bắt stdin từ một đường ống có tên


10

Những gì tôi đang cố gắng làm là chạy python trong một cửa sổ terminal và chuyển hướng nó stdin từ một đường ống có tên. Sau đó, tôi viết vào đường ống có tên trong một thiết bị đầu cuối khác và thực hiện lệnh đó trên python.

Nhà ga 1:

mkfifo p1
python < p1

Nhà ga 2:

echo -n "print \"Hello World\"" > p1

Điều gì xảy ra là - trăn in Hello Worldvà thoát. Những gì tôi muốn làm là giữ cho python chạy để nhận lệnh tiếp theo. Làm thế nào để tôi làm điều này trong vỏ?

Câu trả lời:


10

Bạn cần phải

  • Chạy python tương tác mặc dù stdin của nó không phải là thiết bị đầu cuối: sử dụng python -i
  • giữ cho đầu viết của ống mở, nếu không python sẽ phát hiện EOF và thoát.

Vì thế:

python -i < p1

Và những nơi khác:

exec 3> p1
echo '1j*1j' >&3
...
# and when done, close that file descriptor so python sees the EOF:
exec 3>&-

Cảm ơn! Nó đã làm việc. Tôi không quen thuộc với những gì bạn đã làm. Bạn vui lòng thêm một số chi tiết vào câu trả lời của bạn để giải thích những gì đang xảy ra. Cái gì đang exec 3> p1làm và cái gì là &3& exec 3> &1? Cảm ơn bạn.
Chúa ơi.

1
Câu trả lời của bạn làm tôi nhớ đến biểu ngữ này - sphotos-b.xx.fbcdn.net/hphotos-ash4/. Đó là ảnh bìa của một người bạn trên facebook :-)
Lord Loh.

Một câu hỏi, sẽ exec 3>&-làm việc giống như exec 3>&1ở đây?
tự đại diện

1
@Wildcard Tôi nghi ngờ tôi có ý định viết 3>&-ở đây. 3>&1cũng sẽ làm việc nhưng có ý nghĩa rất nhỏ. Cảm ơn
Stéphane Chazelas

5

Bạn có thể sử dụng tail -fđể giữ fifo mở sau khi echoviết cho nó.

tail -n1 -f p1 | python

Tại sao điều này hoạt động

pythonđang đọc từ p1. Khi đến cuối tập tin, nó dừng đọc. Đây là hành vi bình thường đối với việc đọc tệp, ngay cả khi tệp là đường ống có tên. tailvới -fcờ (theo) sẽ tiếp tục đọc từ một tệp sau khi kết thúc.


Tôi đã thử echo "print \"Hello World\" " > p1trong thiết bị đầu cuối thứ hai và không có gì xảy ra - nhưng thiết bị đầu cuối cũng không bị chặn. Thiết bị đầu cuối với python vẫn bị chặn cho đến khi tôi ^cthoát ra và kết thúc python với thông báo ngắt bàn phím được hiển thị bởi python.
Chúa ơi.

Tôi đã sử dụng tail -fthủ thuật này khi giải nén lưu trữ tar tách khối thông qua một đường ống có tên. Nó làm việc tuyệt vời.
Mael

2

Bạn cần gửi toàn bộ chương trình cùng một lúc.

Khi bạn gọi run python < p1, shell đang đợi đầu vào trước khi gọi python. Đó là, python thậm chí không bắt đầu thực thi chút nào cho đến khi toàn bộ luồng dữ liệu được đọc bởi shell và sau đó được chuyển toàn bộ sang python.

Ngay cả khi chạy python -u p1thay thế (nghĩa là không có bộ đệm và đọc từ tệp p1) pythonsẽ cố gắng đọc toàn bộ tệp trước khi thực thi bất kỳ tệp nào.

Hãy thử thí nghiệm này.

Nhà ga 1:

mkfifo p1
python < p1

Nhà ga 2:

cat > p1
print "Hello World"
print "Hello World"

Bạn sẽ thấy rằng bạn có thể gửi nhiều dòng nhưng python trong Học kỳ 1 không làm gì cả. Bây giờ nhấn ctrl+ D. Toàn bộ chương trình thực hiện cùng một lúc.

Vì vậy, để tóm tắt, nếu bạn muốn python đọc từ một đường ống, bạn cần gửi toàn bộ chương trình. Bạn không thể sử dụng python tương tác theo cách này.


1

Có thể cách tiếp cận đuôi tốt hơn (linh hoạt hơn) nhưng như một cách thay thế:

{ echo -n "print \"Hello World\""; cat; } > p1

Điều này không hoạt động như tôi muốn. -ncó thể có o bị loại bỏ. Và sau đó, 0. Thiết bị đầu cuối với echolệnh bị chặn 1. python không thực thi lệnh cho đến khi tôi nhấn ^ctrong echothiết bị đầu cuối và cả hai quá trình chấm dứt.
Chúa ơi.

1
@LordLoh. Có thể là một vấn đề đệm. Có lẽ python sẽ thực thi lệnh nếu đủ đầu ra đã được tạo để dòng đầu tiên cuối cùng được ghi vào FIFO. Nhưng vì có một giải pháp hiệu quả, sẽ không có ý nghĩa gì khi nỗ lực giải quyết vấn đề này.
Hauke ​​Laging
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.