Jaki jest sens mv -f?

34

Podręcznik GNU Coreutilsmv mówi:

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

Jednak wydaje się to już zachowanie domyślne mv, więc -fopcja wydaje się zbędna. Np. W GNU Bash w wersji 4.3.11:

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

Wydaje się mało prawdopodobne, że intencją -fflagi jest przesłonięcie alias mv="mv -i", ponieważ istnieje kilka standardowych sposobów przesłonięcia aliasu (np. Użycie \mv), które zrobiłyby to bardziej zwięźle i w sposób spójny między poleceniami.

Podręcznik zauważa, że ​​„Jeśli określisz więcej niż jedną z opcji -i, -f, -n, tylko ostatnia zostanie zastosowana”, ale nadal wydaje się mało prawdopodobne, że intencją -fflagi jest zastąpienie -iflagi w ogóle, ponieważ ekwiwalentne zachowanie można osiągnąć po prostu używając mv, co jest o wiele bardziej zwięzłe i zrozumiałe niż używanie mv -if.

W takim razie jaki jest cel -fflagi? Dlaczego to istnieje?

sampablokuper
źródło
6
Domyślne są wybredny biznes. Weźmy na przykład takie narzędzie mount(chociaż istnieją lepsze przykłady). Czy naprawdę chcesz pamiętać o domyślnych ustawieniach każdej opcji, aby określić, które opcje należy ustawić? DOBRA RZECZ jest mieć opcje zarówno domyślne, jak i domyślne, więc możesz jawnie ustawić tę opcję, zamiast mentalnie śledzić domyślną wartość. Coś tam jest łatwiejsze do zapamiętania niż coś nieistniejącego .
Wildcard
Nie można zastosować równoważnego zachowania, jeśli MV jest alized do mv-i
PlasmaHH
1
IMO, jest również miły do ​​użycia w skryptach, ponieważ wyrażasz się jasno. Trochę lepiej komunikuje intencję.
Blacklight Shining

Odpowiedzi:

41

Użycie tego -fjest dokładniej opisane na stronie podręcznika użytkownika z 4BSD, tam gdzie dodano opcje -fi -i:

Jeśli plik 2 już istnieje, jest usuwany przed przeniesieniem pliku 1 . Jeśli plik2 ma tryb, który zabrania pisania, mv wypisuje ten tryb i odczytuje standardowe wejście w celu uzyskania linii; jeśli linia zaczyna się od y, ruch ma miejsce; jeśli nie, mv kończy pracę.

Opcje:

-ioznacza tryb interaktywny. Ilekroć ruch ma zastąpić istniejący plik, użytkownik jest monitowany o nazwę pliku, a następnie znak zapytania. Jeśli odpowie linią rozpoczynającą się od „y”, ruch jest kontynuowany. Każda inna odpowiedź uniemożliwia przeniesienie.

-foznacza siłę. Ta opcja zastępuje wszelkie ograniczenia trybu lub -iprzełącznik.

Jeszcze bardziej precyzyjna definicja działania mv podana jest w standardzie POSIX , co dodaje, że -fzastępuje tylko, -ijeśli pojawi się później w wierszu poleceń.

Więc domyślne zachowanie jest nieco inne niż -f. Domyślnie prosi się o potwierdzenie tylko wtedy, gdy cel nie jest zapisywalny. (To zachowanie sięga co najmniej do V4 , gdzie mvnie wybrano żadnych opcji.) Jeśli -ipodana jest opcja, mv będzie dodatkowo prosić o potwierdzenie, ilekroć istnieje cel. -fOpcja będzie hamować prosząc w obu tych przypadkach (jeśli występuje po każdym -i).

Mark Plotnick
źródło
Świetna odpowiedź, dzięki! Uwaga: Niektóre systemy plików (np. CIFS) mogą powodować, że mv zachowuje się nieoczekiwanie (tj. Różni się od instrukcji), na przykład działa tak, jakby -fflaga była używana, nawet jeśli nie była używana .
sampablokuper,
Warto zauważyć, że wiele implementacji prosi o potwierdzenie tylko wtedy, gdy wydaje się, że znajdują się w interaktywnym terminalu ( isatty(0)). Ponadto, chociaż prawdą jest, że późniejsze -fprzesłania -i, nie może to oznaczać, że jest to to samo, co brak podanych argumentów.
phk
15

Jest to przydatne, gdy ustawiłeś wykonanie mvna rozsądną wartość domyślną:

alias mv="mv -i"

Gdy chcesz wymusić ruch, zadziała to:

mv -f

Ponieważ liczy się ostatnia opcja w rozwiniętym poleceniu:

