Como posso excluir todos “permissão negada” mensagens de “encontrar”?
-
11-09-2019 - |
Pergunta
Eu preciso esconder tudo permissão negada mensagens de:
find . > files_and_folders
Eu estou experimentando quando tal mensagem surge. Eu preciso reunir todas as pastas e arquivos, para que ele não surgir.
É possível direcionar os níveis de permissão para o arquivo files_and_folders
?
Como posso ocultar os erros, ao mesmo tempo?
Solução
Nota:
* Esta resposta provavelmente é mais profundo do que os mandados de caso de uso, e find 2>/dev/null
pode ser bom o suficiente em muitas situações. Ele ainda pode ser de interesse para uma perspectiva multi-plataforma e para sua discussão de algumas técnicas de shell avançados no interesse de encontrar uma solução que é tão robusto quanto possível, mesmo que os casos guardados contra pode ser em grande parte hipotética.
* Se o seu sistema está configurado para mostrar localizada mensagens de erro , prefixo as chamadas find
abaixo com LC_ALL=C
(LC_ALL=C find ...
) para garantir que Inglês mensagens são relatados , de modo que grep -v 'Permission denied'
funciona como pretendido. Invariavelmente, no entanto, quaisquer mensagens de erro que fazer são exibidas estará então em Inglês também.
Se o seu shell é bash
ou zsh
, há uma solução que seja robusta ao ser razoavelmente simples , usando find
única compatível com POSIX apresenta ??strong> ; enquanto a própria bash
não faz parte do POSIX, a maioria das plataformas Unix modernos vêm com ele, tornando esta solução amplamente portátil:
find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)
Nota: Há uma pequena chance de que alguma da produção da grep
pode chegar após concluída find
, porque o comando geral não espera para o comando dentro >(...)
ao fim. Em bash
, você pode evitar isso, anexando | cat
ao comando.
-
>(...)
é um (raramente utilizado) saída processo de substituição que permite redirecionar a saída (neste caso, stderr de saída (2>
) para o stdin do comando dentro>(...)
.
Alémbash
ezsh
, suportesksh
eles também , em princípio, , mas tentar combiná-los com o redirecionamento de stderr , como é feito aqui (2> >(...)
), parece ser silenciosamente ignorados (emksh 93u+
).- filtros
grep -v 'Permission denied'
a (-v
) todas as linhas (de fluxo stderr do comandofind
) que contêm a frasePermission denied
e produz as linhas restantes para stderr (>&2
).
- filtros
Esta abordagem é:
-
robusta ??strong>:
grep
só é aplicada a mensagens de erro (e não a uma combinação de caminhos de arquivos e mensagens de erro, levando potencialmente a falsos positivos), e mensagens de erro outro do que os de permissão negada são passados ??através, para stderr. -
efeito colateral livre : código de saída do
find
é preservado: a incapacidade de acesso, pelo menos um dos itens do sistema de arquivos de resultados encontrados em1
código de saída (embora isso não lhe dirá se erros outros do que os de permissão negada ocorreu (também)).
soluções compatíveis com POSIX:
soluções totalmente compatíveis com POSIX ou têm limitações ou exigir trabalho adicional.
Se a saída do find
está a ser capturado em um arquivo de qualquer maneira (ou suprimida completamente), então a solução à base de gasoduto de Jonathan Leffler é simples, robusta e compatível com POSIX:
find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
Note que a ordem das matérias redirecionamentos:. 2>&1
deve vir início
saída Capturando stdout em um arquivo na frente permite 2>&1
para enviar única mensagens de erro através do gasoduto, que grep
pode, então, de forma inequívoca operar.
única desvantagem é que o do código geral exit irá ser o comando grep
de , não find
de, que neste caso significa: se houver não erros no todo ou única erros de permissão negada, o código de saída será 1
(sinalização < em> falha ), caso contrário (exceto os de permissão negada erros) 0
- que é o oposto da intenção
.
Dito isso, o código de saída do find
é raramente usado de qualquer maneira , como muitas vezes transmite pouca informação além fundamentais falha como passar um caminho inexistente.
No entanto, o caso específico do mesmo que apenas alguns dos caminhos de entrada sendo devido inacessível a falta de permissões é refletido no código de saída do find
(em ambos GNU e BSD find
): se um erro de permissões negado ocorre para qualquer dos arquivos processados, o código de saída está definido para 1
.
Os seguintes endereços variação que:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
Agora, o código de saída indica se os erros que não Permission denied
ocorreu:. 1
em caso afirmativo, 0
outra forma
Em outras palavras: o código de saída agora reflete a verdadeira intenção do comando: sucesso (0
) é relatado, se não houver erros no todo ou única erros de permissão negada ocorreu
.
Este é sem dúvida ainda melhor do que apenas passar o código de saída do find
completamente, como na solução no topo.
gniourf_gniourf nos comentários propõe uma (ainda compatível com POSIX) generalização desta solução usando sofisticados redirecionamentos , que funciona mesmo com o comportamento padrão de imprimir os caminhos de arquivo para stdout :
{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
Em suma: Custom 3
descritor de arquivo é usado para temporariamente stdout swap (1
) e stderr (2
), de modo que as mensagens de erro somente pode ser canalizada para grep
via stdout
Sem esses redirecionamentos, ambos os dados (caminhos de arquivo) e mensagens de erro seria canalizada para grep
via stdout e grep
, então, não ser capaz de distinguir entre o mensagem de erro Permission denied
e um (hipotético) arquivo cujo nome passa a conter a frase Permission denied
.
Tal como na primeira solução, no entanto, o código da saída relatado será grep
de, de não find
, mas a mesma correção como acima pode ser aplicada.
Notas sobre as respostas existentes:
-
Há vários pontos a nota sobre resposta de Michael Brux,
find . ! -readable -prune -o -print
:-
Ela exige GNU
find
; nomeadamente, que não vai funcionar no MacOS. Claro, se você só precisa o comando para trabalhar com GNUfind
, este não será um problema para você. -
Alguns erros
Permission denied
podem ainda superfície:find ! -readable -prune
relata tais erros para o criança itens de diretórios para que o usuário atual tem permissãor
, mas faltax
(executável) permissão. A razão é que, como o próprio diretório é legível,-prune
não é executado, ea tentativa de descer em esse diretório, em seguida, aciona as mensagens de erro. Dito isto, o típico caso é para a permissãor
estar faltando. -
Nota: O ponto seguinte é uma questão de filosofia e / ou caso de uso específico, e você pode decidir que não é relevante para você e que o comando se adapta às suas necessidades bem, especialmente se simplesmente imprimir os caminhos é tudo que você faz:
- Se você conceituar a filtragem das mensagens de erro de permissão negada a separado tarefasque você quer ser capaz de aplicar a qualquer comando
find
, em seguida, a abordagem oposta de forma proativa prevenção erros de permissão negada requer a introdução de "ruído" no comandofind
, que também introduz complexidade e lógica armadilhas . - Por exemplo, o mais comentário up-votado a resposta de Michael (como desta escrita) tenta mostrar como estender o comando, incluindo um filtro
-name
, como segue:
find . ! -readable -prune -o -name '*.txt'
Isso, no entanto, faz não trabalho como pretendido, porque a ação-print
arrastando é necessário (uma explicação pode ser encontrada em esta resposta ). Tais sutilezas podem introduzir erros.
- Se você conceituar a filtragem das mensagens de erro de permissão negada a separado tarefasque você quer ser capaz de aplicar a qualquer comando
-
-
A primeira solução em resposta de Jonathan Leffler,
find . 2>/dev/null > files_and_folders
, como ele mesmo afirma, cegamente silêncios todas mensagens de erro (e a solução é complicada e não totalmente robusto, como ele também explica). Pragmaticamente falando , no entanto, é o solução mais simples , como você pode se contentar em assumir que todo e qualquer erro seria relacionada com a permissão. -
da névoa resposta ,
sudo find . > files_and_folders
, é conciso e pragmático, mas mal aconselhado para outra coisa que meramente imprimir nomes , por razões de segurança: porque você está executando como o root user ", o risco de ter todo o seu sistema a ser confuso por um bug na descoberta ou uma versão maliciosa, ou uma invocação incorrecta que escreve algo inesperadamente, o que não poderia acontecer se você executou esta com privilégios normais "(de um comentário sobre a resposta da névoa por tripleee ). -
A 2ª solução em de viraptor resposta ,
find . 2>&1 | grep -v 'Permission denied' > some_file
corre o risco de falsos positivos (devido ao envio de uma mistura de stdout e stderr através do gasoduto), e, potencialmente, ao invés de relatar não erros via stderr -permission negado, captura-los ao lado dos caminhos de saída no arquivo de saída.
Outras dicas
Use:
find . 2>/dev/null > files_and_folders
Isto esconde não só os erros Permission denied
, é claro, mas todas as mensagens de erro.
Se você realmente quiser manter outros possíveis erros, como muitos pontos em um link simbólico, mas não a permissão negada queridos, então você provavelmente terá que dar um palpite voador que você não tem muitos arquivos chamados ' permissão negada' e tentar:
find . 2>&1 | grep -v 'Permission denied' > files_and_folders
Se você quiser estritamente para filtrar apenas erro padrão, você pode usar a construção mais elaborada:
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
O I / O redirecionamento no comando find
é: 2>&1 > files_and_folders |
.
O tubo de saída padrão redirecciona para o comando grep
e é aplicada em primeiro lugar. O 2>&1
envia erro padrão para o mesmo lugar como saída padrão (o tubo). O > files_and_folders
envia saída padrão (mas não o erro padrão) para um arquivo. O resultado líquido é que as mensagens escritas para o erro padrão são enviados para baixo o tubo ea saída regular de find
é escrito para o arquivo. O grep
filtra a saída padrão (você pode decidir como seletiva você quer que ele seja, e pode ter que alterar a ortografia, dependendo do local e O / S) e os meios >&2
finais que as mensagens de erro sobreviventes (escrito para a saída padrão) GO para o erro padrão mais uma vez. O redirecionamento final poderia ser considerado como opcional no terminal, mas seria uma idéia muito boa para usá-lo em um script para que as mensagens de erro no erro padrão.
Existem infinitas variações sobre este tema, dependendo do que você quer fazer. Este trabalho vontade em qualquer variante do Unix com qualquer shell Bourne derivado (Bash, Korn, ...) e qualquer versão compatível com POSIX de find
.
Se você deseja se adaptar à versão específica do find
você tem no seu sistema, pode haver opções alternativas disponíveis. GNU find
em particular, tem uma miríade de opções que não estão disponíveis em outras versões -. Veja a resposta atualmente aceita por um tal conjunto de opções
Use:
find . ! -readable -prune -o -print
ou, mais geralmente
find <paths> ! -readable -prune -o <other conditions like -name> -print
- para evitar "Permissão negada"
- E não suprimem mensagens de erro (outra)
- e obter status de saída 0 ( "todos os arquivos são processados ??com sucesso")
trabalha com: find (findutils GNU) 4.4.2. Antecedentes:
- O teste
-readable
corresponde arquivos legíveis. O operador!
retorna verdadeiro, quando o teste é falsa. E partidas! -readable
não diretórios legível (e arquivos). - A ação
-prune
não desce para o diretório. -
! -readable -prune
pode ser traduzido para:. Se o diretório não é legível, não descer para isso - O teste
-readable
leva em conta as listas de controle de acesso e outros artefatos de permissões que os ignora teste-perm
.
Veja também find
(1) manpage para muitos mais detalhes.
Se você quer começar a busca da raiz "/", provavelmente você vai ver algumas coisas de saída como:
find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied
É por causa da permissão. Para resolver isso:
-
Você pode usar o comando sudo:
sudo find /. -name 'toBeSearched.file'
. ele pede senha de super usuário, quando digitar a senha que você vai ver o resultado que você realmente quer. -
Você pode usar o redirecionamento da saída de erro padrão a partir de (Geralmente display / tela) para alguns arquivos e evitar ver as mensagens de erro na tela! redirecionar para um arquivo especial / dev / null:
find /. -name 'toBeSearched.file' 2>/dev/null
-
Você pode usar redirecionar a saída de erro padrão a partir de (Geralmente display / tela) para a saída padrão (Geralmente display / tela), então tubo com comando grep com -v "invertido" parâmetro para não ver as linhas de saída que tem 'permissão negada' pares de palavras:
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
Eu tive que usar:
find / -name expect 2>/dev/null
especificando o nome do que eu queria encontrar e, em seguida, dizendo-lhe para redirecionar todos os erros para / dev / null
esperam ser a localização do programa esperam que eu estava procurando.
Cachimbo stderr
para /dev/null
usando 2> / dev / null
find . -name '...' 2>/dev/null
Você também pode usar os predicados -perm
e -prune
para evitar descer para diretórios ilegíveis (ver também Como faço para remover "permissão negada" declarações impressão dos dados do programa encontrar - Unix e Linux Pilha Troca ):?
find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
Redirect erro padrão. Por exemplo, se você estiver usando bash em uma máquina UNIX, você pode redirecionar o erro padrão para / dev / null como este:
find . 2>/dev/null >files_and_folders
Enquanto acima abordagens não abordam o caso para Mac OS X porque o Mac OS X não suporta -readable
mudar isso é como você pode evitar 'Permissão negada' erros em sua saída. Isto pode ajudar alguém.
find / -type f -name "your_pattern" 2>/dev/null
.
Se você estiver usando algum outro comando com find
, por exemplo, para encontrar o tamanho de arquivos de certo padrão em um 2>/dev/null
diretório seria ainda trabalho como mostrado abaixo.
find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$
.
Isto irá retornar o tamanho total dos arquivos de um determinado padrão. Observe o 2>/dev/null
no final do comando find.
Esses erros são impressos com a saída de erro padrão (FD 2). Para filtrá-los, simplesmente redirecionar todos os erros para / dev / null:
find . 2>/dev/null > some_file
ou primeiro unir-se stderr e stdout e, em seguida, grep para fora aqueles erros específicos:
find . 2>&1 | grep -v 'Permission denied' > some_file
A resposta é simples:
find . > files_and_folders 2>&-
2>&-
fecha (-
) o padrão descritor de arquivo de erro (2
) para todas as mensagens de erro são silenciados.
- Código de saída ainda será
1
se quaisquer erros 'Permission denied
' de outra forma seriam impressos
resposta robusta para GNU find
:
find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders
Passe opções extras para find
que -prune
(evitar descer para), mas ainda -print
qualquer diretório ( -type
d
) que não ( \!
) têm ambos -readable
-executable
per missões, ou ( -o
) -print
qualquer outro arquivo.
-
-readable
e opções-executable
são extensões GNU, não fazem parte do o padrão POSIX - Maio ainda retornar '
Permission denied
' nos arquivos anormais / corruptos (por exemplo, consulte relatório de bug afectar sistemas de arquivo usandolxcfs
recipiente montado
resposta robusta que funciona com qualquer find
compatível com POSIX (GNU, OSX / BSD, etc)
{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1
Use a gasoduto para passar o padrão fluxo de erro para grep
, remover todas as linhas que contêm a cadeia 'Permission denied'
.
LC_ALL=C
define o POSIX locale usando um variável de ambiente , 3>&2 2>&1 1>&3
e 3>&2 2>&1
descritores de arquivos duplicados para canalizar o fluxo de erros padrão para grep
e usos [ $? = 1 ]
[]
para inverter o código de erro retornado por grep
para aproximar o comportamento original de find
.
- também irá filtrar quaisquer erros
'Permission denied'
devido ao redirecionamento de saída (por exemplo, se o arquivofiles_and_folders
-loauto não é gravável)
Para evitar apenas a permissão negada advertências, diga encontrar a ignorar os arquivos ilegíveis pela poda-los da pesquisa. Adicionar uma expressão como um OR para seu achado, como
find / \! -readable -prune -o -name '*.jbd' -ls
Este principalmente diz a (coincidir com um arquivo ilegível e podá-la da lista) ou (coincidir com um nome como * .jbd e exibi-lo [com ls]) . (Lembre-se que, por padrão as expressões são AND'd juntos a menos que você use -ou.) Você precisa das -ls na segunda expressão ou então achado pode adicionar uma ação padrão para mostrar qualquer jogo, que também irá mostrar-lhe todos os arquivos ilegíveis .
Mas se você estiver procurando os arquivos reais no seu sistema, normalmente não há razão para olhar em dev /, que tem muitos arquivos, então você deve adicionar uma expressão que exclui esse diretório, como:
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
Assim, (corresponder arquivo ilegível e ameixa da lista) ou (trajeto de jogo / dev e ameixa da lista) ou (arquivo de jogo como o * .jbd e exibi-lo) .
uso
sudo find / -name file.txt
É estúpido (porque você elevar a pesquisa) e não segura, mas muito mais curto para escrever.
Nenhuma das respostas acima trabalharam para mim. Tudo o que eu encontrar na Internet se concentra em: erros esconder. Nenhum lida corretamente o / saída de código de processo de devolução-código. Eu uso achado comando dentro scripts bash para localizar alguns diretórios e, em seguida, inspecionar seu conteúdo. Avalio comando find sucesso usando a saída código: um valor zero de obras, caso contrário falha
.A resposta href="https://stackoverflow.com/questions/762348/how-can-i-exclude-all-permission-denied-messages-from-find/25234419#25234419"> por Michael Brux obras, às vezes. Mas eu tenho um cenário em que ele falhar! Eu descobri o problema e fixa-lo eu mesmo. Preciso arquivos podar quando:
it is a directory AND has no read access AND/OR has no execute access
Veja a questão-chave aqui é: E / OU. Uma boa sugeriu seqüência condição eu li é:
-type d ! -readable ! -executable -prune
Esta não funciona sempre. Isto significa que uma ameixa seca é desencadeada quando uma correspondência é:
it is directory AND no read access AND no execute access
Esta sequência de expressões falha quando o acesso de leitura é concedido, mas sem executar o acesso é.
Depois de alguns testes, percebi sobre isso e mudou a minha solução de shell script para:
encontrar agradável / home * / -maxdepth 5 -follow \
\ (Do tipo d -a ! \ (-Readable -a -executable \) \) -prune \
-o \
\ (Do tipo d -a -readable -a -executable -a -name "$ {m_find_name}" \) -print
A chave aqui é colocar o "não é verdade" para uma expressão combinada:
has read access AND has execute access
Caso contrário, não tem acesso completo, o que significa: ameixa seca-lo. Isto provou trabalho para mim em um cenário que soluções sugeridas anteriores falharam.
Eu forneço abaixo detalhes técnicos para perguntas na seção de comentários. Peço desculpas se detalhes são excessivos.
- ¿Por que usar agradável de comando? Eu tive a idéia aqui . Inicialmente eu pensei que seria bom para reduzir a prioridade do processo quando se olha um sistema de arquivos inteiro. Percebi que não faz sentido para mim, como meu script é limitada a alguns diretórios. Eu reduzi -maxdepth a 3.
- ¿Por que pesquisa dentro / home * /? Esta não relevantes para esta discussão. Eu instalar todos os aplicativos manualmente através de compilação de código-fonte com usuários privilegiados não (não root). Eles são instalados dentro de "home /". I pode ter vários binários e versões que vivem juntos. Preciso localizar todos os diretórios, inspecionar e backup de uma forma mestre-escravo. Posso ter mais de um "/ home" (vários discos em execução dentro de um servidor dedicado).
- ¿Por que usar -follow? Os usuários podem criar links simbólicos para diretórios. É de utilidade depende, eu preciso manter registro dos caminhos absolutos encontrados.
Você pode usar o grep -v invertido-match
-v, --invert-match select non-matching lines
como este:
find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders
deve à magia
- = Para MacOS = -
Faça um novo comando usando apelido: basta adicionar em ~ line / .bash_profile:
alias search='find / -name $file 2>/dev/null'
e em nova janela Terminal você pode chamá-lo:
$ file=<filename or mask>; search
Por exemplo:
$ file = etc; Pesquisa
Se você estiver usando CSH ou tcsh, aqui está uma solução:
( find . > files_and_folders ) >& /dev/null
Se você quer saída para o terminal:
( find . > /dev/tty ) >& /dev/null
No entanto, como o "CSH-whynot" FAQ descreve, você não deve usar CSH.
Você também uma solução fácil para colocar seus resultados encontrar em um arquivo.
encontrar. -name 'NameOfSearchedFile' >> results.txt