Come posso escludere tutti i messaggi "permesso negato" da "trova"?


795

Devo nascondere tutti i messaggi di autorizzazione negata da:

find . > files_and_folders

Sto sperimentando quando sorge questo messaggio. Ho bisogno di raccogliere tutte le cartelle e i file, a cui non si presenta.

È possibile indirizzare i livelli di autorizzazione al files_and_foldersfile?

Come posso nascondere gli errori contemporaneamente?

Risposte:


259

Nota:
* Questa risposta probabilmente va più in profondità rispetto al caso d'uso e find 2>/dev/nullpuò essere abbastanza buona in molte situazioni. Potrebbe essere ancora interessante per una prospettiva multipiattaforma e per la sua discussione di alcune tecniche di shell avanzate nell'interesse di trovare una soluzione il più robusta possibile, anche se i casi a cui si può far fronte possono essere in gran parte ipotetici.
* Se il tuo sistema è configurato per mostrare messaggi di errore localizzati , aggiungi il prefisso delle findchiamate in basso con LC_ALL=C( LC_ALL=C find ...) per assicurarti che i messaggi in inglese vengano segnalati, in modo che grep -v 'Permission denied'funzioni come previsto. Invariabilmente, però, eventuali messaggi di errore che fanno ottenere visualizzati saranno quindi in inglese.

Se la tua shell è bashozsh , c'è una soluzione che è robusta pur essendo ragionevolmente semplice , usando solo findfunzionalità conformi a POSIX ; mentre di per bashsé non fa parte di POSIX, la maggior parte delle piattaforme Unix moderne ne è dotata, rendendo questa soluzione ampiamente portatile:

find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)

Nota: c'è una piccola possibilità che alcuni degli grepoutput possano arrivare dopo il find completamento, perché il comando generale non attende il completamento del comando interno >(...). In bash, puoi impedirlo aggiungendo | catil comando.

  • >(...)è una sostituzione del processo di output (usata raramente) che consente di reindirizzare l'output (in questo caso, stderr output ( ) allo stdin del comando all'interno . Oltre a e , li supporta anche in linea di principio , ma provando a combinarli con il reindirizzamento da stderr , come si fa qui ( ), sembra essere silenziosamente ignorato (in ).2>>(...)
    bashzshksh2> >(...)ksh 93u+

    • grep -v 'Permission denied'filtra out ( -v) tutte le linee (dal findflusso stderr del comando) che contengono la frase Permission deniede visualizza le righe rimanenti stderr ( >&2).

Questo approccio è:

  • robusto : grepviene applicato solo ai messaggi di errore (e non a una combinazione di percorsi di file e messaggi di errore, che potenzialmente portano a falsi positivi) e vengono trasmessi a stderr messaggi di errore diversi da quelli negati dalle autorizzazioni.

  • side-effect free : findil codice di uscita è preservato: l'impossibilità di accedere ad almeno uno degli elementi del filesystem riscontrati provoca il codice di uscita 1(anche se ciò non ti dirà se si sono verificati (anche) errori diversi da quelli negati dal permesso).


Soluzioni conformi a POSIX:

Le soluzioni completamente conformi a POSIX presentano limitazioni o richiedono un lavoro aggiuntivo.

Se find's uscita deve essere catturato in un file di ogni caso (o soppresso del tutto), allora la soluzione a base di gasdotto dalla risposta di Jonathan Leffler è semplice, robusto, e POSIX-compliant:

find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2

Nota che l'ordine dei reindirizzamenti conta: 2>&1deve venire prima .

Catturare l'output di stdout in un file in primo piano consente 2>&1di inviare solo messaggi di errore attraverso la pipeline, che greppossono quindi operare senza ambiguità.

