GNU/Linux >> Linux Esercitazione >  >> Linux

trova:-exec rm {} \; vs. -delete - perché il primo è ampiamente raccomandato?

tl;dr:-delete non è richiesto da POSIX, -exec è.

Fatti

Pagina man POSIX 1003.1 per find specifica -exec ma non -delete .

Questo significa -exec dovrebbe funzionare praticamente ovunque. Sarei sorpreso di trovare find che ha -delete senza -exec . Il contrario è del tutto possibile. Sistemi particolarmente leggeri che utilizzano busybox tendono a fornire solo opzioni di base della riga di comando.

Per esempio. Ho un OpenWRT su uno dei miei router e il suo find comprende -exec , non comprende -delete .

Non avere -delete non è un grosso problema quando hai -exec rm … . D'altra parte -delete non può sostituire -exec in generale. È una buona idea consentire l'omissione di -delete prima.

Esperienze personali, osservazioni e opinioni

Quanto sopra dovrebbe essere il motivo principale per cui -exec rm {} \; è così ampiamente raccomandato. Il secondario potrebbe essere un effetto valanga. Gli utenti leggono articoli ed esempi, familiarizzano con -exec e pubblicare i propri comandi (ad esempio qui su Super User). Alcuni di loro potrebbero anche non conoscere -delete esiste.

Poche volte ho visto (o dato) commenti come 'Puoi usare -delete invece'. E le risposte erano tipo "Grazie, non lo sapevo". Non ricordo alcuna risposta "Lo so, ma questo non è POSIX".

Detto questo tendo a citare -delete ogni volta che -exec rm {} \; appare. Il motivo è -delete non genera un nuovo processo, mentre -exec rm {} \; invoca un rm separato per ogni file corrispondente. Se non puoi usare -delete allora il tuo prossimo pensiero dovrebbe essere -exec rm {} + che può rimuovere più file con un singolo rm (comunque invocherà rm più di una volta se necessario).

Perché non è -exec … + ampiamente consigliato quindi? Potrebbe essere a causa dei suoi limiti. Posso immaginare un utente inesperto che pensa 'Funziona con rm , fammelo usare con mv !' Poi -exec mv {} foo/ + non funziona perché {} deve essere alla fine, appena prima di + . L'utente si sente frustrato e torna di corsa da mamma Finestre.

Consiglio -delete di solito è al sicuro qui su Super User, credo. La maggior parte delle domande specifica OS-es "grandi", find i comandi sono ricchi di opzioni. E anche se c'è un utente il cui find è limitato, probabilmente riceverò un feedback. Lui o lei dice che la soluzione non funziona per loro e suggerisco -exec rm … invece, spiega il problema ecc.

Un articolo a sé stante che consiglia -delete non riceverà tale feedback. In caso di problemi, un utente passerà semplicemente al collegamento successivo restituito da Google.


La differenza sta nella flessibilità. Se usi -exec allora esegui un comando per ogni file selezionato. Se usi -exec, hai la flessibilità di applicare altre opzioni di ricerca. Con -delete sei limitato nell'uso di -prune. Inoltre, il posizionamento di -delete influisce sui risultati. Vedi lo snippet della documentazione di seguito:

-delete
    Delete  files;  true  if removal succeeded.  If the removal failed, 
    an error message is issued.  If -delete fails, find’s exit status will be
        nonzero (when it eventually exits).  Use of -delete automatically turns on 
    the ‘-depth’ option.

    Warnings: Don’t forget that the find command line is evaluated as an 
    expression, so putting -delete first will make find try to delete every-
    thing  below  the  starting  points  you  specified.   When testing a find 
    command line that you later intend to use with -delete, you should
    explicitly specify -depth in order to avoid later surprises.  
    Because -delete implies -depth, you cannot  usefully  use  -prune  and  -delete
    together.

-exec command ;
    Execute  command;  true  if 0 status is returned.  All following arguments 
    to find are taken to be arguments to the command until an argument
    consisting of ‘;’ is encountered.  The string ‘{}’ is replaced by the 
    current file name being processed everywhere it occurs in the arguments
    to  the  command, not just in arguments where it is alone, as in 
    some versions of find.  Both of these constructions might need to be escaped
    (with a ‘\’) or quoted to protect them from expansion by the shell.  
    See the EXAMPLES section for examples of the use of  the  -exec  option.
    The specified command is run once for each matched file.  The 
    command is executed in the starting directory.   There are unavoidable security
    problems surrounding use of the -exec action; you should use the -execdir 
    option instead.

-exec command {} +
    This variant of the -exec action runs the specified command on the 
    selected files, but the command line is built by appending  each  selected
    file name at the end; the total number of invocations of the command 
    will be much less than the number of matched files.  The command line is
    built in much the same way that xargs builds its command lines.  
    Only one instance of ‘{}’ is allowed within the  command.   The  command  is
    executed in the starting directory

Linux
  1. trovare -exec una funzione di shell in Linux?

  2. Dov'è il file di intestazione <conio.h> su Linux? Perché non riesco a trovare <conio.h>?

  3. Perché è necessario il segmento .bss?

  4. Linux perché non riesco a reindirizzare find result a rm?

  5. adb:trova PID dalla shell adb

Rompere la ricerca se un -exec fallisce?

Il comando Trova Directory di Linux:spiegato

trova -exec cmd {} + vs | xargs

Perché find -exec mv {} ./target/ + non funziona?

Come trovo la dimensione massima dello stack?

Come reindirizzare i risultati di "trova" a mv in Linux