Mevcut işlemi yerine getirme işlemi / alt öğesi ile değiştirme


10

P"Merhaba" almak ve "Neden?" Çıktı bekliyor bir program var bir özellik sağlamadan önce. Bu özellik, "Merhaba" ile bir konuşma başlatmanın yaygın bir nezaket olduğunu bilmeyen diğer programlar tarafından kullanılır. Böylece Pbu (zsh sözdizimi) gibi çalışır için bir sarıcı yazmak istiyorum :

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.

Parçanın içinde catveya ddiçinde Replace...(benzeri bir şey cat <&p &; exec cat >&p) kullanılması gereksiz tamponlama ile sonuçlanır. Seçeneklerim neler?


Bir zshçözüm mü istiyorsunuz yoksa bir bashçözüm kabul edilebilir mi?
roaima

1
bashUygulanamayan bir çözümden hayal kırıklığına uğrayacağım zsh, ama kesinlikle kabul ediyorum ☺
Michaël

Bu komut dosyasını başka hangi programların çalıştıracağı biliniyor mu? Sonlu bir liste mi, yoksa herhangi bir sayı olabilir mi? Açıkçası, diğer programın bunu çağırması için bunu bilmesi gerekir.
Lizardx

Benim tipik kullanımı ile sshve onun seçeneği oldu ProxyCommand.
Michaël

1
catgenellikle tampon yapmaz. Sisteminizde çalışıyorsa, deneyin cat -u.
Stéphane Chazelas

Yanıtlar:


1

Belirttiğiniz sorun gerçekten bir süreci değiştirmek değil, mevcut bir sürecin akışlarını değiştirmekle ilgili . Amaç, süreçle biraz etkileşim kurmak ve daha sonra girişini / çıkışını başka bir bağlı akış çiftine aktarmaktır.

Bunu doğrudan yapmanın bir yolu yoktur (en azından kabukta; işlemin içinde bir dup2çağrı akla yatkın olabilir). Akarsuları birleştirmeniz gerekecek. yani:

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

Örneğinizde coprocolduğu gibi kullanmak da sorun değil. Komutun dosya tanımlayıcılarını bir diziye kaydettiğini ve daha sonra bunları yeniden yönlendirmeler için kullanabileceğinizi unutmayın.

P, bağlı olduğu giriş / çıkış akışlarını incelemedikçe ve buna dayalı olarak arabelleğe alma kararı vermedikçe, ek ara belleğe alma işlemine (en azından GNU cat ile) neden olmamalıdır. Örneğin, C standart kitaplığı bir dosyaya bağlıysa stdout/ üzerinde arabelleklemeyi etkinleştirir stderr, ancak yalnızca bir terminale bağlıysa arabellekleme işlemini gerçekleştirir.


-1

Arabelleğe almayı önlemek için perl kullanarak aşağıdaki kodla test edebilir, bunun sizin için çalışıp çalışmadığını deneyin

P'nin örnek versiyonu

$ 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"

Paket programı

$ 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

Test sürüşü

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

Bu, dd ibs=1örneğin kullanmakla aynıdır . Bununla iyi değilim. Bir bakıma, coproc'un kendi tamponlaması vardır ve kullanmak istediğim budur.
Michaël
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.