Impedire all'utente di digitare uno spazio accidentale tra rm e jolly


29

Intenzione:

rm -rf string*

Problema:

rm -rf string *

Il primo caso è un uso legittimo e comune di rm, un piccolo errore di battitura può causare molti problemi nel secondo caso. Esiste un modo semplice per proteggersi in modo intelligente da un trascinamento accidentale o da un jolly iniziale?


8
Con una shell recente o ben configurata ( zsho bash) preferirei prendere l'abitudine di premere il tasto Tab (per attivare il completamento automatico) prima di premere il tasto Invio
Basile Starynkevitch

2
touch -- -icreerà un file -iche verrà passato rmcome parametro -iquando includi un carattere jolly nei tuoi argomenti.
Ripristina Monica - M. Schröder il

@ MartinSchröder: se ti trovi nella directory in cui esiste il file.
In pausa fino a nuovo avviso.

@ MartinSchröder Funzionerà solo se digiti rm *. Se digiti rm name *, si espanderà a rm name -i other names. -inon verrà elaborato come opzione perché non è precedente ai nomi dei file.
Barmar,

1
In genere, un utente lo fa solo una volta.
tedder42,

Risposte:


37

È DEBUGpossibile scrivere una trappola per annullare comandi che sembrano sospetti. È possibile aggiungere al tuo codice seguente o simile ad esso ~/.bashrc:

shopt -s extdebug
checkcommand() {
  if [[ $BASH_COMMAND = 'rm -r'*' *' ]]; then
    echo "Suppressing rm -r command ending in a wildcard" >&2
    return 1
  fi
  # check for other commands here, if you like
  return 0
}
trap checkcommand DEBUG

Regola la logica secondo i tuoi gusti.

(In realtà non mi aspetto che questo approccio sia utile - troppi modi per incasinare un comando in modo distruttivo per trovarli a test uno per uno - ma fornisce una risposta letterale alla domanda).


47

Non c'è modo di un sistema totalmente antiproiettile. E aggiungendo "Sei sicuro?" il suggerimento è controproducente e porta a "Certo che ne sono sicuro". reazioni al ginocchio.

Un trucco che ho raccolto da un libro negli anni passati è quello di fare prima ls -R blah*allora, fare rm -fr blah* se e solo se l'elenco che ho pubblicato ha colpito quello che volevo colpire.

È abbastanza semplice eseguire lsprima il comando, quindi eliminare ls -Re sostituire con rm -fr.

L'ultima domanda è "Se le informazioni sono state preziose per te, dov'è il tuo backup?"


4
Invece di usare la freccia su, puoi usarlo ^ls -R^rm -rf^e impostarlo come alias
esussum

FWIW, questo è ls -Rciò che praticamente faccio sempre, ma è così istintivo a questo punto che mi è sfuggito la mente cosciente quando mi sono formato per risposta. Quindi +1 per quello.
Jake Gould

Ciò ha anche il vantaggio di non danneggiare se si preme il tasto Invio o si urtano il mouse e si incolla qualcosa con le nuove righe. A volte mi inserisco le cose in un modo meno efficiente solo per una maggiore sicurezza, ad esempio cat > .log, poi tornare indietro e pasta o Yank il nome del file prima del .log. Quindi non ho mai > valuablefilesulla linea di comando.
Peter Cordes,

