Pregunta

Esto es extraño y no estoy seguro de quién es realmente el culpable.

¿Estoy haciendo algunas secuencias de comandos en FreeBSD (6.2)?que hace un uso extensivo del siguiente ***bash***ismo:

do_something <(mysql --skip-column-names -B -e 'select ... from ... where ...;')

...donde "do_something es una utilidad algo tosca (en Perl) que no lee desde una canalización.Si uso un archivo normal, funciona bien.Mi intento guión usando cosas como exec 4< <(...) con este tipo de consultas (siguiendo bucles del formulario while read x y z <&4; do ... Nunca parece tener ningún problema.

Sin embargo, Perl (5.8.x) parece bloquearse periódicamente (aparentemente para siempre).Intenté cambiar el chomp(my $data = <MYDATA>); con una rutina que utilizaba lectura del sistema y escribí algunos casos de prueba en Python para comparar.Estos parecen bloquearse con mucha menos frecuencia que el código idiomático de Perl, pero a veces todavía lo hacen.(El código Python usando f.read() o os.read(f.fileno()...) parece comportarse de la misma manera en este tema).

Intenté reproducir el problema usando ... <(cat ...) (Donde estoy gatoing el archivo normal) y que nunca parece reproducir ese bloqueo.

He echado un vistazo a algunos ktrace/kdump datos ...pero estoy mucho más familiarizado con Linux rastro o incluso solaris braguero ...así que tampoco he descubierto todavía qué sucederá a partir de ahí.

Supongo que podemos descartar principalmente Perl, porque he reproducido el mismo problema usando Python...No veo como el intento podría estar haciendo algo mal aquí (solo está creando una tubería con nombre en /var/tmp/sh-np-xxx y cablear los procesos hasta eso).

¿Qué podría MySQL ¿Shell/utilidad está haciendo que podría causar esto?No creo haberlo visto en ningún otro lugar (como gato o dd).No he probado este escenario en Linux...pero lo he usado <(...) (sustitución de procesos) durante años en Linux y no recuerdo haber visto esto.

¿Es un problema de FreeBSD?

Seguro que puedo solucionar el problema utilizando archivos temporales...pero prefiero entender por qué hace esto (y evitar algunas de las carreras y el desorden de limpieza que implican los archivos temporales).

¿Alguna sugerencia?

¿Fue útil?

Solución

La gran diferencia entre operar en la salida de mysql y directamente en un archivo es el tiempo. Cuando se ha detenido el proceso de Perl, la gran pregunta es: "¿por qué no avanza en el reenvío"? Puede utilizar la opción de "L" para ps para ver el canal de espera para el proceso de Perl; de esa manera se puede ver si se bloquea en una lectura, o si algo más está sucediendo. Si realmente está bloqueado en la entrada de la tubería, espero que la entrada MWCHAN para Perl para ser "piperd".

La misma información sería interesante para el proceso de MySQL.

Lo que hace su código de prueba de Python parece?

Otra forma de escribir este evitando al mismo tiempo la del bash es la siguiente; que le permitiría descartar bash:

mysql --skip-column-names -B -e 'select ... from ... where ...;' | do_something /dev/stdin

Otras cuestiones interesantes:

  • ¿Tiene la opción de --unbuffered a mysql cambiar nada?

  • ¿Tiene canalizando el resultado de MySQL a través dd cambiar algo? (Por ejemplo, "perlscript <(MySQL ... |. Dd)

Resumen:. ¿Necesita más información

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top