Não é possível aplicar o comando 'stat' para determinados parâmetros

0

Eu quero fazer um pequeno script de shell que mostre todos os arquivos em uma árvore de arquivos a partir de um determinado diretório que tenha o usuário e o tamanho especificados maiores que um determinado tamanho. Assim, meu script terá como parâmetros o diretório para começar, o nome de usuário e o tamanho. Isso é o que eu tenho até agora:

#!/bin/bash

owner="valdsilviufarcas"
size=0

function display_owner_and_size()
{
    owner='stat --format "%s" $1'
    size='stat --format "%U" $1' 
}

function search()
{

    for elem in $1/*
    do
        display_owner_and_size "$elem"
        if [[ $owner == $2 && $size > $3 ]]
        then
            echo $elem
        fi
        if test -d "$elem"
        then
            search "$elem" $2 $3    
        fi
    done
}

search $1 $2 $3

No entanto, continuo recebendo este erro: Cannot stat: (bla-bla-bla) : No such file or directory . Por que a função stat não está funcionando?

    
por vlad silviu Farcas 03.03.2016 / 09:57

2 respostas

0

Você deve simplesmente usar o comando find :

find ${dir} -user ${user} -type f -size +${size}c -printf "%u\t%s\t%h/%f\n"

Substitua as variáveis de Bash ${dir} pelo diretório a examinar recursivamente, ${user} com o nome de usuário ou UID que deve ser exibido apenas e ${size} com o tamanho mínimo de arquivo em bytes (não inclusivo! se você usar o valor 100 , o menor arquivo que é exibido pode ter 101 bytes).

Este comando só imprimirá arquivos regulares, ignorará diretórios e arquivos especiais como links simbólicos ou dispositivos na saída.

    
por Byte Commander 03.03.2016 / 10:56
0

Existem dois problemas diferentes.

O primeiro é que você não está citando suas variáveis: isso acaba fazendo stat falhar por esse motivo:

  1. search $1 $2 $3 deve ser search "$1" "$2" "$3" ;
  2. for elem in $1/* deve ser for elem in "$1"/* ;
  3. owner='stat --format "%s" $1' deve ser owner='stat --format "%s" "$1"' ;
  4. size='stat --format "%U" $1' deve ser size='stat --format "%U" "$1"' ;
  5. search "$elem" $2 $3 deve ser search "$elem" "$2" "$3" .

O segundo é quando um diretório vazio é alcançado durante a recursão, a expansão de for element in $1/* falha e os dois comandos stat são chamados em /path/to/empty/directory/* , o que não existe:

% bash script.sh /home/user user 0
stat: cannot stat ‘/home/user/Documenti/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/My Games/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/My Games/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/home/user/*’: No such file or directory
stat: cannot stat ‘/home/user/home/user/*’: No such file or directory
stat: cannot stat ‘/home/user/Modelli/*’: No such file or directory
stat: cannot stat ‘/home/user/Modelli/*’: No such file or directory
stat: cannot stat ‘/home/user/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Pubblici/*’: No such file or directory
stat: cannot stat ‘/home/user/Pubblici/*’: No such file or directory
stat: cannot stat ‘/home/user/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/Video/*’: No such file or directory
% 

Uma maneira de corrigir isso seria verificar se o arquivo / diretório existe antes de chamar display_owner_and_size , de modo a ignorar a iteração atual se estivermos tentando stat / percorrer um diretório que não existe (já que o diretório está vazio não há razão para stat seu conteúdo nem para continuar percorrendo esse ramo da árvore):

[ -e "$elem" ] && display_owner_and_size "$elem" || continue

Além disso, outros erros são:

  1. owner='stat --format "%s" "$1"' deve ser owner='stat --format "%U" "$1"' e size='stat --format "%U" "$1"' deve ser size='stat --format "%s" "$1"' ;
  2. Você não pode usar > para fazer comparações numéricas. Use -gt : if [[ $owner == $2 && $size -gt $3 ]] .

Assim, o script corrigido seria:

#!/bin/bash

owner="valdsilviufarcas"
size=0

function display_owner_and_size()
{
    owner='stat --format "%U" "$1"'
    size='stat --format "%s" "$1"'
}

function search()
{

    for elem in "$1"/*
    do
        [ -e "$elem" ] && display_owner_and_size "$elem" || continue
        if [[ $owner == $2 && $size -gt $3 ]]
        then
            echo $elem
        fi
        if test -d "$elem"
        then
            search "$elem" "$2" "$3"    
        fi
    done
}

search "$1" "$2" "$3"
    
por kos 03.03.2016 / 10:47