Điểm của mv -f là gì?


34

Các thủ GNU coreutils chomv biết:

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

Tuy nhiên, điều này dường như đã là hành vi mặc định cho mv, vì vậy -ftùy chọn dường như là thừa. Ví dụ: trong phiên bản GNU Bash 4.3.11:

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

Dường như -fcờ không có ý định ghi đè alias mv="mv -i", bởi vì có một số cách tiêu chuẩn để ghi đè bí danh (ví dụ: sử dụng \mv) sẽ thực hiện việc này chính xác hơn và theo cách nhất quán giữa các lệnh.

Hướng dẫn lưu ý rằng, "Nếu bạn chỉ định nhiều hơn một trong các tùy chọn -i, -f, -n, thì chỉ có tùy chọn cuối cùng có hiệu lực", nhưng dường như vẫn không có ý định -fcờ là ghi đè -icờ nói chung, bởi vì hành vi tương đương có thể đạt được bằng cách sử dụng đơn giản mv, nó ngắn gọn và dễ hiểu hơn nhiều so với sử dụng mv -if.

Đó là trường hợp, mục đích của -fcờ là gì? Tại sao nó tồn tại?


6
Mặc định là một doanh nghiệp khó khăn. Lấy một công cụ như mount, ví dụ (mặc dù có những ví dụ tốt hơn). Bạn có thực sự muốn phải nhớ những gì mặc định cho mỗi tùy chọn, vì vậy bạn có thể xác định những tùy chọn bạn cần đặt? Đó là một điều tốt để có các tùy chọn cho cả mặc định và không mặc định, vì vậy bạn có thể đặt tùy chọn một cách rõ ràng thay vì cần phải theo dõi tinh thần về mặc định là gì. Một cái gì đó dễ nhớ hơn một cái gì đó không có .
tự đại diện

Hành vi tương đương không thể được sử dụng nếu MV được chỉnh sửa thành mv-i
PlasmaHH

1
IMO, nó cũng tốt để sử dụng trong các tập lệnh, bởi vì bạn rõ ràng. Nó truyền đạt ý định tốt hơn một chút.
Blacklight Shining

Câu trả lời:


41

Việc sử dụng -fđược mô tả rõ ràng hơn trong trang man từ 4BSD, đó là nơi -f-icác tùy chọn được thêm vào:

Nếu file2 đã tồn tại, nó sẽ bị xóa trước khi file1 được di chuyển. Nếu file2 có chế độ cấm ghi, mv sẽ in chế độ đó và đọc đầu vào tiêu chuẩn để có được một dòng; nếu dòng bắt đầu bằng y, việc di chuyển diễn ra; nếu không, mv thoát.

Tùy chọn:

-ilà viết tắt của chế độ tương tác. Bất cứ khi nào di chuyển để thay thế một tệp hiện có, người dùng sẽ được nhắc tên của tệp theo sau là một dấu hỏi. Nếu anh ta trả lời bằng một dòng bắt đầu bằng 'y', việc di chuyển sẽ tiếp tục. Bất kỳ trả lời khác ngăn chặn di chuyển xảy ra.

-flà viết tắt của lực lượng. Tùy chọn này ghi đè bất kỳ hạn chế chế độ hoặc -ichuyển đổi.

Một định nghĩa chính xác hơn nữa về cách mv vận hành được đưa ra trong tiêu chuẩn POSIX , bổ sung thêm rằng -fchỉ ghi đè -inếu nó xuất hiện sau trong dòng lệnh.

Vì vậy, hành vi mặc định là một chút khác nhau từ -f. Mặc định là chỉ yêu cầu xác nhận khi mục tiêu không thể ghi được. (Hành vi này quay trở lại ít nhất là đến V4 , trong mvđó không có bất kỳ tùy chọn nào.) Nếu -itùy chọn được đưa ra, mv sẽ yêu cầu xác nhận thêm bất cứ khi nào mục tiêu tồn tại. Các -ftùy chọn sẽ ức chế hỏi trong cả hai trường hợp (nếu nó xảy ra sau khi bất kỳ -i).


Câu trả lời tuyệt vời, cảm ơn! NB Một số hệ thống tệp (ví dụ CIFS) có thể khiến mv thể hiện hành vi không mong muốn (nghĩa là khác với hướng dẫn sử dụng), chẳng hạn như hành động như thể -fcờ đã được sử dụng ngay cả khi không được sử dụng .
sampablokuper

Điều đáng chú ý là nhiều triển khai chỉ yêu cầu xác nhận nếu chúng có vẻ nằm trong một thiết bị đầu cuối tương tác ( isatty(0)). Ngoài ra, trong khi sự thật là một phần -fghi đè sau này -i, điều đó có thể không có nghĩa là điều này giống như không có đối số nào được đưa ra.
phk

15

Nó hữu ích khi đã đặt thực thi mvthành mặc định lành mạnh:

alias mv="mv -i"

Khi bạn muốn thực hiện một động thái, điều này sẽ hoạt động:

mv -f

Vì đó là tùy chọn cuối cùng trong lệnh mở rộng được tính:

mv -i -f

Điểm này cũng được đề cập trong hướng dẫn GNU Coreutils .


