./executable: impossibile eseguire il file binario


12

Ho uno script che funziona bene quando eseguo ssh sul server per eseguirlo da solo, ma ha problemi quando Hudson , un server di integrazione continua, lo esegue.

Sto automatizzando i test su un sistema Linux incorporato (l'obiettivo). Il target è collegato al Server A (RHEL 5) via seriale e gestito su minicom. Il server B (FC 12) costruisce i test effettivamente eseguiti sulla destinazione e può collegarsi al server A. Il server C (RH) ospita Hudson, con il server B come slave.

Ho scritto uno script runscript (http://linux.die.net/man/1/runscript) per fare tutto il necessario sul target effettivo; avvia l'immagine, monta una directory dal server B ed esegue i test. Uno script bash sul Server B invoca minicom con lo script runscript insieme ad alcune azioni associate. Ho uno script bash sul Server B che utilizza

ssh -t -t ServerA bashScript.sh

per eseguire quei test sul target. Sono sul Server C, posso far eseguire quei test eseguendo ssh'ing sul Server B ed eseguendo lo script che ssh è sul Server A che esegue minicom con runscript. Accidenti. Revisionare:

Server A: Hudson usa il suo meccanismo slave per inviare al server B.

Server B: kickOffTests.shha la lineassh -t -t ServerA runTests.sh

Server A: runTests.shchiama uno script perl che invocaminicom -S my.script ttyE1

Destinazione, dopo l'avvio: monta una directory dal server B, dove si trovano i test, ed entra in quella directory. Invoca ancora un altro script bash, che esegue i test, che sono compilati in C eseguibili.

Ora, quando ho eseguire qualsiasi di questi script me stesso, fanno quello che dovrebbero. Tuttavia, quando Hudson tenta di fare la stessa cosa, nella sessione di minicom si lamenta di una riga nello "ennesimo script bash" che invoca l'eseguibile C ./executable, con./executable: cannot execute binary file

Ho ancora molto da imparare su Linux, ma suppongo che questo problema sia dovuto al fatto che Hudson non si collega a una console. Non so esattamente cosa fa Hudson per controllare il suo schiavo. Ho provato a usare la linea export TERM=consolenella configurazione poco prima di eseguire kickOffTests.sh, ma il problema persiste.

Qualcuno può spiegarmi cosa sta succedendo e come posso risolverlo? Non riesco a rimuovere nessuno dei server da questa equazione. Potrebbe essere possibile eliminare minicom dall'equazione, ma ciò aggiungerebbe un periodo di tempo sconosciuto a questo progetto, quindi preferirei di gran lunga una soluzione che utilizza ciò che già ho.

Risposte:


13

Il messaggio cannot execute binary filenon ha nulla a che fare con i terminali (mi chiedo cosa ti abbia portato a pensarlo - e raccomando di evitare di fare simili ipotesi in una domanda, poiché tendono ad affogare il tuo vero problema in un pasticcio di aringhe rosse). In realtà, è il modo di esprimere di Bash ENOEXEC(più comunemente espresso come exec format error.

Innanzitutto, assicurati di non aver tentato accidentalmente di eseguire questo eseguibile come script. Se hai scritto . ./executable, questo dice a bash di essere eseguito ./executablenello stesso ambiente dello script chiamante (al contrario di un processo separato). Questo non può essere fatto se il file non è uno script.

Altrimenti, questo messaggio significa che ./executablenon è in un formato riconosciuto dal kernel. Non ho alcuna idea precisa di ciò che sta accadendo però. Se puoi eseguire lo script su quella stessa macchina invocandolo in un modo diverso, non può essere solo un file corrotto o un file per l'architettura sbagliata (potrebbe essere quello, ma c'è di più). Mi chiedo se ci potrebbe essere una differenza nel modo in cui il bersaglio si avvia (forse una condizione di gara).

Ecco un elenco di dati aggiuntivi che possono aiutare:

  • Uscita file …/executablesul server B.
  • Alcune informazioni sulla destinazione, come l'output di uname -ase è unix-like.
  • Controlla che la destinazione veda lo stesso contenuto del file ogni volta: esegui cksum ./executableo md5sum ./executablequalsiasi metodo tu abbia sulla destinazione appena prima di invocare l'ennesimo script bash ./executable. Verifica che i risultati siano gli stessi nell'invocazione di Hudson, nella tua invocazione manuale eseguita correttamente e sul server B.
  • Aggiungi set -xnella parte superiore di ancora-un altro-bash-script (appena sotto la #!/bin/bashriga). Questo produrrà una traccia di tutto ciò che fa lo script. Confronta le tracce e segnala eventuali differenze o stranezze.
  • Descrivi come viene avviato il target quando esegui gli script manualmente e quando è coinvolto Hudson. È possibile che la destinazione venga avviata in modo diverso e che alcuni moduli caricabili che forniscono il supporto per il formato di ./executablenon vengano caricati (o non ancora caricati) nelle invocazioni di Hudson. Potresti voler utilizzare set -xaltri script per aiutarti lì e ispezionare i log di avvio dalla destinazione.

Se lo script contiene ". ./Executable", non dovrei riscontrare questo problema, indipendentemente da come viene invocato lo script? Quando invoco "./kickOffTests.sh", ci sono diversi livelli di script in basso prima che "./executable" sia invocato sulla destinazione. Hai ragione sul fatto che non dovrei fare ipotesi sulla domanda, ma poiché l'unica cosa che è diversa è come viene invocato lo script genitore, in cui un modo è a mano in un terminale ssh aperto e l'altro è automaticamente da Hudson, esso sembra che la risposta risieda in quella differenza.
Jasper77,

@ jasper77: mi rendo conto ora che il messaggio di errore non significa proprio quello che inizialmente pensavo (anche se se il tuo problema è legato ai terminali, la connessione è molto indiretta). Vedi la mia risposta rivista e prova a fornire quanti più dati aggiuntivi suggeriti possibile.
Gilles 'SO- smetti di essere malvagio'

Ammetto che la faccia rossa a beneficio degli altri è che gli script non stavano facendo esattamente quello che pensavo. Gilles lo inchiodò; gli eseguibili erano stati creati per un obiettivo diverso. In una riga "make -C" di uno script, avevo lasciato fuori un nome di destinazione, quindi è stata creata la destinazione predefinita anziché quella che intendevo. Una volta risolto il problema, Hudson è riuscito a guidare il sesson minicom. Dato che avevo incontrato problemi relativi a un'applicazione console in esecuzione da ssh e ho appreso 'export TERM = console' e "ssh -t -t" lungo la strada, ero convinto che i miei problemi esistessero. Grazie Gilles!
jasper77,

0

Questo può accadere se ti manca la linea shebang nella parte superiore della tua sceneggiatura. Assicurati che lo script inizi con:

#!/bin/bash

Questo è apparso solo per me quando ho eseguito la sceneggiatura con sudo -u <user>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.