Il comando `find` non restituisce risultati quando si aggiunge -exec


1

Quando corro findcon questi argomenti, restituisce migliaia di file:

steven@nook:/mnt/station/media $ sudo find . -not -user steven -or -not -group users | wc
   3508   17479  245851
steven@nook:/mnt/station/media $

Quando aggiungo un -execargomento, si comporta come se findnon restituisse alcun risultato e il codice di ritorno indica il successo:

steven@nook:/mnt/station/media $ sudo find . -not -user steven -or -not -group users -exec echo {} \;
steven@nook:/mnt/station/media $ echo $?
0
steven@nook:/mnt/station/media $

(Il mio obiettivo è quello di utilizzare -exec chown -v steven:users {} \;i risultati (quindi sudo), ma sto usando -exec echo {} \;sopra per illustrare il problema in modo più chiaro ed escludere chowncome fattore che contribuisce.)

Sto usando gnu find in stock bash su Ubuntu Xenial:

steven@nook:/mnt/station/media $ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)
steven@nook:/mnt/station/media $ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
steven@nook:/mnt/station/media $ echo $SHELL
/bin/bash
steven@nook:/mnt/station/media $

Risposte:


4

Questo perché le operazioni adiacenti si legano con un implicito -andpiù stretto di quello esplicito -ore perché, dalla find(1)pagina man, "Se l'espressione non contiene azioni diverse da -prune, -print viene eseguita su tutti i file per i quali l'espressione è vera."

Ciò significa che findguarda l'espressione nel tuo primo esempio e vede

(-not -user steven) -or (-not -group users)

ed esegue -printil risultato, come previsto.

Find vede il tuo secondo esempio, tuttavia, come

(-not -user steven) -or ((-not -group users) -and -exec echo {})

Ciò dovrebbe fare eco a tutti i file appartenenti all'utente steven e non appartenenti agli utenti del gruppo.

La soluzione è aggiungere parentesi di escape attorno all'espressione prima di -exec:

sudo find . \( -not -user steven -or -not -group users \) -exec echo {} \;

Questo ha funzionato, grazie. Grande spiegazione di come ha analizzato il raggruppamento implicito senza raggruppare gli operatori.
Steven K

Penso che la tua risposta trarrebbe beneficio se menzionassi esplicitamente il seguente comportamento cruciale di expr1 -or expr2: " expr2non viene valutato se expr1è vero". Mi ci è voluto del tempo per capire perché hai scritto "Appartenenza all'utente Steven". Non è così ovvio.
Kamil Maciorowski il

1

È necessario apportare due correzioni alla riga di comando.

Innanzitutto, le parentesi graffe del comando exec devono essere evase o quotate per proteggerle dall'espansione della shell. Questo è esplicitamente menzionato nella pagina man di find .
C'è anche un esempio nella pagina man per chiarire questo requisito.

   find . -type f -exec file '{}' \;

   Runs  `file'  on  every file in or below the current directory.  Notice
   that the braces are enclosed in single quote marks to protect them from
   interpretation as shell script punctuation.  The semicolon is similarly
   protected by the use of a backslash, though single  quotes  could  have
   been used in that case also.

In secondo luogo, l'ambito e la precedenza -ordell'espressione devono essere chiariti con parentesi (che devono anche essere sfuggite).

Con le correzioni, dovrebbe funzionare quanto segue:

sudo find . \( -not -user steven -or -not -group users \) -exec echo '{}' \;

FWIW Preferisco reindirizzare l'output del comando find e usare xargs piuttosto che gestire la sintassi di -exec.

find . -not -user steven -or -not -group users | xargs sudo echo
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.