1
Cảm ơn, nhưng vì những lý do mà bây giờ tôi đã thêm vào câu hỏi, dường như không có khả năng ghi đè alias mv="mv -i"là lý do cho sự tồn tại của -f.
sampablokuper

12
Tôi phản đối việc gọi hành vi mặc định là "làm như bạn được hỏi, không có câu hỏi ngớ ngẩn" nào mv(1)(và các lệnh Unix khác) "điên rồ" như bạn ngụ ý ...
vonbrand

1
vonbrand, trong khi tôi đánh giá cao phản ứng trực tiếp của các lệnh Linux / UNIX mà không có -i, tôi tin rằng bất kỳ ai đã sử dụng dòng lệnh trong hơn một vài năm đã bị đốt cháy mv, tại một thời điểm nào đó.
Alexander

1
Bạn có thể nghĩ rằng ghi đè -i là không thể, nhưng đó chính xác là lý do tại sao tôi đoán rằng -f được sử dụng như vậy.
Walter

11

Nó tồn tại bởi vì ( man mv)

Nếu bạn chỉ định nhiều hơn một trong những -i, -f, -n, chỉ có một thức có hiệu lực.

Vì vậy, bạn có thể có một tập lệnh / bí danh / hàm luôn luôn hỏi, nhưng bạn vẫn có thể ghi đè tùy chọn.

# alias
alias mv='mv -i'

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

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

Tất nhiên, một hàm / script có ý nghĩa sẽ làm một cái gì đó nhiều hơn (ví dụ: ghi nhật ký hành động).


@choroba Cảm ơn, nhưng vì những lý do mà bây giờ tôi đã thêm vào câu hỏi, có vẻ như không có khả năng ghi đè các bí danh như alias mv="mv -i"là lý do cho sự tồn tại của -f. Bạn đề cập đến các kịch bản và chức năng là tốt, mặc dù. Xin vui lòng cho tôi ví dụ bằng cách sử dụng hai?
sampablokuper

@sampablokuper: đã cập nhật.
choroba

@choroba, cảm ơn lần nữa. Đáng buồn thay, cả ví dụ chức năng và ví dụ tập lệnh của bạn đều không sử dụng mv -f, vì vậy tôi vẫn chưa rõ ràng về cách họ biện minh / giải thích sự tồn tại của nó. Xin lỗi nếu tôi thiếu điều hiển nhiên!
sampablokuper

@sampablokuper: Tất cả đều sử dụng mv -i. Nếu bạn muốn sử dụng chúng mà bỏ qua tương tác, bạn sẽ sử dụng, MV -fv.v.
choroba

1
@sampablokuper Hành vi mvkhông có bất kỳ tùy chọn nào trong số đó là thỉnh thoảng hỏi (mục tiêu không thể ghi và thiết bị đầu cuối tương tác), vì vậy đây sẽ là một sự khác biệt rõ ràng giữa mv -f\mv.
phk

5

Bản thân mvlệnh có thể hoạt động khác với -ftùy chọn, theo đó nó sẽ cố gắng ghi đè lên các tệp được bảo vệ mà không có dấu nhắc.

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

Do quyền ghi trong thư mục user2 có thể ghi đè lên tệp user1 ./dir/, nhưng sẽ được cảnh báo trước khi thực hiện. -fngăn chặn cảnh báo.


-1

Trong lập trình shell, sử dụng -f là một thành ngữ phổ biến được sử dụng để đảm bảo rằng các lệnh của bạn không hủy bỏ lỗi hoặc yêu cầu tập lệnh / người dùng trả lời tương tác khi chạy một số lệnh nhất định. Điều cuối cùng bạn muốn là cho tập lệnh của bạn tạm dừng chờ đầu vào của người dùng, hoặc có thể tệ hơn, cho lệnh sai để lấy đầu vào từ tiêu chuẩn trong.

Lưu ý: hoàn tác bí danh có thể gây ra / loại bỏ tác dụng phụ. Nếu bạn đã đặt bí danh cho phiên bản khác hoặc với các tùy chọn bổ sung, việc hoàn tác bí danh sẽ gây ra tác dụng phụ không mong muốn. Ví dụ: bạn có thể thiết lập bí danh với mv và rm để sử dụng thùng rác (hoặc các hệ thống bảo vệ / theo dõi khác). Hoàn tác bí danh sẽ phá vỡ điều này ...


Nitpick: -fTùy chọn cho cp hoặc mv không đảm bảo rằng "chúng hoạt động". Ví dụ: nếu không đủ quyền, lệnh -f sẽ không làm cho nó hoạt động. Điều bạn muốn nói là -f buộc ghi đè mà không cần nhắc. Cờ đối diện -i có nghĩa là yêu cầu tương tác trên ghi đè.
Eric Leschinski

Hai điều cần lưu ý: 1.) Việc triển khai thường sẽ kiểm tra xem bạn thậm chí có ở trong một thiết bị đầu cuối tương tác ( isatty(0)) hay không, ví dụ: nếu tập lệnh của bạn chạy như một phần của đường ống thì nó sẽ không được kích hoạt. 2.) Thêm -fkhông giống như hoàn tác -imv -i -fkhác với mv, xem câu trả lời của Mark .
phk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.