Esto implica la programación del sistema, por lo que es más que una cuestión básica. Tal como está escrito, su programa principal no requiere interacción de dúplex completo con el programa externo. Flujo de datos se desplaza en una dirección, es decir,
cadena → → programa externo programa principal
La creación de este gasoducto es sencillo. El open
de Perl tiene un modo útil explicado en el “Safe pipe opens” section of the perlipc documentation.
Otro enfoque interesante para la comunicación entre procesos es hacer que su único programa tenga múltiples procesos y se comunique entre o incluso entre ustedes mismos. La función open
aceptará un argumento de archivo de "-|"
o "|-"
para hacer algo muy interesante: bifurca a un niño conectado al identificador de archivo que ha abierto. El niño ejecuta el mismo programa que el padre. Esto es útil para abrir de manera segura un archivo cuando se ejecuta bajo un UID o GID supuesto, por ejemplo. Si abres un tubo a menos, puedes escribir en el identificador de archivo que abriste y tu hijo lo encontrará en su STDIN
. Si abre una tubería desde el signo menos, puede leer en el identificador de archivo que abrió lo que su hijo escribe en su STDOUT
.
Esto es un open
que implica una tubería, que da matices al valor de retorno. El perlfunc documentation on open
explica.
Si abre un tubo en el comando -
(es decir, especifique |-
o -|
con los de una o dos formas de argumento open
), una implícita fork
se realiza, por lo vuelve abiertas dos veces: en el proceso primario devuelve el pid del proceso hijo, y en el proceso hijo devuelve (un definido) 0
. Use defined($pid)
o //
para determinar si el open
fue exitoso.
Para crear el andamiaje, trabajamos de derecha a izquierda usando open
a fork
un nuevo proceso en cada paso.
- Su programa principal ya se está ejecutando.
- A continuación,
fork
un proceso que eventualmente se convertirá en el programa externo.
- Dentro del proceso desde el paso 2
- Primera
fork
el proceso de la cadena de impresión a fin de hacer llegar su producción en nuestro STDIN
.
- Luego
exec
el programa externo para realizar su transformación.
- Haz que la impresora de cuerdas haga su trabajo y luego
exit
, que avanza al siguiente nivel.
- De vuelta en el programa principal, lea el resultado transformado.
Con todo eso configurado, todo lo que tiene que hacer es implantar su sugerencia en la parte inferior, Sr. Cobb.
#! /usr/bin/env perl
use 5.10.0; # for defined-or and given/when
use strict;
use warnings;
my @transform = qw(tr [A-Za-z] [N-ZA-Mn-za-m]); # rot13
my @inception = (
"V xabj, Qnq. Lbh jrer qvfnccbvagrq gung V pbhyqa'g or lbh.",
"V jnf qvfnccbvagrq gung lbh gevrq.",
);
sub snow_fortress { print map "$_\n", @inception }
sub hotel {
given (open STDIN, "-|" // die "$0: fork: $!") { #/StackOverflow hiliter
snow_fortress when 0;
exec @transform or die "$0: exec: $!";
}
}
given (open my $fh, "-|" // die "$0: fork: $!") {
hotel when 0;
print while <$fh>;
close $fh or warn "$0: close: $!";
}
Gracias por la oportunidad de escribir un programa tan divertido!
El 'perlipc' página del manual tiene una discusión y un montón de ejemplos de diferentes enfoques. – tripleee