Eu tenho um script que funciona bem quando ssh no servidor para executá-lo, mas tem problemas quando 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 no 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. Para revisar:
Servidor A: Hudson usa seu mecanismo escravo para ssh no servidor B.
Servidor B: kickOffTests.sh
tem a linha ssh -t -t ServerA runTests.sh
Servidor A: runTests.sh
chama um script Perl que chama minicom -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. Invoca outro script bash, que executa os testes, que são executáveis em C compilados.
Agora, quando [~ # ~] i [~ # ~] executa 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. Eu tentei usar a linha export TERM=console
na 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.
A mensagem cannot execute binary file
não tem nada a ver com terminais (eu me pergunto o que o levou a pensar isso - e eu recomendo evitar fazer tais suposições em uma pergunta, pois elas tendem a afogar seu problema real em uma confusão de arenques vermelhos). De fato, é a maneira do bash expressar 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 informa ao bash para executar ./executable
no mesmo ambiente que o script de chamada (em oposição a um processo separado). Isso não pode ser feito se o arquivo não for um script.
Caso contrário, esta mensagem significa que ./executable
não está em um 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:
file …/executable
no servidor B.uname -a
se for do tipo unix.cksum ./executable
ou md5sum ./executable
ou qualquer outro método que você tenha no destino antes que outro script bash invoque ./executable
. Verifique se os resultados são os mesmos na invocação do Hudson, na invocação manual bem-sucedida e no servidor B.set -x
na parte superior de outro script bash (logo abaixo do #!/bin/bash
linha). Isso produzirá um rastro de tudo o que o script faz. Compare os traços e relate qualquer diferença ou singularidade../executable
não é carregado (ou ainda não foi carregado) nas invocações do Hudson. Você pode querer usar set -x
em outros scripts para ajudá-lo, e inspecione os logs de inicialização do destino.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>