./executable: Binärdatei kann nicht ausgeführt werden

12

Ich habe ein Skript, das gut funktioniert, wenn ich auf dem Server ssh ausführe, um es selbst auszuführen, aber es hat Probleme, wenn Hudson , ein Continuous Integration Server, es ausführt .

Ich automatisiere Tests auf einem eingebetteten Linux-System (dem Ziel). Das Target ist seriell mit Server A (RHEL 5) verbunden und wird über minicom bedient. Server B (FC 12) erstellt die Tests, die tatsächlich auf dem Ziel ausgeführt werden, und kann an Server A senden. Server C (RH) hostet Hudson, wobei Server B als Slave fungiert.

Ich habe ein RunScript-Skript (http://linux.die.net/man/1/runscript) geschrieben, mit dem ich alles tun kann, was für das eigentliche Ziel erforderlich ist. Es bootet das Image, stellt ein Verzeichnis von Server B bereit und führt die Tests durch. Ein Bash-Skript auf Server B ruft minicom mit dem RunScript-Skript zusammen mit einigen Begleitaktionen auf. Ich habe ein Bash-Skript auf Server B, das verwendet

ssh -t -t ServerA bashScript.sh

um diese Tests auf dem Ziel auszuführen. Ich bin auf Server C und kann diese Tests ausführen, indem ich auf Server B ssh'ing und das Skript von ssh auf Server A ausführe, das minicom mit runScript ausführt. Wütend. Zur Überprüfung:

Server A: Hudson verwendet seinen Slave-Mechanismus, um zu Server B zu sshen.

Server B: kickOffTests.shhat die Leitungssh -t -t ServerA runTests.sh

Server A: runTests.shruft ein Perl-Skript auf, das aufruftminicom -S my.script ttyE1

Ziel nach dem Booten: Hängt ein Verzeichnis von Server B an, in dem sich die Tests befinden, und gibt dieses Verzeichnis ein. Es ruft ein weiteres Bash-Skript auf, das die Tests ausführt, bei denen es sich um kompilierte ausführbare C-Dateien handelt.

Wenn ich jetzt eines dieser Skripte selbst ausführe, tun sie, was sie sollen. Wenn Hudson jedoch versucht, dasselbe zu tun, beklagt er sich in der Minicom-Sitzung über eine Zeile im "Noch ein Bash-Skript", das die ausführbare C-Datei " ./executable, with " aufruft./executable: cannot execute binary file

Ich muss noch viel über Linux lernen, aber ich gehe davon aus, dass dieses Problem darauf zurückzuführen ist, dass Hudson keine Verbindung zu einer Konsole herstellt. Ich weiß nicht genau, was Hudson tut, um seinen Sklaven zu kontrollieren. Ich habe versucht, die Zeile export TERM=consolein der Konfiguration zu verwenden, bevor kickOffTests.sh ausgeführt wurde, aber das Problem bleibt bestehen.

Kann mir jemand erklären, was passiert und wie ich das beheben kann? Ich kann keinen der Server aus dieser Gleichung entfernen. Es könnte möglich sein, Minicom aus der Gleichung herauszunehmen, aber das würde diesem Projekt eine unbekannte Zeitspanne hinzufügen, daher würde ich eine Lösung vorziehen, die das nutzt, was ich bereits habe.

jasper77
quelle

Antworten:

13

Die Nachricht cannot execute binary filehat nichts mit Terminals zu tun (ich frage mich, warum Sie das gedacht haben - und ich empfehle, solche Annahmen in einer Frage zu vermeiden, da sie dazu neigen, Ihr eigentliches Problem in einem Durcheinander roter Heringe zu übertönen). In der Tat ist es Bash Ausdrucksweise ENOEXEC(häufiger ausgedrückt als exec format error.

Stellen Sie zunächst sicher, dass Sie nicht versehentlich versucht haben, diese ausführbare Datei als Skript auszuführen. Wenn Sie geschrieben haben . ./executable, weist dies bash an, ./executablein derselben Umgebung wie das aufrufende Skript auszuführen (im Gegensatz zu einem separaten Prozess). Dies ist nicht möglich, wenn die Datei kein Skript ist.

Andernfalls bedeutet diese Meldung, dass das ./executableFormat nicht vom Kernel erkannt wird. Ich habe jedoch keine definitive Vorstellung davon, was passiert. Wenn Sie das Skript auf demselben Computer ausführen können, indem Sie es auf eine andere Weise aufrufen, kann es sich nicht nur um eine beschädigte Datei oder eine Datei für die falsche Architektur handeln (es kann sein, dass dies der Fall ist, aber es steckt noch mehr dahinter). Ich frage mich, ob es einen Unterschied in der Art und Weise geben könnte, wie das Ziel startet (möglicherweise eine Rennbedingung).

Hier ist eine Liste zusätzlicher Daten, die helfen können:

  • Ausgabe von file …/executableauf Server B.
  • Einige Informationen zum Ziel, z. B. die Ausgabe von uname -a"Unix-like".
  • Vergewissern Sie sich, dass auf dem Ziel jedes Mal derselbe Dateiinhalt angezeigt wird: Ausführen cksum ./executableoder eine md5sum ./executableandere Methode auf dem Ziel, bevor ein weiteres Bash-Skript aufgerufen wird ./executable. Überprüfen Sie, ob die Ergebnisse beim Hudson-Aufruf, bei Ihrem erfolgreichen manuellen Aufruf und auf Server B identisch sind.
  • Fügen Sie set -xoben in ein weiteres Bash-Skript ein (direkt unter der #!/bin/bashZeile). Dies erzeugt eine Spur von allem, was das Skript tut. Vergleichen Sie die Spuren und geben Sie alle Unterschiede oder Kuriositäten an.
  • Beschreiben Sie, wie das Ziel gestartet wird, wenn Sie die Skripts manuell ausführen und wenn Hudson beteiligt ist. Möglicherweise wird das Ziel anders gestartet und ein ladbares Modul, das das Format von ./executableunterstützt, wird in den Hudson-Aufrufen nicht geladen (oder noch nicht geladen). Möglicherweise möchten Sie set -xandere Skripts verwenden, um Sie dort zu unterstützen und die Startprotokolle vom Ziel aus zu überprüfen.
Gilles 'SO - hör auf böse zu sein'
quelle
Wenn das Skript ". ./Executable" enthält, würde dieses Problem dann nicht auftreten, unabhängig davon, wie das Skript aufgerufen wird? Wenn ich "./kickOffTests.sh" aufrufe, befinden sich mehrere Skriptebenen unten, bevor "./executable" auf dem Ziel aufgerufen wird. Sie haben Recht, dass ich in der Frage keine Annahmen treffen sollte, aber da das einzige, was anders ist, ist, wie das übergeordnete Skript aufgerufen wird, wobei die eine Möglichkeit in einem offenen ssh-Terminal von Hand ist und die andere automatisch von Hudson Die Antwort scheint in diesem Unterschied zu liegen.
Jasper77
@jasper77: Mir ist jetzt klar, dass die Fehlermeldung nicht ganz das bedeutet, was ich anfangs gedacht habe (obwohl, wenn Ihr Problem mit Terminals zusammenhängt, die Verbindung sehr indirekt ist). Sehen Sie sich meine überarbeitete Antwort an und versuchen Sie, so viele der vorgeschlagenen zusätzlichen Daten wie möglich bereitzustellen.
Gilles 'SO- hör auf böse zu sein'
Ich gebe zu, dass die Skripte nicht genau das taten, was ich dachte. Gilles hat es genagelt; Die ausführbaren Dateien waren für ein anderes Ziel erstellt worden. In einer "make -C" -Zeile eines Skripts hatte ich einen Zielnamen weggelassen, sodass das Standardziel anstelle des von mir beabsichtigten Ziels erstellt wurde. Sobald ich das behoben habe, ist Hudson erfolgreich in der Lage, die Minicom-Sitzung zu fahren. Da ich Probleme mit einer Konsolenanwendung hatte, die von ssh ausgeführt wurde, und dabei etwas über 'export TERM = console' und "ssh -t -t" erfuhr, war ich überzeugt, dass meine Probleme vorhanden waren. Vielen Dank, Gilles!
Jasper77
0

Dies kann passieren, wenn Sie die Shebang-Zeile oben in Ihrem Skript verpassen. Stellen Sie sicher, dass das Skript mit Folgendem beginnt:

#!/bin/bash

Dies zeigte sich nur für mich, als ich das Skript mit ausgeführt habe sudo -u <user>

Kevin Lamse
quelle