Qual è il punto di mv -f?


34

Il manuale GNU Coreutils permv dice:

-f --force Do not prompt the user before removing a destination file.

Tuttavia, questo sembra già essere il comportamento predefinito per mv, quindi l' -fopzione sembra essere superflua. Ad esempio in GNU Bash versione 4.3.11:

$ ls -l
total 0
$ touch 1 2; mv -f 1 2; ls
2
$ touch 1 2; mv 1 2; ls
2

Sembra improbabile che l'intenzione della -fbandiera sia quella di sovrascrivere alias mv="mv -i", perché ci sono diversi modi standard di sovrascrivere un alias (ad es. Usare \mv) che lo farebbero in modo più conciso e coerente tra i comandi.

Il manuale osserva che "Se si specifica più di una delle opzioni -i, -f, -n, solo l'effetto finale ha effetto", ma sembra ancora improbabile che l'intenzione della -fbandiera sia quella di sostituire la -ibandiera in generale, perché si può ottenere un comportamento equivalente semplicemente usando mv, che è molto più conciso e comprensibile dell'uso mv -if.

Stando così le cose, qual è lo scopo della -fbandiera? Perché esiste?


6
I valori predefiniti sono un affare schizzinoso. Prendi uno strumento come mount, ad esempio (anche se ci sono esempi migliori). Vuoi davvero ricordare quali sono le impostazioni predefinite per ogni opzione, così puoi determinare quali opzioni devi impostare? È una buona cosa avere opzioni sia per il default che per il non default, quindi puoi impostare esplicitamente l'opzione invece di dover tenere mentalmente traccia di ciò che è predefinito. Qualcosa non v'è più facile da ricordare che qualcosa non c'era .
Carattere jolly

Un comportamento equivalente non può essere usato se MV è alleata di mv-i
PlasmaHH

1
IMO, è anche bello da usare negli script, perché sei esplicito. Comunica un po 'meglio l'intenzione.
Blacklight Shining

Risposte:


41

L'uso di -fè descritto più chiaramente nella pagina man di 4BSD, dove erano state aggiunte le opzioni -fe -i:

Se file2 esiste già, viene rimosso prima che file1 venga spostato. Se file2 ha una modalità che proibisce la scrittura, mv stampa la modalità e legge l'input standard per ottenere una riga; se la linea inizia con y, la mossa ha luogo; in caso contrario, mv esce.

Opzioni:

-ista per modalità interattiva. Ogni volta che una mossa deve sostituire un file esistente, all'utente viene richiesto il nome del file seguito da un punto interrogativo. Se risponde con una linea che inizia con 'y', la mossa continua. Qualsiasi altra risposta impedisce che si verifichi lo spostamento.

-fsta per forza. Questa opzione ignora qualsiasi restrizione di modalità o lo -iswitch.

Una definizione ancora più precisa di come opera mv è data nello standard POSIX , che aggiunge ciò-f solo -ise si verifica successivamente nella riga di comando.

Quindi il comportamento predefinito è leggermente diverso da -f. L'impostazione predefinita è chiedere conferma solo quando l'obiettivo non è scrivibile. (Questo comportamento risale almeno fino a V4 , dove mvnon è stata presa alcuna opzione.) Se l' -iopzione è data, mv chiederà inoltre conferma ogni volta che esiste il bersaglio. L' -fopzione inibirà la richiesta in entrambi i casi (se si verifica dopo -i).


Ottima risposta, grazie! NB Alcuni file system (ad es. CIFS) possono far sì che mv mostri comportamenti inattesi (cioè diversi dal manuale), come comportarsi come se la -fbandiera fosse stata usata anche se non fosse stata usata .
sampablokuper,

Vale la pena notare che molte implementazioni chiedono conferma solo se sembrano essere in un terminale interattivo ( isatty(0)). Inoltre, se è vero che una successiva -fsostituzioni -i, potrebbe non significa che questo è lo stesso in quanto non argomenti forniti.
phk,

15

È utile quando si imposta l'esecuzione su mvun valore predefinito sano:

alias mv="mv -i"

Quando vuoi forzare una mossa, questo funzionerà:

mv -f

Poiché è l'ultima opzione nel comando espanso che conta:

mv -i -f

Questo punto è anche menzionato nel manuale GNU Coreutils .


1
Grazie, ma per motivi che ora ho aggiunto alla domanda, sembra improbabile che l'override alias mv="mv -i"sia la ragione dell'esistenza di -f.
sampablokuper,

