Como expressar os testes graváveis ​​e legíveis do `find`, quando eles não estão disponíveis?

Como expressar os testes graváveis ​​e legíveis do `find`, quando eles não estão disponíveis?

Às vezes, em sistemas Linux antigos, experimento que findnão há suporte -writablee -readabletestes, que testam se o arquivo ou diretório é gravável/legível, resp. para o usuário atual.

Diga, eu quero expressar -writable; então -perm -0002não seria equivalente, pois não testa se o usuário possui permissões de gravação por meio de proprietário/grupo.

Como posso expressar findo -writableteste de por meio de findoutros testes (por exemplo -perm)?

Responder1

Não há maneira conveniente. É por isso que o GNU encontra mais -readablee amigos.

Você pode construir uma expressão que se aproxime do teste de permissão enumerando os grupos em que o usuário está. Não testado.

can_access="( -user $(id -u) -perm -0${oct}00 -o ("
for g in $(id -G); do
  can_access="$can_access -group $g -o"
done
can_access="${can_access% -o} ) -perm -00${oct}0 -o -perm -000${oct} )"
find … $can_access -print

Isso não fornece o resultado correto em alguns casos, por exemplo, se houver listas de controle de acesso ou em casos extremos, como -rw----r--negar acesso a um grupo. Você pode verificar os casos extremos com a mesma técnica acima, mas a expressão fica ainda mais complexa. Para listas de controle de acesso, você precisa invocar uma ferramenta que as suporte.

Linguagens como Perl e Python fornecem acesso fácil tanto à access(2)função quanto à funcionalidade do find. Em Perl, comFile::Finde-r//-w-x(que usam o uid e o gid efetivos do processo Perl - use -R/ -W/ -Xpara verificar com o uid/gid real like access(2), e use ofiletest 'access'pragmase o seu Perl não for muito antigo para suportar coisas como ACL):

use File::Find;
use filetest 'access';
find(sub { if (-r $_) { print "$_ is readable\n"; } }, '.');

Em Python, comos.walkeos.access(que usa o uid e o gid reais do processo Python, como access(2)):

import os
for dirpath, dirnames, filenames in os.walk('.', ):
    for filename in filenames:
        filename = os.path.join(dirpath, filenames)
        if os.access(filename, os.R_OK):
            print(filename + ' is readable\n')

A única maneira totalmente confiável é tentar abrir o arquivo. Isso requer um utilitário externo, por isso será mais lento. Para testar a legibilidade de um arquivo normal:

find … -exec sh -c 'exec 2>/dev/null; : <"$0"' {} \; …

Para testar a capacidade de gravação, use : >>"$0"(isso abre o arquivo para acréscimo, portanto falhará se o arquivo não for gravável, mas na verdade não modifica nada e, em particular, não atualiza o horário da modificação). Para testar a legibilidade de um diretório, use ls -- "$0" >/dev/null. Para testar a executábilidade de um diretório, use cd -- "$0". Não há teste passivo para a executabilidade de um arquivo normal, para a capacidade de escrita de um diretório ou para acesso à maioria dos arquivos não regulares.

informação relacionada