Uso rm alias per rm -i, quindi spesso compongo solo il mio comando rm e poi inserisco \ a all'inizio della riga. ( \rmevita l'espansione alias per rm, poiché è stata citata parte della parola). Se avessi bisogno di un -ro -f, sì, a volte comincio con lsinvece di rm, o semplicemente lascio perdere la -rfparte. (modifica, come si ottiene una formattazione del codice di barra rovesciata? bquote bslash bslash bquote fallisce.
Peter Cordes,

8

Puoi allenarti ad usare, per esempio, rmrfal posto di rm -rf?

In tal caso, questa funzione bash ti darà la possibilità di vedere cosa sarebbe effettivamente accaduto prima di confermare il comando:

rmrf() { echo rm -rf "$@"; read -p "Proceed (y/N)? "; [ "${REPLY,,}" = y ] && rm -rf "$@"; }

Per rendere permanente questa funzione, aggiungi questa riga al ~/.bashrcfile su ogni computer che usi.

Confronto con l' rmalias comune

È comune definire un alias:

alias rm='rm -i'

Questo ha due limiti:

  1. Se arrivate a dipendere da questo alias, allora sarete scioccati quando vi trovate su una macchina o in un ambiente che non lo possiede. Al contrario, provare a funzionare rmrfsu una macchina senza quella funzione restituirà un innocuo command not found.

  2. Questo alias non è di aiuto nel tuo caso perché l' -fopzione fornita sulla riga di comando sovrascrive l' -iopzione dell'alias .


4
Non è una cattiva idea. Dipende dall'installazione e dalla disponibilità di questa funzione su tutti i sistemi utilizzati dall'utente. Diciamo quindi che accedono a un server remoto per qualche lavoro ed eseguono il rm -rfcomando sbagliato , cosa succede? La creazione di pseudo funzioni come questa alla fine complica semplicemente una soluzione semplice: basta essere più attenti e capire quali sono le autorizzazioni.
Jake Gould

4
@JakeGould E non usare rm -f a meno che non sia necessario .
un CVn

1
Perché preoccuparsi di rmrf, invece di creare semplicemente una funzione shell rmche controlla gli argomenti -ro -rf, e applica una logica speciale in quel caso, altrimenti chiama direttamente command rm "$@"per invocare il rmcomando reale ?
Charles Duffy,

3
Usi un nome diverso in modo da non spararti ai piedi quando il tuo override non è presente. E sono d'accordo con @ MichaelKjörling, non è necessario -fse non lo hai -i. Lasciarti -fti dà un avvertimento extra prima di rimuovere un file di sola lettura, ad esempio.
Peter Cordes,

6

Se mi trovo in una situazione in cui l'eliminazione dei file sbagliato è davvero un grosso problema, una delle cose che ho fatto è fare una cartella cestino, come mkdir trashcan, e poi Ho uno script rmTrashcanche ha una rm -rf trashcan/*o rm -rf *o simile, scritto con molta attenzione e controllato più volte.

In questo modo, se commetto un errore, l'errore è su un mvcomando, non su un rmcomando. Una volta che faccio un lse sono fiducioso di esattamente quello che sto eliminazione, una rmTrashcanrealtà fa il lavoro sporco in modo sicuro.

È stato anche straordinariamente conveniente per una situazione in cui ho dovuto eliminare i backup. Potevo mvun intero mese di backup nel cestino, mvi pochi che volevo mantenere (1 ° del mese, 15 del mese) di nuovo nei backup, quindi rmTranshcanil resto. Fare un comando simile è difficile da fare da rmsolo, e farlo in questo modo mi consente di fare in modo che lsi backup siano sicuri di quali file mi sto lasciando (piuttosto che elencare solo i file che intendo eliminare)


4

Invece di preoccuparmi di due comandi ( lse rm), penso che un modo più semplice e facile sia usare find:

find . -maxdepth 1 -name "string*" -delete

Se digiti per errore "string *", eliminerà i file con nome string charse string letters(che è quello che volevi comunque), ma non afferrerà tutti i file come *in una shell.

Inoltre, puoi lasciare fuori -deleteper vedere quali file sta per eliminare, quindi premi la freccia e digita -deletepiù facilmente della digitazione ^ls -R^rm -rfo di altre sciocchezze.


A findeseguirà una ricerca nidificata di file corrispondenti anziché solo i parametri espliciti dichiarati sulla riga di comando. Penso che questo non raggiunga il segno. Potrei sbagliarmi però.
assassino

3

Esiste un modo semplice per proteggersi in modo intelligente da un trascinamento accidentale o da un jolly iniziale?

Non proprio. Viene proposto in un'altra risposta che è possibile creare un comando personalizzato per aggiungere un prompt prima di eseguire un'attività. Ma il problema con questo comando personalizzato è che deve essere installato consapevolmente sui sistemi su cui stai lavorando. E anche se è installato, il problema è che il tuo riflesso da colpire yper portare a termine l'attività potrebbe entrare in gioco.

Ciò significa che si tratta di un problema dell'interfaccia utente anche se si trova a livello di testo / riga di comando. Quante reti di sicurezza ti aspetti che ci sia per proteggerti dal fare qualcosa che non dovresti? È come un paio di forbici: se sei in qualche modo negligente, scivoli e ti tagli la mano mentre intendi tagliare stoffa o carta, chi è la colpa? O addirittura semafori e segnali di stop: non c'è davvero nulla che possa impedire a un conducente di accendere un semaforo o ignorare i segnali stradali se non un'acuta consapevolezza di ciò che potrebbe accadere se intraprendono un comportamento così rischioso.

Detto questo, la soluzione migliore e realistica risiede nelle autorizzazioni di sistema per utenti e gruppi. Questa è la migliore / unica vera rete di sicurezza per proteggere un utente da se stessi.

Se stai lavorando su un sistema in cui sei l'unico ad accedervi, potresti essere tentato da chmod 777tutto, ma non è così che viene installato un sistema razionale. Invece le autorizzazioni dovrebbero essere simili 755a tutte le directory e 644a tutti i file non eseguibili. I file eseguibili dovrebbero essere 755almeno, ma forse anche 744se vuoi solo che gli altri leggano ma non eseguano i file.


2

Prova a comporre il tuo rmcomando iniziale senza il -fflag, ma con -iinvece tale che rmti chiederà ogni file che intende eliminare. Per piccole eliminazioni ricorsive, puoi tenere premuto il ytasto, una volta che sei sicuro che il comando sia stato digitato correttamente. Per cancellazioni di grandi dimensioni, è possibile interrompere l'operazione e utilizzare la cronologia della riga di comando per modificare con attenzione il simbolo -ia -f.


In realtà devi premere y[RETURN]ogni file, non c'è niente che puoi tenere premuto con GNU rm. Modificare -iè la strada da percorrere, dopo aver digitato correttamente il comando. Quindi ricevi un prompt solo su un file di sola lettura e forse altre cose.
Peter Cordes,

1
Basta usarlo in rm -Imodo che venga richiesto una sola volta, e solo per eliminazioni potenzialmente pericolose (cioè di molti file.)
Nick Matteo,

1
In forum meno costruttivi, la mia risposta sarebbe stata qualcosa del tipo "Se la tua digitazione / correzione di bozze è così grave, non puoi fare affari con" rm -rf "con i caratteri jolly." Non sapevo dell'interruttore -I ... deve essere stato inserito <20 anni fa; dell'ultima volta che ho fatto "amico". :)
Nevin Williams,

