Sé de dos tipos cómo se pueden conectar los comandos entre sí:
- mediante el uso de una tubería (poner salida estándar en entrada estándar del siguiente comando).
- mediante el uso de una T (empalme la salida en muchas salidas).
No sé si eso es todo lo que es posible, así que dibujo un tipo de conexión hipotética:
¿Cómo podría ser posible implementar un flujo circular de datos entre comandos como, por ejemplo, en este pseudocódigo, donde uso variables en lugar de comandos .:
pseudo-code:
a = 1 # start condition
repeat
{
b = tripple(a)
c = sin(b)
a = c + 1
}
fuente
En general, usaría un Makefile (comando make) y trataría de mapear su diagrama a las reglas de makefile.
Para tener comandos repetitivos / cíclicos, necesitamos definir una política de iteración. Con:
cada
make
uno producirá una iteración a la vez.fuente
make
, pero innecesario: si usa un archivo intermedio, ¿por qué no usar un bucle para administrarlo?make
se trata de macros, que es una aplicación perfecta aquí.Sabes, no estoy convencido de que necesariamente necesites un ciclo de retroalimentación repetitiva como lo muestran tus diagramas, por mucho que tal vez puedas usar una tubería persistente entre coprocesos . Por otra parte, puede ser que no haya demasiada diferencia: una vez que abre una línea en un coproceso, puede implementar bucles de estilo típicos simplemente escribiendo información y leyendo información de ella sin hacer nada fuera de lo común.
En primer lugar, parecería que
bc
es un candidato principal para un coproceso para usted. Enbc
usted puededefine
funciones que pueden hacer más o menos lo que pide en su pseudocódigo. Por ejemplo, algunas funciones muy simples para hacer esto podrían ser:... que imprimiría ...
Pero, por supuesto, no dura . Tan pronto como el subshell a cargo de
printf
la tubería se cierra (justo después deprintf
escribira()\n
en la tubería), la tubería se rompe ybc
la entrada se cierra y también se cierra. Eso no es tan útil como podría ser.@derobert ya ha mencionado FIFO como se puede obtener al crear un archivo de canalización con nombre con la
mkfifo
utilidad. Estos son esencialmente solo tuberías, excepto que el núcleo del sistema vincula una entrada del sistema de archivos a ambos extremos. Estos son muy útiles, pero sería mejor si pudieras tener una tubería sin correr el riesgo de que se espíe en el sistema de archivos.Resulta que tu caparazón lo hace mucho. Si usa un shell que implementa la sustitución de procesos, entonces tiene un medio muy sencillo de obtener una tubería duradera , del tipo que podría asignar a un proceso en segundo plano con el que puede comunicarse.
En
bash
, por ejemplo, puede ver cómo funciona la sustitución del proceso:Ves que realmente es una sustitución . El shell sustituye un valor durante la expansión que corresponde a la ruta a un enlace a una tubería . Puede aprovechar eso: no necesita limitarse a usar esa tubería solo para comunicarse con cualquier proceso que se ejecute dentro de la
()
sustitución misma ...... que imprime ...
Ahora sé que diferentes shells hacen el coprocesamiento de diferentes maneras, y que hay una sintaxis específica
bash
para configurar uno (y probablemente también para unozsh
) , pero no sé cómo funcionan esas cosas. Solo sé que puede usar la sintaxis anterior para hacer prácticamente lo mismo sin todo el rigmarole en ambosbash
yzsh
, y puede hacer algo muy similardash
ybusybox ash
lograr el mismo propósito con documentos aquí (porquedash
ybusybox
hacer aquí) documentos con tuberías en lugar de archivos temporales como lo hacen los otros dos) .Entonces, cuando se aplica a
bc
...... esa es la parte difícil. Y esta es la parte divertida ...
... que imprime ...
... y sigue funcionando ...
... lo que me da el último valor para
bc
's ena
lugar de llamar a laa()
función para incrementarlo e imprime ...Continuará funcionando, de hecho, hasta que lo mate y derribe sus tuberías IPC ...
fuente
eval "exec {BCOUT}<>"<(:) "{BCIN}<>"<(:)
, también funciona