./executable: nie można wykonać pliku binarnego

12

Mam skrypt, który działa dobrze, gdy ssh do serwera, aby go wykonać, ale ma problemy, gdy Hudson , serwer ciągłej integracji, uruchamia go.

Automatyzuję testy we wbudowanym systemie Linux (cel). Cel jest połączony z serwerem A (RHEL 5) szeregowo i obsługiwany przez minicom. Serwer B (FC 12) buduje testy, które faktycznie działają na obiekcie docelowym i może ssh do serwera A. Serwer C (RH) hostuje Hudson, z serwerem B jako slave.

Napisałem skrypt runcript (http://linux.die.net/man/1/runscript), aby zrobić wszystko, co potrzebne w rzeczywistym celu; uruchamia obraz, montuje katalog z serwera B i wykonuje testy. Skrypt bash na serwerze B wywołuje minicom wraz ze skryptem runcript wraz z pewnymi akcjami towarzyszącymi. Mam skrypt bash na serwerze B, który używa

ssh -t -t ServerA bashScript.sh

aby testy te zostały uruchomione na obiekcie docelowym. Jestem na serwerze C, mogę uruchomić te testy poprzez ssh'ing na serwerze B i wykonanie skryptu ssh na serwerze A, który wykonuje minicom z runcript. Uff Recenzować:

Serwer A: Hudson używa swojego mechanizmu podrzędnego do ssh na serwerze B.

Serwer B: kickOffTests.shma linięssh -t -t ServerA runTests.sh

Serwer A: runTests.shwywołuje skrypt Perla, który się wywołujeminicom -S my.script ttyE1

Cel po uruchomieniu: Montuje katalog z serwera B, na którym znajdują się testy, i wchodzi do tego katalogu. Wywołuje kolejny skrypt bash, który uruchamia testy, które są skompilowanymi plikami wykonywalnymi C.

Teraz, kiedy mam wykonać żadnego z tych scenariuszy się, robią to, co powinny. Jednak gdy Hudson próbuje zrobić to samo, w sesji minicom narzeka na wiersz w „jeszcze innym skrypcie bash”, który wywołuje plik wykonywalny C ./executable, z./executable: cannot execute binary file

Nadal mam wiele do nauczenia się na temat Linuksa, ale podejrzewam, że ten problem wynika z braku połączenia Hudsona z konsolą. Nie wiem dokładnie, co Hudson robi, aby kontrolować swojego niewolnika. Próbowałem użyć linii export TERM=consolew konfiguracji tuż przed uruchomieniem kickOffTests.sh, ale problem pozostaje.

Czy ktoś może mi wyjaśnić, co się dzieje i jak mogę to naprawić? Nie mogę usunąć żadnego serwera z tego równania. Możliwe, że uda się wyciągnąć minicom z równania, ale dałoby to nieznany czas temu projektowi, więc wolałbym rozwiązanie, które wykorzystuje to, co już mam.

jasper77
źródło

Odpowiedzi:

13

Wiadomość cannot execute binary filenie ma nic wspólnego z terminalami (zastanawiam się, co skłoniło cię do takiego przypuszczenia - i zalecam unikanie takich założeń w pytaniu, ponieważ mają one tendencję do zagłuszania twojego rzeczywistego problemu w bałaganie czerwonych śledzi). W rzeczywistości jest to sposób wyrażania basha ENOEXEC(częściej wyrażany jako exec format error.

Po pierwsze, upewnij się, że nie próbowałeś przypadkowo uruchomić tego pliku wykonywalnego jako skryptu. Jeśli napisałeś . ./executable, to mówi bashowi, aby działał ./executablew tym samym środowisku co skrypt wywołujący (w przeciwieństwie do osobnego procesu). Nie można tego zrobić, jeśli plik nie jest skryptem.

W przeciwnym razie ten komunikat oznacza, że ./executablenie jest w formacie rozpoznawanym przez jądro. Nie wiem jednak, co się dzieje. Jeśli możesz uruchomić skrypt na tym samym komputerze, wywołując go w inny sposób, nie może to być po prostu uszkodzony plik lub plik o niewłaściwej architekturze (może tak być, ale jest coś więcej). Zastanawiam się, czy może istnieć różnica w sposobie, w jaki buty docelowe (być może warunki wyścigu).

Oto lista dodatkowych danych, które mogą pomóc:

  • Dane wyjściowe file …/executablena serwerze B.
  • Niektóre informacje o celu, takie jak wynik działania uname -aif, jeśli jest on uniksowy.
  • Sprawdź, czy cel widzi tę samą zawartość pliku za każdym razem: uruchom cksum ./executablelub md5sum ./executableinną metodę, którą masz na celu tuż przed wywołaniem skryptu bash ./executable. Sprawdź, czy wyniki są takie same w wywołaniu Hudson, udanym ręcznym wywołaniu i na serwerze B.
  • Dodaj set -xna górze jeszcze innego skryptu bash (tuż poniżej #!/bin/bashlinii). To wygeneruje ślad wszystkiego, co robi skrypt. Porównaj ślady i zgłoś każdą różnicę lub osobliwość.
  • Opisz, w jaki sposób uruchamia się cel, gdy uruchamiasz skrypty ręcznie i gdy zaangażowany jest Hudson. Może się zdarzyć, że cel zostanie uruchomiony inaczej i jakiś moduł, który zapewnia obsługę formatu, ./executablenie jest ładowany (lub nie jest jeszcze ładowany) w wywołaniach Hudsona. Możesz użyć set -xinnych skryptów, które ci w tym pomogą, i sprawdź dzienniki rozruchu od celu.
Gilles „SO- przestań być zły”
źródło
Jeśli skrypt zawiera „. ./Executable”, to czy nie napotkałbym tego problemu bez względu na sposób jego wywołania? Kiedy wywołuję „./kickOffTests.sh”, istnieje kilka warstw skryptów, zanim „./executable” zostanie wywołany na celu. Masz rację, że nie powinienem przyjmować założeń w tym pytaniu, ale ponieważ jedyną różnicą jest to, w jaki sposób wywoływany jest skrypt nadrzędny, gdzie jedna strona jest ręcznie w otwartym terminalu ssh, a druga automatycznie przez Hudsona, wydaje się, że odpowiedź leży w tej różnicy.
jasper77
@ jasper77: Teraz zdaję sobie sprawę, że komunikat o błędzie nie oznacza dokładnie tego, co początkowo myślałem (chociaż jeśli twój problem dotyczy terminali, połączenie jest bardzo pośrednie). Zobacz moją poprawioną odpowiedź i spróbuj podać jak najwięcej sugerowanych dodatkowych danych.
Gilles „SO- przestań być zły”
Przyznaję, że czerwona twarz z korzyścią dla innych mówi, że skrypty nie działały dokładnie tak, jak myślałem. Gilles go przybił; pliki wykonywalne zostały zbudowane dla innego celu. W wierszu „make -C” jednego skryptu zrezygnowałem z nazwy celu, więc domyślny cel został zbudowany zamiast zamierzonego. Kiedy to naprawię, Hudson jest w stanie z powodzeniem prowadzić minicom sesson. Ponieważ miałem problemy z aplikacją konsolową uruchomioną z ssh i po drodze dowiedziałem się o „export TERM = console” i „ssh -t -t”, byłem przekonany, że moje problemy tam są. Dzięki Gilles!
jasper77
0

Może się to zdarzyć, jeśli brakuje linii shebang na górze skryptu. Upewnij się, że skrypt zaczyna się od:

#!/bin/bash

To pokazało mi się tylko wtedy, gdy uruchomiłem skrypt sudo -u <user>

Kevin Lamse
źródło