Câu trả lời:
locate(1)
chỉ có một lợi thế lớn hơn find(1)
: tốc độ.
find(1)
mặc dù, có nhiều lợi thế hơn locate(1)
:
find(1)
là nguyên thủy, quay trở lại phiên bản đầu tiên của AT & T Unix . Bạn thậm chí sẽ tìm thấy nó trong các Linux nhúng được cắt giảm thông qua Busybox . Nó là tất cả nhưng phổ quát.
locate(1)
là trẻ hơn nhiều so với find(1)
. Tổ tiên đầu tiên của locate(1)
đã không xuất hiện cho đến năm 1983 và nó không được phổ biến rộng rãi như " locate
" cho đến năm 1994, khi nó được đưa vào công cụ tìm kiếm GNU và vào 4.4BSD .
locate(1)
cũng không phải là tiêu chuẩn , do đó nó không được cài đặt theo mặc định ở mọi nơi. Một số HĐH kiểu POSIX thậm chí không cung cấp tùy chọn này và nếu có sẵn, việc triển khai có thể thiếu các tính năng bạn muốn vì không có tiêu chuẩn độc lập chỉ định bộ tính năng tối thiểu phải có.
Có một de facto tiêu chuẩn, là BSDlocate(1)
, nhưng đó là chỉ vì hai hương vị chính khác locate
thực hiện tất cả các tùy chọn của nó: -0
, -c
, -d
, -i
, -l
, -m
, -s
, và -S
. mlocate
thực hiện 6 tùy chọn bổ sung không BSD locate
: -b
, -e
, -P
, -q
, --regex
và -w
. GNUlocate
thực hiện những sáu cộng khác Bốn : -A
, -D
, -E
, và -p
. (Tôi bỏ qua các bí danh và sự khác biệt nhỏ như -?
so -h
với --help
.)
BSD và Mac OS X gửi BSD locate
.
Hầu hết các Linux đều phát hành GNU locate
, nhưng mlocate
thay vào đó là Red Hat Linuxes và Arch . Debian không cài đặt trong cài đặt cơ bản, nhưng cung cấp cả hai phiên bản trong kho gói mặc định của nó; nếu cả hai được cài đặt cùng một lúc, " locate
" chạy mlocate
.
Oracle đã giao hàng mlocate
trong Solaris kể từ ngày 11.2 , được phát hành vào tháng 12 năm 2014. Trước đó, locate
không được cài đặt mặc định trên Solaris. (Có lẽ, điều này đã được thực hiện để giảm sự không tương thích lệnh của Solaris với Oracle Linux , dựa trên Red Hat Enterprise Linux , cũng sử dụng mlocate
.)
IBM AIX vẫn không gửi bất kỳ phiên bản nào locate
, ít nhất là từ AIX 7.2 , trừ khi bạn cài đặt GNU findutils
từ Hộp công cụ AIX cho Ứng dụng Linux .
HP-UX cũng xuất hiện thiếu locate
trong hệ thống cơ sở.
Các Unix "thực" cũ hơn thường không bao gồm việc triển khai locate
.
find(1)
có cú pháp biểu thức mạnh mẽ, với nhiều hàm, toán tử Boolean , v.v.
find(1)
có thể chọn tập tin bằng nhiều hơn chỉ tên. Nó có thể chọn bằng cách:
Khi tìm tệp theo tên, bạn có thể tìm kiếm bằng cú pháp toàn cầu hóa tệp trong tất cả các phiên bản find(1)
hoặc trong phiên bản GNU hoặc BSD, bằng cách sử dụng các biểu thức thông thường .
Các phiên bản hiện tại locate(1)
chấp nhận mô hình toàn cầu cũng find
vậy, nhưng BSD locate
hoàn toàn không thực hiện regexes. Nếu bạn giống tôi và phải sử dụng nhiều loại máy khác nhau, bạn sẽ thấy mình thích grep
lọc hơn để phát triển sự phụ thuộc vào -r
hoặc --regex
.
locate
cần lọc mạnh hơn find
vì ...
find(1)
không nhất thiết phải tìm kiếm toàn bộ hệ thống tập tin. Bạn thường trỏ nó vào thư mục con, cha mẹ chứa tất cả các tệp bạn muốn nó hoạt động. Hành vi điển hình cho locate(1)
việc triển khai là phun ra tất cả các tệp khớp với mẫu của bạn, để nó grep
lọc và như vậy để cắt giảm sự phun trào của nó xuống kích thước.
(Mẹo xấu: locate /
có thể sẽ giúp bạn có danh sách tất cả các tệp trên hệ thống!)
Có các biến thể locate(1)
giống như slocate(1)
hạn chế đầu ra dựa trên quyền của người dùng, nhưng đây không phải là phiên bản mặc định locate
trong bất kỳ hệ điều hành chính nào.
find(1)
có thể làm mọi thứ với các tập tin mà nó tìm thấy, ngoài việc chỉ tìm thấy chúng. Toán tử mạnh nhất và được hỗ trợ rộng rãi như vậy -exec
, nhưng có những toán tử khác. Trong các triển khai GNU và BSD gần đây, ví dụ, bạn có các toán tử -delete
và -execdir
toán tử.
find(1)
chạy trong thời gian thực, vì vậy đầu ra của nó luôn được cập nhật.
Bởi vì locate(1)
dựa trên cơ sở dữ liệu được cập nhật hàng giờ hoặc ngày trong quá khứ, đầu ra của nó có thể bị lỗi thời. (Đây là vấn đề bộ nhớ cache cũ .) Đồng xu này có hai mặt:
locate
có thể đặt tên cho các tập tin không còn tồn tại
GNU locate
và mlocate
có -e
cờ để kiểm tra sự tồn tại của tệp trước khi in tên của từng tệp mà nó đã phát hiện ra trong quá khứ, nhưng điều này ăn mất một số locate
lợi thế về tốc độ và không có sẵn trong BSD locate
.
locate
sẽ không thể đặt tên cho các tệp đã được tạo kể từ lần cập nhật cơ sở dữ liệu cuối cùng.
Bạn học được cách không tin tưởng vào locate
đầu ra, biết rằng nó có thể sai.
Có nhiều cách để giải quyết vấn đề này, nhưng tôi không biết về bất kỳ triển khai nào trong việc sử dụng rộng rãi. Ví dụ, có rlocate
, nhưng nó dường như không hoạt động đối với bất kỳ nhân Linux hiện đại nào.
find(1)
không bao giờ có bất kỳ đặc quyền nào hơn người dùng chạy nó.
Vì locate
cung cấp dịch vụ toàn cầu cho tất cả người dùng trên một hệ thống, nên nó muốn updatedb
chạy quy trình của nó root
để có thể xem toàn bộ hệ thống tệp. Điều này dẫn đến một sự lựa chọn về các vấn đề bảo mật:
Chạy updatedb
bằng root, nhưng làm cho tệp đầu ra của nó có thể đọc được để locate
có thể chạy mà không cần đặc quyền. Điều này có hiệu quả hiển thị tên của tất cả các tệp trong hệ thống cho tất cả người dùng. Điều này có thể đủ vi phạm an ninh để gây ra một vấn đề thực sự.
BSD locate
được cấu hình theo cách này trên Mac OS X và FreeBSD.
Viết cơ sở dữ liệu dưới dạng chỉ có thể đọc được root
và tạo locate
setuid
root để nó có thể đọc cơ sở dữ liệu. Điều này có nghĩa locate
một cách hiệu quả phải reimplement hệ thống cho phép của hệ điều hành vì vậy nó không cho bạn thấy các tập tin bạn bình thường không thể nhìn thấy. Nó cũng làm tăng bề mặt tấn công của hệ thống của bạn, đặc biệt có nguy cơ tấn công leo thang gốc .
Tạo một locate
người dùng hoặc nhóm "" đặc biệt để sở hữu tệp cơ sở dữ liệu và đánh dấu locate
nhị phân là setuid/setgid
cho người dùng / nhóm đó để có thể đọc cơ sở dữ liệu. Điều này không ngăn chặn các cuộc tấn công leo thang đặc quyền của chính nó, nhưng nó giảm thiểu rất nhiều thiệt hại mà người ta có thể gây ra.
mlocate
được cấu hình theo cách này trên Red Hat Enterprise Linux .
Tuy nhiên, bạn vẫn có một vấn đề, bởi vì nếu bạn có thể sử dụng trình gỡ lỗi trên locate
hoặc khiến nó đổ lõi, bạn có thể nhận được tại các phần đặc quyền của cơ sở dữ liệu.
Tôi không thấy cách nào để tạo một lệnh thực sự "an toàn" locate
, thiếu chạy nó riêng cho từng người dùng trên hệ thống, điều này phủ nhận phần lớn lợi thế của nó so với find(1)
.
Tóm lại, cả hai đều rất hữu ích. locate(1)
sẽ tốt hơn khi bạn chỉ cố gắng tìm một tệp cụ thể theo tên mà bạn biết là có tồn tại, nhưng bạn không nhớ chính xác nó ở đâu. find(1)
sẽ tốt hơn khi bạn có một khu vực tập trung để kiểm tra, hoặc khi bạn cần bất kỳ lợi thế nào của nó.
find -- "$dir"
không mạnh mẽ ( $dir
có thể được dùng cho một vị ngữ), không có cách nào để kiểm tra các thuộc tính của một liên kết tượng trưng, các vấn đề về điều kiện chủng tộc ... Đối với tôi find
và locate
giải quyết hai vấn đề khác nhau. Có nhiều nơi sử dụng find là không thực tế (như thư mục chứa hàng triệu tệp). định vị là một hệ thống lập chỉ mục giới hạn cho tên tệp.
locate
đại khái là đôi khi giống như find / -type f | gzip > locate.gz
, vàzgrep "$1" <locate.gz
locate
có trong findutils
gói và updatedb
chương trình của nó được triển khai theo các khía cạnh find(1)
. Vì vậy, trong ý nghĩa đó, locate(1)
thực sự đòi hỏi find(1)
. :)
find
, locate
vv trong các phần khác vì vậy nó không phải có mặt ở đó để disambiguate cùng tên được sử dụng trong các phần khác nhau của hướng dẫn sử dụng (ví dụ unlink(1)
vs unlink(2)
), những người trong chúng ta đã sử dụng quy ước xem đó là tài liệu tham khảo trang nam.
locate
sử dụng cơ sở dữ liệu dựng sẵn, cần được cập nhật thường xuyên, trong khi find
lặp qua hệ thống tệp để định vị tệp.
Do đó, locate
nhanh hơn nhiều find
, nhưng có thể không chính xác nếu cơ sở dữ liệu -can được xem là bộ đệm - không được cập nhật (xem updatedb
lệnh).
Ngoài ra, find
có thể cung cấp mức độ chi tiết cao hơn, vì bạn có thể lọc các tệp theo mọi thuộc tính của nó, trong khi locate
sử dụng một mẫu khớp với tên tệp.
find
người dùng mới hoặc người dùng thỉnh thoảng sử dụng Unix có thể sử dụng thành công mà không có sự xem xét cẩn thận của trang người đàn ông. Trong lịch sử, một số phiên bản find
thậm chí không mặc định -print
tùy chọn, thêm vào sự thù địch của người dùng.
locate
ít linh hoạt hơn, nhưng trực quan hơn nhiều để sử dụng trong trường hợp phổ biến.
find . -name 'nametosearch'
hoặc -iname
cho trường hợp không nhạy cảm. Thay thế .
bằng một đường dẫn thư mục để tìm kiếm khác với thư mục hiện tại. Ở đó, đó là 90% các yêu cầu của người dùng mới được bảo hiểm mà thậm chí không được đưa vào tập tin toàn cầu. (Tôi thường sẽ sử dụng find . -iname '*partialfilename*'
và nếu tôi tìm kiếm từ /
, tôi sử dụng find / -maxdepth 5 -iname '*partialname*'
mà cắt giảm thời gian tìm kiếm trong khi việc tìm kiếm tất cả mọi thứ tôi quan tâm đến 90% thời gian đó, 75% nhu cầu sử dụng trung gian..) :)
Một nhược điểm nhỏ của định vị là nó có thể không lập chỉ mục khu vực của hệ thống tệp mà bạn quan tâm. Trên các hệ thống máy tính để bàn Debian, ví dụ Linux Mint 17.2, tệp /etc/updatedb.conf được định cấu hình để loại trừ các khu vực nhất định khỏi xem xét , bao gồm / tmp, / var / spool và /home/.ecryptfs.
Bỏ qua /home/.ecryptfs ngăn tên tệp trong các thư mục được mã hóa tiếp xúc với người dùng trái phép. Tuy nhiên, nếu thư mục chính của bạn được mã hóa bằng ecryptfs, điều đó cũng có nghĩa là thư mục chính của bạn không được lập chỉ mục và do đó, vị trí sẽ không bao giờ tìm thấy bất cứ điều gì trong thư mục chính của bạn. Điều này có thể làm cho nó phần lớn vô dụng đối với bạn (nó làm cho tôi). Ngoài việc không tìm thấy kết quả, quá trình cập nhật sẽ tải đĩa của bạn theo định kỳ mà không có lợi ích, và cũng có thể bị vô hiệu hóa nếu bạn là người dùng chính hoặc duy nhất của hệ thống.