Estou tentando fazer um link simbólico de arquivos executáveis para um diretório bin dentro de um script docker. Preciso de uma maneira de identificar executáveis e retornar status booleano. Estou tentando isso. Não funciona e não entendo o porquê.
for i in ../src/u-boot/tools/*; do if ! [[ "readelf -h $i | grep -q DYN" ]]; then ln -s $i .; fi; done
Se eu olhar para os valores de retorno reais, vejo os valores que espero:
root@0f1bca692c90:/home/work/bin# readelf -h ../src/u-boot/tools/mkimage |grep -q DYN
root@0f1bca692c90:/home/work/bin# echo $?
0
root@0f1bca692c90:/home/work/bin# readelf -h ../src/u-boot/tools/mkimage.c |grep -q DYN
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
root@0f1bca692c90:/home/work/bin# echo $?
1
Estou assumindo que estou entendendo mal como o bash interpreta valores de retorno. Eu tentei com colchetes simples e duplos, e obtive o mesmo comportamento.
Atualização: Consegui fazer funcionar assim:
RUN for i in ../src/u-boot/tools/*; do if /usr/bin/readelf -h $i | grep -q DYN; then ln -s $i .; fi; done
O problema tem vários aspectos, mas o principal é que você escolheu a
[[ ... ]]
construção de teste Bash e colocou a condição de teste completamente entre aspas duplas. Isso significa que a condição inteira é interpretada como uma string, que - como não é vazia - sempre é avaliada como "true".O segundo ponto é que você realmente não precisa da construção de teste. Como você baseia seu teste na presença da
DYN
propriedade na saída dereadelf
, que você testa viagrep
, você pode simplesmente declararComo o status de saída de um pipeline de comandos é o do último comando no pipeline, você obterá "true" se
DYN
ele foi encontrado na saída e "false" seDYN
não foi encontrado.O último ponto pode ser um equívoco sobre o valor de
$?
. Para testes de shell, um código de saída de0
significatrue
enquanto diferente de zero significafalse
, então a negação (if ! ....
) que você tinha está (se entendi sua intenção corretamente) errada neste ponto.