L' unico inconveniente è che il codice di complessiva di uscita sarà il grepdel comando , non finds', che in questo caso significa: se non ci sono nessun errori a tutti o solo errori di autorizzazione negata, il codice di uscita verrà 1(segnalamento fallimento ), in caso contrario ( errori diversi da quelli negati dal permesso) 0- che è l'opposto dell'intento.
Detto questo, findil codice di uscita viene utilizzato raramente in ogni caso , poiché spesso trasmette poche informazioni al di là di un fallimento fondamentale come il passaggio di un percorso inesistente.
Tuttavia, il caso specifico di anche solo alcunidei percorsi di input inaccessibili a causa della mancanza di autorizzazioni si riflette nel findcodice di uscita (sia in GNU che in BSD find): se si verifica un errore negato alle autorizzazioni per uno qualsiasi dei file elaborati, il codice di uscita è impostato su 1.

La seguente variazione si rivolge a:

find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }

Ora, il codice di uscita indica se si sono verificati errori diversi Permission denied : in 1tal caso, 0altrimenti.
In altre parole: il codice di uscita ora riflette il vero intento del comando: 0viene segnalato success ( ), se non si sono verificati errori o si sono verificati solo errori negati.
Questo è probabilmente anche meglio del semplice passaggio finddel codice di uscita, come nella soluzione in alto.


gniourf_gniourf nei commenti propone una generalizzazione (ancora conforme a POSIX) di questa soluzione usando reindirizzamenti sofisticati , che funziona anche con il comportamento predefinito di stampa dei percorsi dei file su stdout :

