bash jogando o aviso “byte nulo ignorado na entrada” em um script

2

Eu tenho um script que roda no bash 4.3 e verifica um pacote rpm. Eu quero que o mesmo script seja executado com sucesso no bash 4.4, mas o script lança um aviso “warning: command substitution: ignored null byte in input” . Abaixo está a linha que está lançando este aviso:

FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0

O script é executado no modo de depuração, conforme abaixo:

 +++ find /opt/RPM/components -type d -name eum-1.1.6 -print0
bash: warning: command substitution: ignored null byte in input
++ LINSEE_RPM=/opt/RPM/components/enum-1.1.6

Como devo agora reescrever esta linha para ignorar este aviso e silenciosamente derrubar este byte nulo como é feito no bash4.3?

    
por Emlyn Jose 05.04.2017 / 08:21

4 respostas

1

Como você não está usando o -print0 bytes que a opção %code% gera, você pode querer:

 FIND_RPM="$(find /opt/RPM/components -type d -name enum-1.1.6 -print)"
    
por 05.04.2017 / 08:31
1

Seu comando não será alterado (mesmo que seja uma sintaxe inválida em sua pergunta, talvez copiar e colar) e funcionará da mesma forma no bash 4.3 e bash 4.4.

O byte nulo ainda é descartado; a única mensagem de aviso é diferente, que foi adicionada em bash 4.4 patch 2

No seu caso, o comando funciona porque encontrou apenas uma entrada. Se várias entradas forem encontradas, elas serão concatenadas juntas (porque o byte nulo foi eliminado).

Altere o comando para:

FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6)

corrija esse problema, mas ainda engasgue se algum caminho contiver caracteres de nova linha.

    
por 05.04.2017 / 08:42
1

A propósito, se por alguma razão você precisar manter a opção -print0 de encontrar (ou seja, você espera que os resultados contenham novas linhas), você pode fazê-lo no bash 4.4 com um método diferente e evitar concatenação de resultados. O Bash reclama sobre butes nulas quando isso é atribuído a variáveis, mas os bytes nulos na substituição do processo são tratados sem problemas.

Se você espera mais de um resultado, provavelmente precisará de uma matriz:

$ IFS= readarray -t -d '' array < <(find . -type f -name 'a*.sh' -print0)
$ declare -p array
declare -a array=([0]="./appslist.sh" [1]="./advfind2.sh" [2]="./autorotate.sh" [3]="./autorot.sh" [4]="./advfind.sh" [5]="./appslist(draft).sh")

Se você espera apenas um resultado:

$ IFS= read -r -d '' var < <(find . -type f -name 'autorot.sh' -print0)
$ declare -p var
declare -- var="./autorot.sh"

Apenas para o registro, esse comportamento de eliminação de bytes nulos não se aplica em outros shells como zsh . Seu comando funcionará em zsh mesmo com mais de um resultado usando -print0 sem problema.

zsh$ var=$(find . -type f -name 'auto*.sh' -print0)
zsh$ declare -p var                                
typeset var=$'./autorotate.sh\C-@./autorot.sh\C-@'
zsh$ echo "$var" |od -w32 -t x1c                   
0000000  2e  2f  61  75  74  6f  72  6f  74  61  74  65  2e  73  68  00  2e  2f  61  75  74  6f  72  6f  74  2e  73  68  00  0a
          .   /   a   u   t   o   r   o   t   a   t   e   .   s   h  
$ IFS= readarray -t -d '' array < <(find . -type f -name 'a*.sh' -print0)
$ declare -p array
declare -a array=([0]="./appslist.sh" [1]="./advfind2.sh" [2]="./autorotate.sh" [3]="./autorot.sh" [4]="./advfind.sh" [5]="./appslist(draft).sh")
. / a u t o r o t . s h
$ IFS= read -r -d '' var < <(find . -type f -name 'autorot.sh' -print0)
$ declare -p var
declare -- var="./autorot.sh"
\n
    
por 05.04.2017 / 10:07
0
FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0

provavelmente deveria ser

FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6 -print0)

Mas essa não é a causa da mensagem de aviso.

Você está usando -print0 com find , que produzirá um byte nulo ( $'find' , ASCII 0) como separador entre os caminhos encontrados por -print em vez da nova linha gerada por -print0 (sem o zero).

Geralmente, usa xargs para enviar caminhos que podem conter espaços ou outros caracteres em branco para -print0 ou outros utilitários que saibam como lidar com caminhos terminados em bytes nulos. Isto é para que nomes de arquivos exóticos em caminhos possam ser corretamente manipulados (o byte nul pode não ser parte de um nome de arquivo no Unix, mas um espaço ou uma nova linha pode ser).

No seu caso, acho que é apenas uma questão de alterar -print para -print0 .

Isso também tem o efeito de fornecer caminhos válidos no caso de vários caminhos serem encontrados. Com %code% , Bash soltaria o nul e concatenaria os caminhos.

    
por 05.04.2017 / 08:34

Tags