./executable: não é possível executar o arquivo binário


12

Eu tenho um script que funciona bem quando ssh no servidor para executá-lo, mas tem problemas quando o Hudson , um servidor de integração contínua, o executa.

Estou automatizando testes em um sistema Linux embutido (o destino). O destino está conectado ao servidor A (RHEL 5) via serial e operado pelo minicom. O servidor B (FC 12) cria os testes que realmente são executados no destino e pode ssh no servidor A. O servidor C (RH) hospeda Hudson, com o servidor B como escravo.

Eu escrevi um script runscript (http://linux.die.net/man/1/runscript) para fazer tudo o que é necessário no destino real; ele inicializa a imagem, monta um diretório do servidor B e executa os testes. Um script bash no Servidor B chama minicom com o script runscript, juntamente com algumas ações complementares. Eu tenho um script bash no servidor B que usa

ssh -t -t ServerA bashScript.sh

para executar esses testes no alvo. Estou no servidor C, posso executar esses testes ssh'ing no servidor B e executando o script ssh no servidor A que executa o minicom com o runcript. Ufa. Rever:

Servidor A: Hudson usa seu mecanismo escravo para ssh no servidor B.

Servidor B: kickOffTests.shtem a linhassh -t -t ServerA runTests.sh

Servidor A: runTests.shchama um script perl que chamaminicom -S my.script ttyE1

Destino, após a inicialização: Monta um diretório do Servidor B, onde estão os testes, e entra nesse diretório. Ele chama ainda outro script bash, que executa os testes, que são executáveis ​​em C compilados.

Agora, quando eu executo qualquer um desses scripts, eles fazem o que devem. No entanto, quando Hudson tenta fazer a mesma coisa, na sessão minicom, ele reclama de uma linha no "ainda outro script bash" que chama o executável C ./executable, com./executable: cannot execute binary file

Ainda tenho muito a aprender sobre linux, mas suponho que esse problema seja resultado do Hudson não se conectar a um console. Não sei exatamente o que Hudson faz para controlar seu escravo. Tentei usar a linha export TERM=consolena configuração imediatamente antes de executar o kickOffTests.sh, mas o problema permanece.

Alguém pode me explicar o que está acontecendo e como posso corrigi-lo? Não consigo remover nenhum servidor desta equação. Pode ser possível tirar o minicom da equação, mas isso adicionaria uma quantidade desconhecida de tempo a este projeto, por isso prefiro uma solução que use o que já tenho.

Respostas:


13

A mensagem cannot execute binary filenão tem nada a ver com terminais (pergunto-me o que o levou a pensar isso - e recomendo evitar fazer tais suposições em uma pergunta, pois elas tendem a afogar seu problema real em uma confusão de arenques vermelhos). Na verdade, é a maneira de expressar o bash ENOEXEC(mais comumente expresso como exec format error.

Primeiro, verifique se você não tentou executar acidentalmente este executável como um script. Se você escreveu . ./executable, isso instrui o bash a executar ./executableno mesmo ambiente que o script de chamada (ao contrário de um processo separado). Isso não pode ser feito se o arquivo não for um script.

Caso contrário, esta mensagem significa que ./executablenão está no formato que o kernel reconhece. Eu não tenho um palpite definitivo sobre o que está acontecendo. Se você pode executar o script nessa mesma máquina invocando-o de uma maneira diferente, ele não pode ser apenas um arquivo corrompido ou um arquivo para a arquitetura errada (pode ser isso, mas há mais). Gostaria de saber se poderia haver uma diferença na maneira como o alvo inicializa (talvez uma condição de corrida).

Aqui está uma lista de dados adicionais que podem ajudar:

  • Saída file …/executableno servidor B.
  • Algumas informações sobre o destino, como a saída de uname -ase for do tipo unix.
  • Verifique se o destino vê o mesmo conteúdo de arquivo a cada vez: execute cksum ./executableou md5sum ./executableou qualquer outro método que você tenha no destino antes de outro script bash chamar ./executable. Verifique se os resultados são os mesmos na chamada Hudson, na sua chamada manual bem-sucedida e no servidor B.
  • Adicione set -xna parte superior de outro script bash (logo abaixo da #!/bin/bashlinha). Isso produzirá um rastro de tudo o que o script faz. Compare os traços e relate qualquer diferença ou singularidade.
  • Descreva como o destino está inicializando quando você executa os scripts manualmente e quando o Hudson está envolvido. Pode ser que o destino seja inicializado de maneira diferente e algum módulo carregável que forneça suporte ao formato de ./executablenão seja carregado (ou ainda não esteja carregado) nas invocações do Hudson. Você pode usar set -xoutros scripts para ajudá-lo, e inspecionar os logs de inicialização do destino.

Se o script contiver ". ./Executable", não encontro esse problema, não importa como o script seja chamado? Quando eu chamo "./kickOffTests.sh", há várias camadas de scripts desativadas antes de "./executable" ser chamado no destino. Você está certo que eu não deveria fazer suposições na pergunta, mas como a única coisa diferente é como o script pai é chamado, onde uma maneira é manualmente em um terminal ssh aberto e a outra é automaticamente por Hudson, Parece que a resposta está nessa diferença.
jasper77

@ jasper77: Agora percebo que a mensagem de erro não significa exatamente o que eu pensava inicialmente (embora se o seu problema estiver relacionado a terminais, a conexão é muito indireta). Veja minha resposta revisada e tente fornecer o máximo possível dos dados adicionais sugeridos.
Gilles 'SO- stop be evil'

Eu admito que o vermelho enfrentou em benefício de outras pessoas que os scripts não estavam fazendo exatamente o que eu pensava. Gilles acertou em cheio; os executáveis ​​foram construídos para um destino diferente. Em uma linha "make -C" de um script, deixei um nome de destino, portanto o destino padrão foi criado em vez do que eu pretendia. Uma vez que eu consertei isso, Hudson conseguiu conduzir com êxito o minicom sesson. Como eu estava enfrentando problemas relacionados a um aplicativo de console em execução no ssh, e aprendi sobre 'export TERM = console' e "ssh -t -t" ao longo do caminho, estava convencido de que meus problemas estavam lá. Obrigado Gilles!
jasper77

0

Isso pode acontecer se você estiver perdendo a linha shebang na parte superior do seu script. Verifique se o script começa com:

#!/bin/bash

Isso só apareceu para mim quando executei o script com sudo -u <user>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.