{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1

In breve: il descrittore di file personalizzato 3viene utilizzato per scambiare temporaneamente stdout ( 1) e stderr ( 2), in modo che solo i messaggi di errore possano essere inviati greptramite stdout.

Senza questi reindirizzamenti, sia i dati (percorsi dei file) che i messaggi di errore verrebbero inviati greptramite stdout e grepquindi non sarebbero in grado di distinguere tra messaggio di errore Permission denied e un file (ipotetico) il cui nome contiene la frase Permission denied.

Come nella prima soluzione, tuttavia, il codice di uscita segnalato sarà grep"non find", ma è possibile applicare la stessa correzione di cui sopra.


Note sulle risposte esistenti:

  • Ci sono diversi punti da notare su risposta di Michael Brux , find . ! -readable -prune -o -print:

    • Richiede GNU find ; in particolare, non funzionerà su macOS. Ovviamente, se hai solo bisogno del comando per lavorare con GNU find, questo non sarà un problema per te.

    • Alcuni Permission deniederrori possono ancora emergere: find ! -readable -prunesegnala tali errori per gli elementi figlio delle directory per i quali l'utente attuale dispone rdell'autorizzazione, ma manca l' xautorizzazione (eseguibile). Il motivo è che, poiché la directory stessa è leggibile, -prunenon viene eseguita e il tentativo di scendere in quella directory attiva quindi i messaggi di errore. Detto questo, il caso tipico è che rmanchi l' autorizzazione.

    • Nota: il punto seguente è una questione di filosofia e / o caso d'uso specifico e potresti decidere che non è pertinente per te e che il comando si adatta bene alle tue esigenze, soprattutto se semplicemente stampando i percorsi è tutto ciò che fai:

      • Se si concettualizza il filtraggio dei messaggi di errore negati all'autorizzazione un'attività separata che si desidera poter applicare a qualsiasi find comando, l'approccio opposto di prevenzione proattiva degli errori negati all'autorizzazione richiede l'introduzione di "rumore" nel findcomando, che introduce anche complessità e insidie logiche .
      • Ad esempio, il commento più votato sulla risposta di Michael (al momento della stesura di questo documento) tenta di mostrare come estendere il comando includendo un -namefiltro, come segue:
        find . ! -readable -prune -o -name '*.txt'
        Questo, tuttavia, non funziona come previsto, poiché -printè richiesta l' azione finale (una spiegazione può essere trovata in questa risposta ). Tali sottigliezze possono introdurre bug.
  • La prima soluzione in risposta di Jonathan Leffler , find . 2>/dev/null > files_and_folders, come egli stesso afferma, zittisce ciecamente tutti i messaggi di errore (e la soluzione è ingombrante e non pienamente affidabile, come egli spiega anche). In termini pragmatici , tuttavia, è la soluzione più semplice , poiché potresti accontentarti di presumere che tutti gli errori siano legati alle autorizzazioni.

  • La risposta di foschia , sudo find . > files_and_folders, è conciso e pragmatico, ma mal consigliato per altro che solamente la stampa i nomi dei file , per motivi di sicurezza: perché si sta eseguendo come radice dell'utente ", si rischia di avere l'intero sistema di essere incasinato da un bug nel ritrovamento o una versione malevola o una chiamata errata che scrive qualcosa di inaspettatamente, il che non potrebbe accadere se lo eseguissi con privilegi normali "(da un commento sulla risposta di mist da parte di tripleee ).

  • La seconda soluzione nella risposta di viraptor , find . 2>&1 | grep -v 'Permission denied' > some_filecorre il rischio di falsi positivi (a causa dell'invio di un mix di stdout e stderr attraverso la pipeline) e, potenzialmente, invece di segnalare errori non negati per ammissione tramite stderr, li cattura lungo i percorsi di output nel file di output.


4
Solo una domanda veloce: perché usi una sostituzione di processo e non solo una pipe find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2:?
gniourf_gniourf il

2
@ LéoLéopoldHertz 준영: Se non si desidera eseguire l'output su un file esterno, fare semplicemente più impianti idraulici:{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
gniourf_gniourf

2
@ LéoLéopoldHertz 준영: Solo che è conforme a POSIX. Le sostituzioni di processo >(...)sono specifiche di Bash.
gniourf_gniourf il

2
Non sono sicuro che la conservazione del codice di uscita di finddovrebbe essere enfatizzata e pubblicizzata: findil codice di uscita è notoriamente inutile. Qui, molto probabilmente sarà diverso da zero (e inutilmente).
gniourf_gniourf,

3
POSIX richiede esplicitamente l' execute/searchautorizzazione in modalità file per "cercare" una directory (recuperare gli inode dei file contenuti). findfa questo per scendere in una sottodirectory (oltre a richiedere l' readautorizzazione per elencare i file in una directory). Questo non è un "bug" o "errore di porting".
jjordan,

542

Uso:

find . 2>/dev/null > files_and_folders

Ciò nasconde non solo gli Permission deniederrori, ovviamente, ma tutti i messaggi di errore.

Se vuoi davvero mantenere altri possibili errori, come troppi salti su un collegamento simbolico, ma non quelli negati dal permesso, allora probabilmente dovresti pensare che non hai molti file chiamati 'permesso negato' e prova:

find . 2>&1 | grep -v 'Permission denied' > files_and_folders

Se si desidera filtrare rigorosamente solo l'errore standard, è possibile utilizzare la costruzione più elaborata:

find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2

La redirezione I / O sul findcomando è: 2>&1 > files_and_folders |. La pipe reindirizza l'output standard al grepcomando e viene applicata per prima. La 2>&1manda errore standard nello stesso posto come uscita standard (tubo). L' > files_and_foldersinvia output standard (ma errore non standard) in un file. Il risultato netto è che i messaggi scritti con errori standard vengono inviati alla pipe e l'output regolare di findviene scritto nel file. L' grepfiltra l'output standard (si può decidere come selettiva si vuole che sia, e potrebbe essere necessario cambiare l'ortografia in base al paese e O / S) e la finale>&2significa che i messaggi di errore sopravvissuti (scritti nell'output standard) passano nuovamente all'errore standard. Il reindirizzamento finale potrebbe essere considerato facoltativo sul terminale, ma sarebbe una buona idea usarlo in uno script in modo che i messaggi di errore compaiano su errori standard.

Ci sono infinite variazioni su questo tema, a seconda di cosa vuoi fare. Funzionerà su qualsiasi variante di Unix con qualsiasi derivato della shell Bourne (Bash, Korn, ...) e qualsiasi versione conforme a POSIX di find.

Se desideri adattarti alla versione specifica findche hai sul tuo sistema, potrebbero essere disponibili opzioni alternative. GNU findin particolare ha una miriade di opzioni non disponibili in altre versioni - vedi la risposta attualmente accettata per una di queste serie di opzioni.


9
Se sei come me, nota che la mancanza di spazio è importante! 2>/dev/null, senza spazio!
Nik,

20
La 2>è una singola unità senza spazi; puoi avere uno spazio tra esso e il nome del file. Analogamente ad altri reindirizzamenti, come 2>&1(che reindirizza l'errore standard nella stessa posizione in cui sta andando l'output standard) o 2>&-che chiude l'errore standard, ecc. Vedere Reindirizzamenti per i dettagli gory rimanenti. (Il codice sopra è una shell generica simile a POSIX, non specifica per bash.)
Jonathan Leffler

3
Ho dovuto usare una P maiuscola perché è quello che il mio terminale avrebbe prodotto: find. 2> & 1 | grep -v "Autorizzazione negata"
David Doria,

4
In che modo questa è una soluzione accettabile? 1) Stai reindirizzando TUTTI gli errori a dev / null 2) Stai filtrando una stringa di errore esplicita !! A seconda di questi è notoriamente fragile e se il tuo file si trovasse in una directory denominata "permesso negato"? Oops!
Gunchars,