2

rm ha -ie -Iflag per confermare prima di ogni rimozione. In passato, alcune distribuzioni le hanno attivate per impostazione predefinita. Questa è un'idea terribile. Dai all'utente troppe finestre di dialogo di conferma per le normali operazioni e inizieranno a confermarle abitualmente. Questo sposta semplicemente l'esigenza di "stare attenti" (sempre una bandiera rossa) a una nuova e più fastidiosa finestra di dialogo. "Sì. Sì. Sì. Sì! SÌ! Dannazione, stupido computer, cancella i file SÌ SÌ SÌ SÌ SÌ - CRAP I MEANT NO! NOOOOOOO!" Questo è il problema della finestra di dialogo "Sì, ma non intendevo no". Questa risposta fornisce una spiegazione visiva del perché le finestre di dialogo di conferma arrivano nel momento sbagliato.

Il tipo di errore che si descrive è uno slittamento , "l'esecuzione di un'azione che non era quello che era destinato". L'utente in genere riconosce immediatamente l'errore e sa esattamente come risolverlo. Sfortunatamente, Unix non offre all'utente la possibilità, rm elimina immediatamente il file. Ogni altro sistema operativo risolve questo problema consentendo di eliminare le eliminazioni, almeno per un po ', mediante l'uso del Cestino.

Esistono vari sistemi di immondizia per Unix e questa risposta è piena di suggerimenti .

La domanda è alias rm o no alias rm. Pro per aliasing rm ...

  1. Non puoi fare la scusa di dimenticare di usare l'alternativa rm.

Contro aliasing rm ...

  1. Potresti fare affidamento su di esso su sistemi che non lo hanno.
  2. Potrebbe causare problemi quando il disco è quasi pieno.
  3. Hai bisogno di infrastrutture per svuotare periodicamente la spazzatura.
  4. Devono essere sicuri di non interferire con il comportamento previsto di rm nei programmi.
  5. Potrebbe non emulare completamente rm.

Se segui troppo il primo argomento, finisci per usare vi (non vim, vi), csh (non tcsh, csh) e altre utility antiquate perché sono universalmente disponibili. Tuttavia, esiste il pericolo di personalizzare eccessivamente l'ambiente. Preferisco portare le mie utilità con me e renderlo il più semplice possibile. YMMV.

Due e tre sono problemi tecnici. Possono essere risolti con un lavoro intelligente del mietitore che controlla le dimensioni del cestino e pulisce periodicamente le cose, in modo simile a un dispositivo di sollevamento . Questo può essere un lavoro cron o una versione più intelligente può fare uso delle varie infrastrutture di eventi del file system disponibili su molte distribuzioni Linux desktop. Questo non è semplice e persino più difficile da eseguire in modo efficiente. È meglio trovare un sistema esistente piuttosto che provare a crearne uno tuo.

Il quarto può essere gestito trasformando il tuo nuovo rm in un alias di shell alias rm='trash', quindi non influirà sui programmi.

Il quinto è un problema che lascio risolvere per il lettore. rm non ha molti switch.


Ho rm aliasato rm -i, ma spesso uso \rmper ottenere il comportamento senza precedenti. Scrivo rm -iogni volta che sto pianificando di dire di no a uno degli argomenti. A volte avvio il comando con lscome comando, quindi inserisco \ rm solo quando ho finito. Quindi non c'è modo che io possa accidentalmente premere il ritorno su rm -rf /invece di/.../file
Peter Cordes il

