./executable: no se puede ejecutar el archivo binario

12

Tengo un script que funciona bien cuando ssh al servidor para ejecutarlo yo mismo, pero tiene problemas cuando Hudson , un servidor de integración continua, lo ejecuta.

Estoy automatizando las pruebas en un sistema Linux integrado (el objetivo). El objetivo está conectado al servidor A (RHEL 5) a través de serie y operado a través de minicom. El servidor B (FC 12) construye las pruebas que realmente se ejecutan en el destino, y puede enviar ssh al servidor A. El servidor C (RH) aloja Hudson, con el servidor B como esclavo.

He escrito un script de runcript (http://linux.die.net/man/1/runscript) para hacer todo lo necesario en el objetivo real; arranca la imagen, monta un directorio desde el Servidor B y ejecuta las pruebas. Un script bash en el Servidor B invoca minicom con el script runcript junto con algunas acciones complementarias. Tengo un script bash en el Servidor B que usa

ssh -t -t ServerA bashScript.sh

para ejecutar esas pruebas en el objetivo. Estoy en el servidor C, puedo hacer que esas pruebas se ejecuten enviando ssh' al servidor B y ejecutando el script que ssh's al servidor A que ejecuta minicom con runcript. Uf. Para revisar:

Servidor A: Hudson usa su mecanismo esclavo para enviar ssh al Servidor B.

Servidor B: kickOffTests.shtiene la líneassh -t -t ServerA runTests.sh

Servidor A: runTests.shllama a un script perl que invocaminicom -S my.script ttyE1

Destino, después del arranque: Monta un directorio desde el Servidor B, donde están las pruebas, y entra en ese directorio. Invoca otro script bash, que ejecuta las pruebas, que son compilados en C ejecutables.

Ahora, cuando me ejecutar cualquiera de estas secuencias de comandos a mí mismo, que hacen lo que deberían. Sin embargo, cuando Hudson intenta hacer lo mismo, en la sesión de minicom se queja de una línea en "otro script bash" que invoca el ejecutable C ./executable, con./executable: cannot execute binary file

Todavía tengo mucho que aprender sobre Linux, pero supongo que este problema es el resultado de que Hudson no se conecta con una consola. No sé exactamente qué hace Hudson para controlar a su esclavo. Intenté usar la línea export TERM=consoleen la configuración justo antes de ejecutar kickOffTests.sh, pero el problema persiste.

¿Alguien puede explicarme qué está sucediendo y cómo puedo solucionarlo? No puedo eliminar ninguno de los servidores de esta ecuación. Puede ser posible eliminar el minicom de la ecuación, pero eso agregaría una cantidad de tiempo desconocida a este proyecto, por lo que preferiría una solución que use lo que ya tengo.

jasper77
fuente

Respuestas:

13

El mensaje cannot execute binary fileno tiene nada que ver con los terminales (me pregunto qué lo llevó a pensar eso, y recomiendo evitar hacer tales suposiciones en una pregunta, ya que tienden a ahogar su problema real en un lío de pistas falsas). De hecho, es la forma de expresarse de bash ENOEXEC(más comúnmente expresada como exec format error.

Primero, asegúrese de no haber intentado accidentalmente ejecutar este ejecutable como un script. Si escribió . ./executable, esto le dice a bash que se ejecute ./executableen el mismo entorno que el script de llamada (en oposición a un proceso separado). Eso no se puede hacer si el archivo no es un script.

De lo contrario, este mensaje significa que ./executableno está en un formato que el núcleo reconoce. Sin embargo, no tengo ninguna suposición definitiva sobre lo que está sucediendo. Si puede ejecutar el script en esa misma máquina invocando de una manera diferente, no puede ser simplemente un archivo corrupto o un archivo para la arquitectura incorrecta (puede ser eso, pero hay más). Me pregunto si podría haber una diferencia en la forma en que el objetivo arranca (tal vez una condición de carrera).

Aquí hay una lista de datos adicionales que pueden ayudar:

  • Salida del file …/executableservidor B.
  • Alguna información sobre el objetivo, como la salida de uname -asi es similar a Unix.
  • Verifique que el destino vea el mismo contenido de archivo cada vez: ejecute cksum ./executableo md5sum ./executablecualquier método que tenga en el destino justo antes de que se invoque otro script bash ./executable. Verifique que los resultados sean los mismos en la invocación de Hudson, en su invocación manual exitosa y en el servidor B.
  • Agregue set -xen la parte superior de yet-another-bash-script (justo debajo de la #!/bin/bashlínea). Esto producirá un rastro de todo lo que hace el script. Compare los rastros e informe cualquier diferencia u rareza.
  • Describa cómo se inicia el destino cuando ejecuta los scripts manualmente y cuando Hudson está involucrado. Podría ser que el destino se inicie de manera diferente y algún módulo cargable que brinde soporte para el formato de ./executableno se cargue (o no se cargue aún) en las invocaciones de Hudson. Es posible que desee utilizar set -xotros scripts para ayudarlo allí e inspeccionar los registros de arranque desde el destino.
Gilles 'SO- deja de ser malvado'
fuente
Si el script contiene ". ./Executable", ¿no encontraría este problema sin importar cómo se invoque el script? Cuando invoco "./kickOffTests.sh", hay varias capas de scripts antes de que se invoque "./executable" en el destino. Tienes razón en que no debería hacer suposiciones en la pregunta, pero dado que lo único diferente es cómo se invoca el script principal, donde una forma es a mano en una terminal ssh abierta y la otra es automáticamente por Hudson, Parece que la respuesta está en esa diferencia.
jasper77
@ jasper77: Ahora me doy cuenta de que el mensaje de error no significa exactamente lo que pensé inicialmente (aunque si su problema está relacionado con terminales, la conexión es muy indirecta). Vea mi respuesta revisada e intente proporcionar la mayor cantidad de datos adicionales sugeridos que pueda.
Gilles 'SO- deja de ser malvado'
Admito cara roja en beneficio de otros que los guiones no estaban haciendo exactamente lo que pensaba. Gilles lo clavó; los ejecutables habían sido construidos para un objetivo diferente. En una línea "make -C" de una secuencia de comandos, había dejado un nombre de destino, por lo que se creó el destino predeterminado en lugar del que pretendía. Una vez que lo solucioné, Hudson puede manejar con éxito el minicom sesson. Como me había encontrado con problemas relacionados con una aplicación de consola que se ejecutaba desde ssh, y aprendí sobre 'export TERM = console' y "ssh -t -t" en el camino, estaba convencido de que mis problemas estaban allí. Gracias Gilles!
jasper77
0

Esto puede suceder si te falta la línea shebang en la parte superior de tu script. Asegúrese de que el script comience con:

#!/bin/bash

Esto solo apareció para mí cuando ejecuté el script con sudo -u <user>

Kevin Lamse
fuente