./exécutable: impossible d'exécuter le fichier binaire

12

J'ai un script qui fonctionne bien quand je ssh sur le serveur pour l'exécuter moi-même, mais qui a des problèmes quand Hudson , un serveur d'intégration continue, l'exécute.

J'automatise des tests sur un système Linux embarqué (la cible). La cible est connectée au serveur A (RHEL 5) via série et exploitée via minicom. Le serveur B (FC 12) construit les tests qui s'exécutent réellement sur la cible et peut ssh vers le serveur A. Le serveur C (RH) héberge Hudson, avec le serveur B comme esclave.

J'ai écrit un script runscript (http://linux.die.net/man/1/runscript) pour faire tout ce qui est nécessaire sur la cible réelle; il démarre l'image, monte un répertoire à partir du serveur B et exécute les tests. Un script bash sur le serveur B appelle minicom avec le script runscript ainsi que certaines actions compagnes. J'ai un script bash sur le serveur B qui utilise

ssh -t -t ServerA bashScript.sh

pour exécuter ces tests sur la cible. Je suis sur le serveur C, je peux faire exécuter ces tests en faisant ssh sur le serveur B et en exécutant le script qui ssh sur le serveur A qui exécute minicom avec runscript. Ouf. Réviser:

Serveur A: Hudson utilise son mécanisme esclave pour ssh vers le serveur B.

Serveur B: kickOffTests.sha la lignessh -t -t ServerA runTests.sh

Serveur A: runTests.shappelle un script perl qui appelleminicom -S my.script ttyE1

Cible, après le démarrage: monte un répertoire à partir du serveur B, où se trouvent les tests, et entre dans ce répertoire. Il appelle encore un autre script bash, qui exécute les tests, qui sont des exécutables C compilés.

Maintenant, quand j'exécute un de ces scripts moi - même, ils font ce qu'ils devraient. Cependant, lorsque Hudson essaie de faire la même chose, au cours de la session minicom, il se plaint d'une ligne dans le "encore un autre script bash" qui invoque l'exécutable C , avec./executable./executable: cannot execute binary file

J'ai encore beaucoup à apprendre sur Linux, mais je suppose que ce problème est dû au fait que Hudson ne se connecte pas à une console. Je ne sais pas exactement ce que fait Hudson pour contrôler son esclave. J'ai essayé d'utiliser la ligne export TERM=consoledans la configuration juste avant d'exécuter kickOffTests.sh, mais le problème persiste.

Quelqu'un peut-il m'expliquer ce qui se passe et comment je peux y remédier? Je ne peux supprimer aucun des serveurs de cette équation. Il peut être possible de supprimer minicom de l'équation, mais cela ajouterait une quantité de temps inconnue à ce projet, donc je préférerais de loin une solution qui utilise ce que j'ai déjà.

jasper77
la source

Réponses:

13

Le message cannot execute binary filen'a rien à voir avec les terminaux (je me demande ce qui vous a amené à penser cela - et je recommande d'éviter de faire de telles hypothèses dans une question, car ils ont tendance à noyer votre problème réel dans un gâchis de harengs rouges). En fait, c'est la façon dont Bash exprime ENOEXEC(plus communément exprimé par exec format error.

Tout d'abord, assurez-vous que vous n'avez pas accidentellement essayé d'exécuter cet exécutable en tant que script. Si vous avez écrit . ./executable, cela indique à bash de s'exécuter ./executabledans le même environnement que le script appelant (par opposition à un processus séparé). Cela ne peut pas être fait si le fichier n'est pas un script.

Sinon, ce message signifie que ce ./executablen'est pas dans un format reconnu par le noyau. Je n'ai cependant aucune idée précise de ce qui se passe. Si vous pouvez exécuter le script sur cette même machine en l'invoquant d'une manière différente, il ne peut pas simplement s'agir d'un fichier corrompu ou d'un fichier pour la mauvaise architecture (c'est peut-être cela, mais il y a plus). Je me demande s'il pourrait y avoir une différence dans la façon dont la cible démarre (peut-être une condition de course).

Voici une liste de données supplémentaires qui peuvent vous aider:

  • Sortie de file …/executablesur le serveur B.
  • Quelques informations sur la cible, comme la sortie de uname -asi elle est de type Unix.
  • Vérifiez que la cible voit le même contenu de fichier à chaque fois: exécutez cksum ./executableou md5sum ./executableou toute autre méthode que vous avez sur la cible juste avant qu'un autre script bash ne soit invoqué ./executable. Vérifiez que les résultats sont les mêmes dans l'appel Hudson, dans votre appel manuel réussi et sur le serveur B.
  • Ajoutez set -xen haut d'un autre script bash (juste en dessous de la #!/bin/bashligne). Cela produira une trace de tout ce que le script fait. Comparez les traces et signalez toute différence ou bizarrerie.
  • Décrivez comment la cible démarre lorsque vous exécutez les scripts manuellement et quand Hudson est impliqué. Il se peut que la cible soit démarrée différemment et qu'un module chargeable qui prend en charge le format de ./executablene soit pas chargé (ou n'est pas encore chargé) dans les appels Hudson. Vous pouvez utiliser set -xd'autres scripts pour vous y aider et inspecter les journaux de démarrage de la cible.
Gilles 'SO- arrête d'être méchant'
la source
Si le script contient ". ./Executable", ne rencontrerais-je pas ce problème, quelle que soit la façon dont le script est invoqué? Lorsque j'appelle "./kickOffTests.sh", il y a plusieurs couches de scripts avant que "./executable" soit invoqué sur la cible. Vous avez raison, je ne devrais pas faire d'hypothèses dans la question, mais comme la seule chose qui est différente est la façon dont le script parent est appelé, où une façon se fait à la main dans un terminal ssh ouvert et l'autre est automatiquement par Hudson, il semble que la réponse réside dans cette différence.
jasper77
@ jasper77: Je me rends compte maintenant que le message d'erreur ne signifie pas tout à fait ce que je pensais initialement (bien que si votre problème est lié aux terminaux, la connexion est très indirecte). Consultez ma réponse révisée et essayez de fournir autant de données supplémentaires suggérées que possible.
Gilles 'SO- arrête d'être méchant'
J'avoue que les visages rouges pour le bénéfice des autres que les scripts ne faisaient pas exactement ce que je pensais. Gilles l'a cloué; les exécutables avaient été construits pour une cible différente. Dans une ligne "make -C" d'un script, j'avais laissé un nom de cible, donc la cible par défaut a été construite à la place de celle que je voulais. Une fois que j'ai corrigé cela, Hudson est capable de conduire avec succès le minicom sesson. Étant donné que j'avais rencontré des problèmes liés à une application console exécutée à partir de ssh et appris en cours de route «export TERM = console» et «ssh -t -t», j'étais convaincu que mes problèmes étaient là. Merci Gilles!
jasper77
0

Cela peut arriver si vous manquez la ligne shebang en haut de votre script. Assurez-vous que le script commence par:

#!/bin/bash

Cela ne m'est apparu que lorsque j'ai exécuté le script avec sudo -u <user>

Kevin Lamse
la source