rm -Io rm --interactive=onceè molto, molto meno fastidioso di rm -i, e rileva ancora qualcosa di pericoloso (viene richiesto solo quando ci sono più di 3 file, o se è ricorsivo, e UNA VOLTA invece DI PER OGNI FILE.)
Nick Matteo

@Kundor Sì, e non cambia l'equazione. Probabilmente rende più probabile che l'utente lo ignori. L'utente ha un obiettivo: eliminare elementi. Il prompt dice "sei sicuro di voler eliminare le cose che mi hai appena detto di eliminare?" L'utente è ancora fissato sull'obiettivo di eliminare le cose, non verificando ciò che deve essere eliminato, quindi dicono "sì" senza pensare. -ipotrebbe dare all'utente il tempo di cambiare obiettivo. Questa risposta a una domanda correlata delinea tutto.
Schwern,

@Schwern: ma nessuno può vivere con rm -ipiù di 30 secondi senza spegnerlo. Considerando rm -Iche viene richiesto solo quando è probabile che tu abbia rovinato; il prompt arriva solo per grandi cancellazioni. Quando stavi cercando di eliminare un paio di cose e ti viene dato il prompt, verrai colto di sorpresa e ti rendi conto che hai digitato accidentalmente "pippo *".
Nick Matteo,

@Kundor L'eliminazione di più di tre file e l'eliminazione in modo ricorsivo (la conferma è disabilitata dall'abituale che -rfho appena scoperto) sono dei proxy inadeguati per rilevare un probabile errore. Volere eliminare una sottodirectory non è probabilmente un casino. Il messaggio non aiuta perché conferma semplicemente ciò che l'utente ha detto di fare senza aggiungere informazioni utili in un punto in cui l'utente non sta cercando di verificare. "rm: rimuovere 1 argomento in modo ricorsivo?" "Sì, elimina la directory, ti ho appena detto di farlo! ... aspetta, quale directory era quella? CRAP !!!"
Schwern,

2

Insegno a tutti !$sull'argomento = last nell'ultimo trucco di comando:

% ls job[XYZ].*
jobX.out1
jobX.out2
[rest of the matches]

% rm !$

Ciò consente un'ispezione dell'espansione dei caratteri jolly e quindi l'uso dello stesso identico modello glob senza la possibilità di inserire uno spazio prima di *.

Inoltre, suggerisco alle persone di non tagliare e incollare mai un motivo jolly traballante su una riga di comando potenzialmente distruttiva. Perché nelle mie mani è stato un problema :)

Un tecnico del mio laboratorio ha appena commesso questo errore la scorsa settimana (3 mesi di lavoro) - e sì, abbiamo avuto un backup (1 giorno di ritardo).


0

Tutti sembrano dire: "Stai più attento", "Non fare un alias / richiesta di conferma perché ti abituerai a non prestargli la dovuta attenzione".

Fantastico, e tutto. Voglio dire, non penso che dovresti creare un alias per rm(né rmrf, dal momento che potresti facilmente rovinare tutto e digitare il vero comando).

Ma perché non puoi creare un alias / script e chiamarlo, diciamo, removee dargli solo un argomento (ad esempio $ 1)? Il carattere jolly dovrebbe essere $ 2, a causa dello spazio involontario (prima?) E quindi il tuo script / wrapper / alias non verrà alimentato il secondo. Sì, puoi fare solo una serie di eliminazioni (con un carattere jolly) alla volta, ma è il prezzo che pagheresti.

Se stavo scrivendo qualcosa di carino, potrei dirmi il numero di file e directory che sta pianificando di eliminare e la dimensione totale delle cose che stavo eliminando, quindi chiedere una conferma, ma ciò potrebbe impedire il flusso. Forse renderlo un'opzione bandiera attiva remove? (-io). Potresti anche voler fare un controllo $ 1 per vedere se è solo un carattere jolly e chiedere una conferma, ed elencare la directory in cui ti trovi effettivamente.


A parte, ci sono un certo numero di rmsostituzioni là fuori. Molti stanno cercando di essere conformi al cestino del desktop dell'interfaccia utente. Alcuni di quelli potrebbero valere la pena esaminarli.


6
Il tuo alias "rimuovi" non rimuoverà mai più di un file alla volta. Non è possibile utilizzare un carattere jolly, poiché la shell lo espande prima che il comando lo veda.
hymie,

Quindi fai una valutazione su di esso e poi inseriscilo nella sceneggiatura?
user3082,

Quindi vuoi scrivere remove \*? Se il tuo script consente alla shell glob di espandere il suo input, non lo vedo molto utile.
Peter Cordes,

0

Un trucco molto semplice è quello di mettere -rfalla fine: rm whatever* -rf
questo riduce drasticamente il tasso di errore, perché si digita più carattere dopo il *, quindi si ha più tempo per vedere gli errori di battitura.
Questo non risolve tutto. Solo un semplice trucco di tutti i giorni.

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.