shellcheck avisa sobre os loops ao encontrar a saída mesmo quando é dado o caminho para iniciar a pesquisa [duplicado]

3

Ubuntu 16.04

#!/bin/bash

site="hello"
wDir="/home/websites/${site}/httpdocs/"

for file in $(find "${wDir}" -name "*.css")
do
   echo "$file";
done
exit 0;

O shellcheck me avisa mesmo que eu defina o diretório de inicialização, mas o script funciona bem.

root@me /scripts/ # shellcheck test.sh

In test.sh line 6:
for file in $(find "${wDir}" -name "*.css")
            ^-- SC2044: For loops over find output are fragile. Use find -exec or a while read loop.
    
por needtoknow 19.03.2018 / 11:29

2 respostas

7

Usar um loop for sobre find output é um antipadrão na melhor das hipóteses. Veja BashFAQ / 001 - Como posso ler um arquivo (fluxo de dados, variável) linha-a-linha (e / ou campo-por- campo)? pelo motivo. Use um loop while como abaixo com um comando read . O comando abaixo delimita a saída de find com um byte NULL e o comando read lê ao dividir esse byte, para que todos os arquivos com caracteres especiais em seus nomes sejam manipulados com segurança (incluindo novas linhas)

#!/usr/bin/env bash

site="hello"
wDir="/home/websites/${site}/httpdocs/"

find "${wDir}" -name "*.css" -type f -print0 | while IFS= read -r -d '' file; do
    printf '%s\n' "$file"
done

Ou evite usar as linhas de tubulação e faça a substituição do processo

while IFS= read -r -d '' file; do
    printf '%s\n' "$file"
done< <(find "${wDir}" -name "*.css" -type f -print0)

A web ShellCheck não relata problemas para nenhum dos dois snippets acima.

    
por 19.03.2018 / 11:33
11

O problema é exatamente o que o shellcheck está dizendo: for faz a iteração da saída de find ou comandos semelhantes são frágeis. Por exemplo:

$ ls
'a file with spaces' 

$ for file in $(find . ); do    echo "$file"; done
.
./a
file
with
spaces

O modo seguro seria usar o -exec de find :

$ find . -exec echo  {} \;
.
./a file with spaces

Ou para usar um loop while :

$ find . -print0 | while IFS= read -r -d '' file; do echo "$file"; done
.
./a file with spaces
    
por 19.03.2018 / 11:38