mv -i -f

Ten punkt jest również wspomniany w podręczniku GNU Coreutils .

Alexander
źródło
1
Dzięki, ale z powodów, które dodałem do pytania, wydaje się mało prawdopodobne, że zastąpienie alias mv="mv -i"jest przyczyną istnienia -f.
sampablokuper
12
Sprzeciwiam się nazywaniu domyślnego zachowania „rób to, o mv(1)co
prosisz
1
vonbrand, choć doceniam bezpośrednią reakcję na komendy Linux / UNIX bez -i, wierzę, że każdy, kto używał linii poleceń od ponad kilku lat, został spalony mv, w pewnym momencie.
Alexander
1
Możesz myśleć, że przesłonięcie -i jest mało prawdopodobne, ale właśnie dlatego domyślam się, że -f jest używane w ten sposób.
Walter
11

Istnieje, ponieważ ( man mv)

Jeśli podasz więcej niż jedną -i, -f, -n, tylko ostatni z nich wchodzi w życie.

Możesz więc mieć skrypt / alias / funkcję, która zawsze pyta, ale nadal możesz zastąpić tę opcję.

# alias
alias mv='mv -i'

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

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

Znacząca funkcja / skrypt zrobiłby oczywiście coś więcej (np. Zarejestrował akcję).

choroba
źródło
@choroba Dzięki, ale z powodów, które teraz dodałem do pytania, wydaje się mało prawdopodobne, aby nadpisujące aliasy, takie jak alias mv="mv -i"powód istnienia -f. Wspominasz także skrypty i funkcje. Czy możesz podać przykłady, używając tych dwóch?
sampablokuper
@sampablokuper: zaktualizowano.
choroba
@choroba, jeszcze raz dziękuję. Niestety, ani twój przykład funkcji, ani przykład twojego skryptu nie używa mv -f, więc wciąż nie jest dla mnie jasne, jak uzasadniają / wyjaśniają jego istnienie. Przepraszam, jeśli brakuje mi oczywistości!
sampablokuper
@sampablokuper: Wszyscy używają mv -i. Jeśli chcesz z nich korzystać, ale pomijasz interakcję, możesz użyć MV -fitd.
choroba
1
@sampablokuper Zachowanie mvbez żadnej z tych opcji polega czasem na pytaniu (cel nie jest zapisywalny i interaktywny terminal), więc byłaby to wyraźna różnica między mv -fi \mv.
phk
5

Samo mvpolecenie może działać inaczej z -fopcją, ponieważ spróbuje zastąpić zapisywanie chronionych plików bez pytania.

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

Z powodu uprawnień do zapisu w katalogu użytkownik2 może nadpisywać pliki użytkownika1 ./dir/, ale zostanie o tym ostrzeżony. -fzapobiega ostrzeżeniu.

Centyman
źródło
-1

W programowaniu powłoki używanie -f jest powszechnym idiomem używanym do upewnienia się, że twoje polecenia nie przerywają błędów lub nie pytają skryptu / użytkownika o interaktywną odpowiedź podczas uruchamiania niektórych poleceń. Ostatnią rzeczą, jakiej chcesz, to aby skrypt wstrzymał oczekiwanie na dane wejściowe od użytkownika lub, co gorsza, na niewłaściwe polecenie pobierające dane wejściowe ze standardu.

Uwaga: cofnięcie aliasu może powodować / usuwać skutki uboczne. W przypadku aliasu polecenia do innej wersji lub z dodatkowymi opcjami cofnięcie aliasu spowoduje niepożądane skutki uboczne. Na przykład, możesz mieć skonfigurowany alias z mv i rm, aby używać kosza (lub innych systemów ochrony / śledzenia). Cofnięcie aliasu spowoduje uszkodzenie tego ...

Walter
źródło
Nitpick: -fOpcja cp lub mv nie gwarantuje, że „będą działać”. Na przykład, jeśli uprawnienie jest niewystarczające, polecenie -f nie sprawi, że będzie działać. Miałeś na myśli to, że -f wymusza nadpisanie bez pytania. Przeciwna flaga -i oznacza, że ​​wymaga interaktywnego nadpisywania.
Eric Leschinski
Dwie rzeczy do zapamiętania: 1.) Implementacje normalnie sprawdzałyby, czy jesteś nawet w interaktywnym terminalu ( isatty(0)), więc np. Jeśli twój skrypt działa jako część potoku, nie zostanie uruchomiony. 2.) Dodawanie -fnie jest tym samym co cofanie, -iponieważ mv -i -fróżni się od mv, patrz odpowiedź Marka .
phk