Tại sao 'find -delete' lại xóa tất cả các tệp trong một thư mục


15

Vì vậy, các hành vi sau đây của unix chỉ khiến tôi phải trả giá đắt:

> touch foo
> touch bar
> ls  
bar  foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar  baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?

Điều này có ý nghĩa là gì?


2
Câu hỏi này có liên quan, có thể thú vị cho độc giả tương lai. unix.stackexchange.com/questions/101282/ Ấn
Bernhard

Câu trả lời:


14

Dòng lệnh tìm được tạo từ các loại tùy chọn khác nhau, được kết hợp để tạo thành biểu thức.

Các findtùy chọn -deletelà một hành động.
Điều đó có nghĩa là nó được thực thi cho mỗi tệp được khớp cho đến nay.
Là tùy chọn đầu tiên sau các đường dẫn, tất cả các tệp được khớp ... rất tiếc!

Điều đó thật nguy hiểm - nhưng trang người đàn ông ít nhất có một cảnh báo lớn :

Từ man find:

ACTIONS
    -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
           everything 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.


Từ xa hơn trong man find:

EXPRESSIONS
    The expression is made up of options (which affect overall operation rather
    than  the  processing  of  a  specific file, and always return true), tests
    (which return a true or false value), and actions (which have side  effects
    and  return  a  true  or false value), all separated by operators.  -and is
    assumed where the operator is omitted.

    If the expression contains no actions other than  -prune,  -print  is  per‐
    formed on all files for which the expression is true.


Khi thử những gì một findlệnh sẽ làm:

Để xem lệnh như thế nào

find . -name '*ar' -delete

sẽ xóa, trước tiên bạn có thể thay thế hành động -deletebằng một hành động vô hại hơn - như -flshoặc -print:

find . -name '*ar' -print

Điều này sẽ in những tập tin bị ảnh hưởng bởi hành động.
Trong ví dụ này, -print có thể bị bỏ lại. Trong trường hợp này, không có hành động nào cả, vì vậy rõ ràng nhất được thêm vào ngầm : -print. (Xem đoạn thứ hai của phần "GIẢI THÍCH" được trích dẫn ở trên)


Tôi đoán rằng tôi chỉ là một thằng ngốc vì đã không đọc hướng dẫn trước .. Nhưng dường như rất đơn giản để thêm -deletecờ :-) Nhưng có lý do nào có ai sẽ làm find . -deletehơn là rm -rf .không? Hay đó chỉ là cách findphân tích cú pháp và xử lý các đối số của nó?
mszep

1
Ồ, tôi hoàn toàn đồng ý rằng cú pháp rất nguy hiểm - nhưng điều đó khó tránh, vì đó chỉ là một trường hợp đặc biệt của cú pháp biểu thức dòng comman tìm thấy, cực kỳ mạnh mẽ. Mạnh mẽ như trong " Một cưa máy mạnh mẽ ".
Volker Siegel

không phải trang hướng dẫn được trích dẫn nói rằng warning: use -depth when testing stuff you later want to -deletebạn không làm gì trong ví dụ thực tế của bạn?
pqnet

Ồ, phải - vấn đề là tiêu đề - Tôi muốn minh họa việc sử dụng in ở vị trí -delete như một -ntùy chọn; Lệnh đầu tiên không nên có bất kỳ sử dụng thực tế nào, tất nhiên; Tôi sẽ đi thay đổi nó.
Volker Siegel

9

Trong findcác vấn đề để tranh luận, rất nhiều.

Đối số có thể là tùy chọn, kiểm tra và hành động. Thông thường bạn nên sử dụng các tùy chọn trước, sau đó kiểm tra, sau đó hành động.

Đôi khi, findthậm chí còn cảnh báo bạn về một thứ tự xấu có thể xảy ra (ví dụ như khi bạn sử dụng -maxdepthsau các đối số khác), nhưng những người khác thì có vẻ như không.

Cái gì find . -delete -name '*ar'là:

  1. Tìm tập tin và thư mục theo thư mục hiện tại.
  2. Xóa chúng TẤT CẢ khi chúng được tìm thấy!
  3. Sau đó xem nếu chúng được đặt tên như '* ar' (phần này hiện không có hiệu lực).

Những gì bạn có thể muốn làm là:

find -name '*ar' -delete

Điều này sẽ, cho mọi tập tin, xem nếu nó phù hợp '*ar' và chỉ khi nó thỏa mãn điều kiện thì nó sẽ xóa tệp.

Xin lỗi nếu bạn phát hiện quá muộn.

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.