Thay thế quy trình hiện tại bằng coprocess / con của nó


10

Tôi có một chương trình Pmong đợi nhận được "Xin chào" và đầu ra "Tại sao?" trước khi cung cấp một tính năng. Tính năng này được sử dụng bởi các chương trình khác không biết rằng đó là phép lịch sự phổ biến để bắt đầu cuộc trò chuyện với "Xin chào". Do đó, tôi muốn viết một trình bao bọc cho Phoạt động như thế này (cú pháp zsh):

coproc P
print -p Hello  # Send Hello to P
read -pr line   # Read what P has to say
[[ "$line" = "Why?" ]] && Replace current process with the coprocess.
echo Could not get P's attention.

Sử dụng cathoặc ddtrong Replace...phần (giống như cat <&p &; exec cat >&p) kết quả trong đệm không cần thiết. Những lựa chọn của tôi là gì?


Bạn có muốn một zshgiải pháp hoặc là một bashgiải pháp chấp nhận được?
roaima

1
Tôi sẽ thất vọng bởi một bashgiải pháp không áp dụng được zsh, nhưng chắc chắn sẽ chấp nhận nó
Michaël

Được biết những chương trình khác sẽ chạy tập lệnh này? Đây có phải là một danh sách hữu hạn, hoặc nó có thể là bất kỳ số nào? Rõ ràng chương trình khác cần biết về cái này để gọi nó.
Lizardx

Sử dụng điển hình của tôi là với sshvà tùy chọn của nó ProxyCommand.
Michaël

1
catnói chung là không đệm. Nếu nó làm trên hệ thống của bạn, hãy thử cat -u.
Stéphane Chazelas

Câu trả lời:


1

Vấn đề bạn đã nêu không thực sự là về việc thay thế một quy trình , mà là thay thế các luồng của quy trình hiện có . Mục tiêu là tương tác một chút với quy trình sau đó bàn giao đầu vào / đầu ra của nó cho một cặp luồng được kết nối khác.

Không có cách nào để thực hiện điều này trực tiếp (ít nhất là trong vỏ; bên trong quy trình, một dup2cuộc gọi có thể có thể hình dung được). Bạn sẽ cần phải ghép các luồng. I E:

( echo Hello ; cat ) | P | ( read ; cat )

Sử dụng coprocnhư trong ví dụ của bạn là OK quá. Lưu ý rằng lệnh lưu bộ mô tả tệp vào một mảng và sau đó bạn có thể sử dụng chúng để chuyển hướng.

Điều này sẽ không gây ra bộ đệm bổ sung (ít nhất là với con mèo GNU), trừ khi P kiểm tra các luồng đầu vào / đầu ra mà nó được kết nối và đưa ra quyết định đệm dựa trên đó. Ví dụ: thư viện chuẩn C sẽ cho phép đệm trên stdout/ stderrnếu chúng được kết nối với một tệp, nhưng chỉ thực hiện đệm dòng nếu chúng được kết nối với một thiết bị đầu cuối.


-1

Có thể kiểm tra mã bên dưới bằng cách sử dụng perl để tránh đệm, hãy thử nếu cách này hiệu quả với bạn

Phiên bản mẫu của P

$ cat /tmp/P
#!/bin/bash
read input
if [[ $input = "Hello" ]]
then
    echo "Why?"
else
    exit 1
fi
echo "Got Hello from client, working ..."
sleep 10
echo "Need to read some input"
read x
echo "Got: $x"

Chương trình bao bọc

$ cat /tmp/wrapper 
#!/usr/bin/zsh
coproc /tmp/P
print -p Hello  # Send Hello to P
read -pr line   # Read what P has to say
if [[ "$line" = "Why?" ]]; then
    perl -e '$|=1;print $_ while(<>);' <& p &
    perl -e '$|=1;print $_ while(<>);' >& p
else
    echo "Could not get P's attention."
fi

Chạy thử nghiệm

$ /tmp/wrapper 
Got Hello from client, working ...
Need to read some input
hi there P!   <== Typed in at teminal
Got: hi there P!

Điều này giống như sử dụng dd ibs=1, ví dụ. Tôi không ổn với điều này. Theo một cách nào đó, coproc có bộ đệm riêng, và đây là cái mà tôi muốn sử dụng.
Michaël
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.