Como você não está usando o
bytes que a opção %code% gera, você pode querer: -print0
FIND_RPM="$(find /opt/RPM/components -type d -name enum-1.1.6 -print)"
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?
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.
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
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 ( $'
, ASCII 0) como separador entre os caminhos encontrados por find
'-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.
Tags bash