12
Mi oppongo a chiamare il comportamento predefinito "fai come ti viene chiesto, senza domande stupide" di mv(1)(e altri comandi Unix) "insano" come intendi ...
vonbrand,

1
vonbrand, mentre apprezzo la risposta diretta dei comandi Linux / UNIX senza -i, credo che chiunque abbia usato la riga di comando per più di qualche anno sia stato bruciato mv, in un punto o nell'altro.
Alexander,

1
Potresti pensare che ignorare -i sia improbabile, ma è esattamente per questo che immagino che -f sia usato in questo modo.
Walter,

11

Esiste perché ( man mv)

Se si specifica più di uno di -i, -f, -n, solo quella finale ha effetto.

Quindi, puoi avere una funzione script / alias / che chiede sempre, ma puoi comunque sostituire l'opzione.

# alias
alias mv='mv -i'

# function
MV () { mv -i "$@" ; }

# script
#!/bin/bash
mv -i "$@"

Una funzione / script significativi farebbe qualcosa di più, ovviamente (ad esempio, registra l'azione).


@choroba Grazie, ma per motivi che ora ho aggiunto alla domanda, sembra improbabile che alias prevalenti come alias mv="mv -i"il motivo dell'esistenza di -f. Citi anche script e funzioni. Per favore, potresti fare degli esempi usando questi due?
sampablokuper,

@sampablokuper: aggiornato.
Choroba,

@choroba, grazie ancora. Purtroppo, né il tuo esempio di funzione né il tuo esempio di script usano mv -f, quindi non mi è ancora chiaro come giustificano / spiegano la sua esistenza. Scusa se mi manca l'ovvio!
sampablokuper,

@sampablokuper: usano tutti mv -i. Se vuoi usarli ma salti l'interazione, MV -f
useresti

1
@sampablokuper Il comportamento di mvsenza nessuna di queste opzioni è talvolta chiedere (target non scrivibile e terminale interattivo), quindi questa sarebbe una chiara differenza tra mv -fe \mv.
phk,

5

Il mvcomando da solo può funzionare diversamente con l' -fopzione, in quanto proverà a sovrascrivere i file protetti da scrittura senza un prompt.

user2@host:location> ls -l ./
drwxrwxr-x 2 user1 users    10   Oct 16 12:58 dir
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user1 users     0   Oct 16 12:58 file1
-rw-r--r-- 2 user2 users     0   Oct 16 12:58 file2
user2@host:location> \mv ./dir/file2 ./dir/file1
'mv' try to overwrite './dir/file1', overridding mode 0644 (rw-r--r--)? n
user2@host:location> \mv -f ./dir/file2 ./dir/file1
user2@host:location> ls -l ./dir/
-rw-r--r-- 2 user2 users     0   Oct 16 12:58 file1

A causa delle autorizzazioni di scrittura nella directory user2 può sovrascrivere i file user1 ./dir/, ma verrà avvisato prima di farlo. -fimpedisce l'avvertimento.


-1

Nella programmazione della shell, usare -f è un linguaggio comune usato per assicurarsi che i comandi non si interrompano con errori o chiedano allo script / utente una risposta interattiva quando si eseguono determinati comandi. L'ultima cosa che vuoi è che il tuo script metta in pausa in attesa dell'input dell'utente, o forse peggio, che il comando sbagliato prenda l'input dallo standard in.

Nota: l' annullamento di un alias può causare / rimuovere effetti collaterali. Se il comando è stato modificato in un'altra versione o con opzioni aggiuntive, l'annullamento dell'alias causerà effetti collaterali indesiderati. Ad esempio, potresti avere una configurazione alias con mv e rm per usare un cestino (o altri sistemi di protezione / tracciamento). Annullare l'alias interromperà questo ...


Nitpick: l' -fopzione per cp o mv non garantisce che "funzionino". Ad esempio se l'autorizzazione è insufficiente, il comando -f non lo farà funzionare. Quello che intendevi dire è che -f forza una sovrascrittura senza prompt. Il flag opposto -i significa richiedere interattivo su sovrascrittura.
Eric Leschinski,

Due cose da notare: 1.) Le implementazioni normalmente verificherebbero se ci si trova anche in un terminale interattivo ( isatty(0)), quindi ad esempio se lo script viene eseguito come parte di una pipe non verrà attivato. 2.) L'aggiunta -fnon è la stessa dell'annullamento -iperché è mv -i -fdiversa mv, vedi la risposta di Mark .
phk,
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.