find: não faz nada, se nenhum arquivo for especificado

3

Eu quero chamar o uso find em alguns nomes de arquivos.

find $(do_something to find filenames) -print0 | xargs -r0 ls -ld

Isso quebra se $(do_something to find filenames) não retorna nada: o comando find começa a fazer uma pesquisa recursiva.

Existe uma maneira de dizer ao find para não fazer nada se ele não tiver nenhum filename / dirname explícito como argumento?

    
por guettli 23.05.2016 / 10:37

4 respostas

4

Com zsh , eu faria:

files=($(do_something to find filenames))
(($#files)) && find $files ...

com tcsh :

set files=('do_something to find filenames')
if ($#files) find $files:q ...

Com bash , mksh ou ksh93 ,

set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...

POSIXly:

set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...

(no bash e em outros POSIX shells, $(...) splits (em $IFS : space, tab e newline por padrão), mas também executa globbing nas palavras resultantes que eu não espero que você queira aqui. o set -f . Outros shells ((t) csh, zsh, fish, rc, es ...) não têm esse problema).

    
por 23.05.2016 / 16:12
3

Que tal fazer isso:

paths=$(do_something to find filenames)
if [ "$paths" ]; then
    find "$paths" ...
fi

Isso funciona de forma independente da implementação find .

Observe que find "$paths" com mais de um nome de caminho causa problemas. Se os nomes dos caminhos não contiverem espaços, você poderá usar: find $paths , caso contrário, uma alternativa funcional é esta função:

dofind() {
    set -f
    set -- $(do_something to find filenames)
    if [ $# -gt 0 ]; then
        find "$@" ...
    fi
    set +f
}

Desabilita a globalização de arquivos e, em seguida, usa set -- para definir o vetor de argumentos shells. Isso funciona com qualquer shell POSIX.

    
por 23.05.2016 / 15:12
0

Você pode dar a find um diretório extra inexistente para começar:

find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld

Para deixar isso claro, elimine a saída de erro de find :

find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld

(mas você não notará se outro erro ocorrer ...).

Quando do_something to find filenames gera nomes de arquivos, find reclamará de " " , mas continuará processando o restante da linha de comando. Quando não houver saída de nomes de arquivo, find reclamará novamente de " " , mas não adicionará o padrão . .

    
por 23.05.2016 / 10:41
0

Em zsh (e a maioria dos shells não derivados de Bourne), quando um (ou todo dependendo do shell) glob não se expande, o comando é abortado.

$(do_something to find filenames) não é um glob, mas você pode torná-lo um adicionando um qualificador glob em zsh :

 find $(do_something to find filenames)(#q) -print0...

Acima, que (#q) (um qualificador de glob vazio, portanto não faz nada) é anexado à última palavra resultante da divisão da saída de do_something to find filenames , portanto o comando será abortado se esse comando não produzir ( ou em branco), mas também se essa última palavra (e essa última palavra apenas) não resolver para um caminho existente. Você pode aplicá-lo a cada palavra resultante dessa divisão (para que o comando seja abortado se alguma dessas palavras não resolver para um arquivo existente) com:

 find ${^$(do_something to find filenames)}(#q) -print0...
    
por 23.05.2016 / 16:31

Tags