10
Sto obiettando contro stringhe di errore grepping per modificare l'output del programma. Funzionerà la maggior parte del tempo, ma semplice non è la soluzione corretta (trovare con permanenti sotto è). Per darvi un esempio del perché, questo non funzionerà su OSX perché l'errore è "Autorizzazione negata". Lo stesso per qualsiasi altro sistema in cui ci sono anche minuscole differenze nella stringa di errore (internazionalizzazione qualcuno?)
Gunchars

286

Uso:

find . ! -readable -prune -o -print

o più in generale

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • per evitare "Autorizzazione negata"
  • E NON sopprimere (altri) messaggi di errore
  • E ottenere lo stato di uscita 0 ("tutti i file vengono elaborati correttamente")

Funziona con: find (GNU findutils) 4.4.2. Sfondo:

  • Il -readabletest corrisponde ai file leggibili. L' !operatore restituisce true, quando test è false. E ! -readablecorrisponde a directory (e file) non leggibili.
  • L' -pruneazione non scende nella directory.
  • ! -readable -prune può essere tradotto in: se la directory non è leggibile, non scendere in essa.
  • Il -readabletest tiene conto degli elenchi di controllo di accesso e di altri artefatti delle autorizzazioni che il -permtest ignora.

Vedi anche find(1) manpage per molti più dettagli.


6
le differenze sono già menzionate. se non capisci, allora le risposte forse non fanno differenza per te? STDOUT è lo stesso - STDERR è diverso (ricevi gli altri messaggi di errore con questa risposta) - $? è diverso (è 0 "riuscito" con questa risposta, quando non si verificano altri errori - è sempre> 0 "non riuscito" quando si reindirizza a dev / null) - forse qualcuno ha bisogno di "corretto" $? in una sceneggiatura
Michael Brux,

6
@Masi il difetto più evidente è la risposta di Jonathan (grep -v) escluderà il nome del file che contiene 'Autorizzazione negata' :)
Fruit

65
Ritengo opportuno aggiungere qui che se è necessario aggiungere altri criteri di ricerca, ciò dovrebbe essere fatto con -o:find . ! -readable -prune -o -name '*.txt'
tempestadept

22
Si noti che POSIX findnon include -readablecome opzione; né lo fa findper BSD e quindi Mac OS X (non sono sicuro di altri sistemi). Quindi, dove hai GNU findgarantito, funziona alla grande, ma non è ovvio come adattarlo se non puoi garantire che il sistema abbia GNU findinstallato. (Funzionerà bene su Linux; potrebbe funzionare o meno altrove.)
Jonathan Leffler,

