start instalar shell ubuntu jenkins hudson pipe

shell - instalar - install jenkins ubuntu java



Hudson: "sí: salida estándar: tubería rota" (5)

Necesito ejecutar un script de shell en hudson. Ese script necesita una respuesta del usuario. Para dar una respuesta automática hice la siguiente línea de comando:

yes | ./MyScript.sh

Esto funciona bien en la terminal de Ubuntu. Pero cuando uso el mismo comando en el trabajo de Hudson, el script se automatizará y hará todo el trabajo necesario, pero al final, obtengo estas dos líneas de error:

yes: standard output: Broken pipe yes: write error

Y esto provoca el fracaso de mi trabajo en Hudson.

¿Cómo debo cambiar mi línea de comandos para que funcione bien en Hudson?


Pero, ¿cómo explicaría que no obtengo este error mientras ejecuto el script localmente , pero recibo el error al ejecutarlo de forma remota desde un trabajo de Hudson?

Cuando lo está ejecutando en un terminal ( localmente ); yes es matado por la señal SIGPIPE que se genera cuando intenta escribir en la tubería cuando MyScript.sh ya ha salido.

Lo que sea que ejecute el comando (de forma remota ) en Hudson atrapa esa señal (establece su manejador en SIG_IGN , puede probarlo ejecutando el comando trap y buscando SIGPIPE en la salida) y no restaura la señal para nuevos procesos secundarios ( yes y lo que sea que ejecute MyScript.sh , por ejemplo, sh en su caso). Conduce al error de escritura ( EPIPE ) en lugar de la señal. yes detecta el error de escritura y lo informa.

Simplemente puede ignorar el mensaje de error:

yes 2>/dev/null | ./MyScript.sh

También puede informar el error contra el componente que ejecuta la canalización. El error está en no restaurar SIGPIPE en el controlador predeterminado después de que el hijo se bifurque. Es lo que esperan los programas cuando se ejecutan en un terminal en sistemas POSIX. Aunque no sé si hay una forma estándar de hacerlo para un programa basado en Java. jvm probablemente genera una excepción por cada error de escritura, por lo que no morir en SIGPIPE no es un problema para un programa java.

Es común que demonios como el proceso hudson ignoren la señal SIGPIPE. No quieres que tu demonio muera solo porque el proceso con el que te estás comunicando muere y de todos modos verificas si hay errores de escritura.

Los programas ordinarios que se escriben para ejecutarse en un terminal no verifican el estado de cada printf() busca de errores, pero usted quiere que se mueran si los programas en la tubería mueren, por ejemplo, si ejecuta source | sink tubería de source | sink ; Por lo general, usted desea source proceso de source se cierre lo antes posible si el sink sale.

EPIPE error de escritura de EPIPE se devuelve si la señal SIGPIPE está deshabilitada (como se ve en el caso de Hudson) o si un programa no muere al recibirlo (el programa sí no definió ningún controlador para SIGPIPE por lo que debería morir al recibir la señal).

No quiero ignorar el error, quiero hacer el comando correcto o corregirlo para deshacerme del error.

la única forma en que el proceso yes se detiene si se cancela o se produce un error de escritura . Si la señal SIGPIPE está configurada para ser ignorada (por el padre) y ninguna otra señal mata el proceso, entonces yes recibe un error de escritura en la salida ./MyScript.sh . No hay otras opciones si usas el programa yes .

SIGPIPE señal SIGPIPE y el error EPIPE comunican exactamente la misma información: la tubería está rota . Si SIGPIPE estuviera habilitado para el proceso yes , no vería el error. Y solo porque lo ves; no pasa nada nuevo. Simplemente significa que ./MyScript.sh (con éxito o sin éxito, no importa).


¿Está intentando usar el programa yes para canalizar al script? ¿O echo si al guión? Si el proceso funciona a través de jenkins, agregue "; true" al final de su comando de shell.


Dado que yes y ./MyScript.sh pueden ejecutarse en una subshell explícita, es posible poner en segundo plano el comando yes , enviar yespid a la subshell ./MyScript.sh y luego implementar una captura en EXIT para finalizar manualmente el comando yes . (La captura en EXIT siempre debe implementarse en la subshell del último comando de una secuencia de comandos canalizada).

# avoid hangup or "broken pipe" error message when parent process set SIGPIPE to be ignored # sleep 0 or cat /dev/null: do nothing but with external command (for a shell builtin command see: help :) ( trap "" PIPE ( (sleep 0; exec yes) & echo ${!}; wait ${!} ) | ( trap ''trap - EXIT; kill "$yespid"; exit 0'' EXIT yespid="$(head -n 1)" head -n 10 # replacement for ./MyScript.sh ) echo ${PIPESTATUS[*]} )

Si desea salir de la subshell yes con el código de salida 0 también puede hacer esto:

# avoid hangup or "broken pipe" error message when parent process set SIGPIPE to be ignored # set exit code of yes subshell to 0 ( trap "" PIPE ( trap ''trap - TERM; echo "kill from yes subshell ..." 1>&2; kill "${!}"; exit 0'' TERM subshell_pid="$(bash -c ''echo "$PPID"'')" (sleep 0; exec yes) & echo "${subshell_pid}"; wait ${!} ) | ( trap ''trap - EXIT; kill -s TERM "$subshell_pid"; exit'' EXIT subshell_pid="$(head -n 1)" head -n 10 # replacement for ./MyScript.sh ) echo ${PIPESTATUS[*]} )


El comando sí se está ejecutando en un bucle infinito. Supuse que esta podría ser la solución:

yes | head -1 | ./MyScript.sh #only one "Y" would be output of the command yes

Pero, tengo el mismo error.

Podemos redirigir el error a / dev / null según lo sugerido por @JF Sebastian, o hacer que el comando sea correcto con esto:

yes | head -1 | ./MyScript.sh || yes

Pero, estas sugerencias fueron menos apreciadas. Y así, tuve que crear mi propia tubería con nombre, de la siguiente manera:

mkfifo /tmp/my_fifo #to create the named pipe exec 3<>/tmp/my_fifo #to make the named pipe in read and write mode by assigning it to a file descriptor echo "Y" >/tmp/my_fifo #to write into the named pipe, "Y" is the default value of yes ./MyScript.sh </tmp/my_fifo #to read from the named pipe rm /tmp/my_fifo #remove the named pipe

Espero soluciones más valiosas con mayores explicaciones.

Here es una explicación para un descriptor de archivo en linux.

Gracias


Tuve este error, y mi problema no es que produzca yes: standard output: Broken pipe sino que devuelve un código de error.

Debido a que ejecuto mi secuencia de comandos con el modo estricto de bash, incluido -o pipefail , cuando sí "errores" hace que mi secuencia de comandos -o pipefail errores.

Cómo evitar un error

La forma en que evité esto es así:

bash -c "yes || true" | my-script.sh