6
find . ! -readable -prune -o -name '*.txt'non sembra funzionare su Ubuntu 14.04 usando find 4.2.2. Sembra di importare il -name. Per qualche strana ragione per cui ho successofind . \( ! -readable -prune \) -o -name '*.txt' -print
con-f-use

110

Se vuoi iniziare la ricerca dalla radice "/", probabilmente vedrai un output come:

find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied

È a causa del permesso. Per risolvere questo:

  1. Puoi usare il comando sudo:

    sudo find /. -name 'toBeSearched.file'

Chiede la password dell'utente super, quando inserisci la password vedrai il risultato che vuoi veramente. Se non si dispone dell'autorizzazione per utilizzare il comando sudo, il che significa che non si dispone della password del superutente, innanzitutto chiedere all'amministratore di sistema di aggiungerti al file sudoers.

  1. È possibile utilizzare il reindirizzamento dell'output di errore standard da (Generalmente display / schermo) su alcuni file ed evitare di visualizzare i messaggi di errore sullo schermo! reindirizzare a un file speciale / dev / null:

    find /. -name 'toBeSearched.file' 2>/dev/null
  2. È possibile utilizzare il reindirizzamento dell'output di errore standard da (Generalmente display / schermo) all'output standard (generalmente display / schermo), quindi eseguire il pipe con il comando grep con il parametro -v "invert" per non vedere le righe di output che hanno "Autorizzazione negata" coppie di parole:

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'

7
@scottmrogowski tranne per il fatto che non risponde alla domanda ... 1. chiedi all'amministratore di sistema di aggiungerti al file sudoers. 2.sudo find...
Stephen,

1
esattamente quello che stavo cercando!
DankMasterDan

92

Ho dovuto usare:

find / -name expect 2>/dev/null

specificando il nome di ciò che volevo trovare e poi dicendogli di reindirizzare tutti gli errori su / dev / null

mi aspetto di essere la posizione del programma prevede che stavo cercando.


3
@Masi, il comando nella risposta non utilizza expect. Invece, expectè semplicemente il nome del file che questo comando tenterà di trovare.
Dhruv Kapoor,

2
Reindirizzare ciecamente tutto l'output stderr solo per ignorare una singola classe di messaggi di errore è generalmente una cattiva idea: perderai tutti gli altri errori arbitrari nel processo.
Josip Rodin,

59

Tubo stderrdi /dev/nullbase 2> / dev / null

find . -name '...' 2>/dev/null


2
Questo funziona bene anche per me su Mac OSX. O addiritturafind . -name '...' -print 2>/dev/null
shadowsheep,

30

È inoltre possibile utilizzare i predicati -perme -pruneper evitare di scendere in directory illeggibili (vedere anche Come rimuovere le istruzioni di stampa "permesso negato" dal programma find? - Unix & Linux Stack Exchange ):

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders

4
-perm -g+r,u+r,o+rabbina semplicemente i file con l' rautorizzazione (lettura) impostata per tutti e 3 i principi di sicurezza del file , che non ha alcuna relazione diretta con l' utente corrente in grado di leggere quel file o meno. Ha il potenziale sia per perdere i file che l'utente corrente può leggere sia per abbinare i file che non possono.
mklement0

Penso che find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -printsarebbe la buona soluzione.
Mattia72,

2
@ Mattia72: No, è fondamentalmente impossibile emulare completamente -readablecon -perm- vedi il mio commento precedente e considera questo esempio: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rstampa file, perché il suo bit di lettura dell'utente è impostato, ma si riferisce nobodyall'utente, non all'utente corrente. L'utente corrente non può leggere questo file; provare cat file. Vedi anche: questa mia risposta .
mklement0,

23

Reindirizzare l'errore standard. Ad esempio, se stai usando bash su una macchina unix, puoi reindirizzare l'errore standard su / dev / null in questo modo:

find . 2>/dev/null >files_and_folders

20

Sebbene gli approcci di cui sopra non affrontino il caso di Mac OS X perché Mac Os X non supporta lo -readableswitch, in questo modo è possibile evitare errori "Autorizzazione negata" nell'output. Questo potrebbe aiutare qualcuno.

find / -type f -name "your_pattern" 2>/dev/null.

Se si utilizza un altro comando con find, ad esempio, per trovare la dimensione dei file di un determinato modello in una directory 2>/dev/nullfunzionerebbe comunque come mostrato di seguito.

find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$.

Ciò restituirà la dimensione totale dei file di un determinato modello. Nota il 2>/dev/nullcomando alla fine di find.


Bell'associazione con OS X! La risposta di Jonathan spiega la parte 2>/dev/null. Puoi per favore spiegare la parte -exec du -ch {} + 2>/dev/null | grep total$.
Léo Léopold Hertz

1
@Masi È possibile utilizzare qualsiasi comando con -execopzione per intraprendere ulteriori azioni sui file o directory trovati dal findcomando. du -ch file_patterncalcola la dimensione di ciascun file corrispondente file_patterne l'ultima riga dell'output è il totale generale di tutti i file che corrispondono al file_pattern. Vedi la pagina man per du. grep totalfiltra solo la riga che estrae il totale generale (che è l'ultima riga).
Bunti

13

Tali errori vengono stampati sull'output di errore standard (fd 2). Per filtrarli, reindirizza semplicemente tutti gli errori su / dev / null:

find . 2>/dev/null > some_file

o prima unisciti a stderr e stdout e poi elimina quegli errori specifici:

find . 2>&1 | grep -v 'Permission denied' > some_file

11

Risposta semplice:

find . > files_and_folders 2>&-

2>&-chiude ( -) il descrittore di file di errore standard ( 2) in modo che tutti i messaggi di errore vengano silenziati.

  • Il codice di uscita rimarrà comunque 1se in caso Permission deniedcontrario venissero stampati degli errori

Risposta affidabile per GNU find:

find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders

Passa opzioni extra a findquesto -prune(evita di scendere in) ma comunque -printqualsiasi directory ( ) che non ha ( ) ha entrambi e permessi, o ( ) qualsiasi altro file.-typed\!-readable-executable-o-print

Risposta affidabile che funziona con qualsiasi POSIX compatibile find(GNU, OSX / BSD, ecc.)

{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1

Utilizzare una pipeline per passare il flusso di errore standard grep, rimuovendo tutte le righe contenenti la 'Permission denied'stringa.

LC_ALL=Cset la localizzazione POSIX utilizzando una variabile d'ambiente , 3>&2 2>&1 1>&3e 3>&2 2>&1 descrittori di file duplicati per il tubo del flusso standard di errore grep, e [ $? = 1 ]usi []di invertire il codice di errore restituito da grepapprossimare il comportamento originale di find.

  • Filtrerà anche eventuali 'Permission denied'errori dovuti al reindirizzamento dell'output (ad esempio, se il files_and_foldersfile stesso non è scrivibile)

Come giudica la proposta di risposta di JordiFerran? - - Puoi confrontare la tua risposta?
Léo Léopold Hertz 준영

2
Lo script della shell di quella risposta come indicato non è generico (elenca solo le directory corrispondenti a $ {m_find_name}) e contiene diverse opzioni non pertinenti alla domanda (nice, / home *, -maxdepth 5, -follow). Questa risposta affronta in modo più conciso la questione specifica del "filtraggio di directory leggibili ma non eseguibili", pur rimanendo di uso generale.
gennaio

1
@wjordan: grazie. Ho rimosso i miei commenti, ma vale ancora un punto: -permnon vale la pena presentare la soluzione basata su, perché fondamentalmente più che la citazione suggerisce fa qualcosa di diverso dal previsto: è un test puramente incentrato sui file , relativo al proprietario del file e gruppo, nessuno dei quali ha alcuna relazione garantita con l'utente che chiama il comando (vedi questa mia risposta . Sembra che la tua soluzione GNU rivista ora non
rilevi gli

Non riconosco la sintassi che stai utilizzando (né come GNU né come BSD), ma mi permetta di illustrare il mio punto con un esempio autonomo: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rstampe file, perché il bit di lettura dell'utente è impostato, ma si riferisce nobodyall'utente , non l'utente corrente. L'utente corrente non può leggere questo file; provare cat file.
mklement0,

1
@ mklement0 grazie per la discussione, sono riuscito a produrre il comportamento che hai descritto in un altro test (non so cosa ho fatto di sbagliato la prima volta), sembra che -permnon funzioni per determinare le autorizzazioni correnti dell'utente. Rimossa tale alternativa da questa risposta.
Giordania,

4

Per evitare solo gli avvisi di autorizzazione negata, dire a find di ignorare i file illeggibili eliminandoli dalla ricerca. Aggiungi un'espressione come OR alla tua ricerca, ad esempio

find / \! -readable -prune -o -name '*.jbd' -ls

Questo per lo più dice (abbina un file illeggibile e potalo dall'elenco) OPPURE (abbina un nome come * .jbd e visualizzalo [con ls]) . (Ricorda che per impostazione predefinita le espressioni sono AND riunite a meno che tu non usi -o.) È necessario il -ls nella seconda espressione o altrimenti find può aggiungere un'azione predefinita per mostrare una delle due corrispondenze, che ti mostrerà anche tutti i file illeggibili .

Ma se stai cercando file reali sul tuo sistema, di solito non c'è motivo di cercare in / dev, che ha molti file, quindi dovresti aggiungere un'espressione che esclude quella directory, come:

find / -mount \! -readable -prune  -o  -path /dev -prune  -o  -name '*.jbd' -ls

Quindi (abbina il file illeggibile e elimina dall'elenco) OPPURE (abbina il percorso / sviluppo e elimina dall'elenco) OR (abbina il file come * .jbd e visualizzalo) .


4

uso

sudo find / -name file.txt

È stupido (perché elevi la ricerca) e non è sicuro, ma molto più breve da scrivere.


Cerca qui l'intero filesystem quindi intendi con questo "elevare la ricerca". Perché lo chiami non sicuro? Perché sta cercando l'intero filesystem?
Léo Léopold Hertz 준영

2
Perché sudo esegue il comando find con permessi di root, che in pratica è una cattiva idea. Vengono violati i principi di segregazione e minimo privilegio.
nebbia,

3
L '"elevazione" qui è dei privilegi, alla radice, con sudo. Si rischia che l'intero sistema venga incasinato da un bug findo da una versione dannosa o da una chiamata errata che scrive qualcosa inaspettatamente, cosa che non potrebbe accadere se si eseguisse questo con privilegi normali.
Tripleee

2

Nessuna delle risposte sopra ha funzionato per me. Tutto ciò che trovo su Internet si concentra su: nascondere errori. Nessuno gestisce correttamente il codice di ritorno / codice di uscita del processo. Uso il comando find all'interno degli script bash per individuare alcune directory e quindi controllare il loro contenuto. Valuto il comando trova successo usando il codice di uscita: un valore zero funziona, altrimenti fallisce.

La risposta fornita sopra da Michael Brux a volte funziona. Ma ho uno scenario in cui fallisce! Ho scoperto il problema e l'ho risolto da solo. Devo eliminare i file quando:

it is a directory AND has no read access AND/OR has no execute access

Vedere il problema chiave qui è: AND / OR. Una buona sequenza di condizioni suggerite che ho letto è:

-type d ! -readable ! -executable -prune

Questo non funziona sempre. Ciò significa che una prugna si innesca quando una partita è:

it is directory AND no read access AND no execute access

Questa sequenza di espressioni ha esito negativo quando viene concesso l'accesso in lettura ma non esiste alcun accesso in esecuzione.

Dopo alcuni test mi sono reso conto di ciò e ho cambiato la mia soluzione di script di shell in:

bella ricerca / home * / -maxdepth 5 -segui \
    \ (-type d -a ! \ (-readable -a -executable \) \) -prune \
    -o \
    \ (-type d -a -readable -a - eseguibile -a -name "$ {m_find_name}" \) -print

La chiave qui è di posizionare il "non vero" per un'espressione combinata:

has read access AND has execute access

Altrimenti non ha pieno accesso, il che significa: potarlo. Ciò ha dimostrato di funzionare per me in uno scenario in cui le precedenti soluzioni suggerite fallivano.

Fornisco i dettagli tecnici di seguito per le domande nella sezione commenti. Mi scuso se i dettagli sono eccessivi.

  • ¿Perché usare il comando nice? Ho avuto l'idea qui . Inizialmente ho pensato che sarebbe stato bello ridurre la priorità del processo quando si guardava un intero filesystem. Mi sono reso conto che non ha senso per me, dato che la mia sceneggiatura è limitata a poche directory. Ho ridotto -maxdepth a 3.
  • ¿Perché cercare in / home * /? Questo non è rilevante per questa discussione. Installo manualmente tutte le applicazioni tramite la compilazione del codice sorgente con utenti non privilegiati (non root). Sono installati in "/ home". Posso avere più binari e versioni che vivono insieme. Devo individuare tutte le directory, ispezionare e eseguire il backup in modo master-slave. Posso avere più di un "/ home" (diversi dischi in esecuzione all'interno di un server dedicato).
  • ¿Perché usare -follow? Gli utenti possono creare collegamenti simbolici alle directory. La sua utilità dipende, devo tenere traccia dei percorsi assoluti trovati.

Grazie per la tua risposta e belle osservazioni! Ho aperto una taglia qui per vedere meglio l'anteprima della tua risposta. Penso che sia una buona scoperta non impedire l'accesso in lettura ed esecuzione. - - Puoi spiegare perché usi nicee find $HOME -maxdepth 5 -follow ...?
Léo Léopold Hertz 준영

2
Lo script di shell come detto non è di uso generale (solo elenca le directory di corrispondenza ${m_find_name}), e contiene diverse opzioni non rilevanti per la domanda ( nice, /home*, -maxdepth 5, -follow). Ho aggiunto una risposta che affronta in modo più conciso il problema specifico di "filtrare le directory leggibili ma non eseguibili", pur rimanendo di uso generale.
jjordan

2

Puoi usare grep -v invert-match

-v, --invert-match        select non-matching lines

come questo:

find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders

Dovrebbe alla magia


2

- = Per MacOS = -

Effettua un nuovo comando usando l'alias: aggiungi semplicemente la riga ~ / .bash_profile:

alias search='find / -name $file 2>/dev/null'

e nella nuova finestra Terminale puoi chiamarlo:

$ file=<filename or mask>; search

per esempio:

$ file = etc; ricerca


1

Se stai usando CSH o TCSH, ecco una soluzione:

( find . > files_and_folders ) >& /dev/null

Se si desidera l'output al terminale:

( find . > /dev/tty ) >& /dev/null

Tuttavia, come descrive la FAQ "csh-whynot", non dovresti usare CSH.


Voglio grep tutti i file txt ed escludere file / directory nascosti, omettere il messaggio "Autorizzazione negata" da stampare. Sto usando la shell csh. Ho usato i comandi seguenti e non funzionano trovare. -type f -iname " .txt" -not -path '* / \. '| egrep -v "Autorizzazione negata" find. -type f -iname " .txt" -not -path '* / \. '2> / dev / null Ottenere sotto l'errore. find: i percorsi devono precedere l'espressione: 2 Uso: find [-H] [-L] [-P] [-Olevel] [-D help | tree | search | stat | rate | opt | exec] [path ...] [espressione]
yadav,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.