คำตอบ:
locate(1)
มีข้อได้เปรียบข้อใหญ่เพียงข้อเดียวfind(1)
: ความเร็ว
find(1)
แม้ว่าจะมีหลายข้อได้เปรียบกว่าlocate(1)
:
find(1)
เป็นดั่งเดิมจะกลับไปเป็นรุ่นแรกของ AT & T ยูนิกซ์ คุณยังจะพบว่าใน Linuxes ตัดลงฝังตัวผ่าน Busybox มันคือทั้งหมดที่เป็นสากล
locate(1)
อายุน้อยกว่าfind(1)
มาก บรรพบุรุษเก่าแก่ที่สุดของlocate(1)
ไม่ปรากฏ 1983 จนและมันก็ไม่สามารถใช้ได้อย่างกว้างขวางว่าเป็น " locate
" จนกระทั่งปี 1994 เมื่อมันถูกนำมาใช้เข้า findutils GNUและเข้าไปใน 4.4BSD
locate(1)
ยังไม่เป็นมาตรฐานดังนั้นจึงไม่ได้ติดตั้งตามค่าเริ่มต้นทุกที่ ระบบปฏิบัติการ POSIX บางประเภทไม่ได้เสนอเป็นตัวเลือกและในกรณีที่ใช้งานได้การปรับใช้อาจขาดคุณสมบัติที่คุณต้องการเนื่องจากไม่มีมาตรฐานอิสระระบุชุดคุณลักษณะขั้นต่ำที่ต้องใช้งาน
มีความเป็นพฤตินัยมาตรฐานเป็นBSDlocate(1)
แต่นั่นเป็นเพียงเพราะอีกสองรสชาติหลักของการlocate
ดำเนินการทั้งหมดของตัวเลือกของ: -0
, -c
, -d
, -i
, -l
, -m
, และ-s
ดำเนินการ 6 ตัวเลือกเพิ่มเติมที่ไม่มีใน BSD : , , , , และ GNUดำเนินหกบวกอีกสี่ : , , และ (ฉันไม่สนใจชื่อแทนและความแตกต่างเล็กน้อยเช่นvs vs. )-S
mlocate
locate
-b
-e
-P
-q
--regex
-w
locate
-A
-D
-E
-p
-?
-h
--help
BSDsและ Mac OS X เรือ locate
BSD
Linuxes ส่วนใหญ่ส่ง GNU locate
แต่ Red Hat Linuxes และ Arch ship mlocate
แทน Debian ไม่ได้ติดตั้งในการติดตั้งพื้นฐาน แต่มีทั้งสองเวอร์ชันในที่เก็บแพ็คเกจเริ่มต้น ถ้าทั้งสองมีการติดตั้งในครั้งเดียว " locate
" mlocate
วิ่ง
Oracle ได้รับการจัดส่งmlocate
ใน Solaris ตั้งแต่ 11.2ซึ่งวางจำหน่ายในเดือนธันวาคม 2014 ก่อนหน้านั้นlocate
ไม่ได้ติดตั้งตามค่าเริ่มต้นบน Solaris (สมมุติว่าสิ่งนี้ทำเพื่อลดความไม่เข้ากันของคำสั่งของ Solaris กับOracle Linuxซึ่งใช้ Red Hat Enterprise Linuxซึ่งใช้mlocate
เช่นกัน)
IBM AIXยังไม่จัดส่งสินค้ารุ่นใด ๆlocate
, อย่างน้อยเป็นของ AIX 7.2เว้นแต่คุณจะติดตั้ง GNU findutils
จากAIX กล่องเครื่องมือสำหรับการใช้งานลินุกซ์
HP-UXก็ดูเหมือนว่าจะขาดlocate
ในระบบฐาน
เก่าUnixes "ของจริง"locate
โดยทั่วไปไม่ได้รวมถึงการดำเนินการของ
find(1)
มีไวยากรณ์นิพจน์ที่ทรงพลังพร้อมฟังก์ชันมากมายตัวดำเนินการบูลีนฯลฯ
find(1)
สามารถเลือกไฟล์ได้มากกว่าชื่อ สามารถเลือกโดย:
เมื่อค้นหาไฟล์โดยใช้ชื่อคุณสามารถค้นหาโดยใช้ไฟล์ไวยากรณ์ globbingในทุกรุ่นของfind(1)
หรือ GNU หรือ BSD รุ่นโดยใช้การแสดงผลปกติ
เวอร์ชันปัจจุบันของlocate(1)
รูปแบบการยอมรับ glob เช่นเดียวกับfind
แต่ BSD locate
ไม่ได้ regexes เลย หากคุณชอบฉันและต้องใช้ความหลากหลายของประเภทเครื่องคุณพบว่าตัวเองพอใจgrep
การกรองเพื่อการพัฒนาพึ่งพาหรือ-r
--regex
locate
ต้องการการกรองที่รัดกุมมากกว่าfind
เพราะ ...
find(1)
ไม่จำเป็นต้องค้นหาระบบไฟล์ทั้งหมด โดยทั่วไปคุณจะชี้ไปที่ไดเรกทอรีย่อยซึ่งเป็นพาเรนต์ที่มีไฟล์ทั้งหมดที่คุณต้องการให้ทำงาน พฤติกรรมทั่วไปสำหรับlocate(1)
การนำไปใช้คือการคายไฟล์ทั้งหมดที่ตรงกับรูปแบบของคุณทิ้งไว้ในการgrep
กรองและเพื่อลดการปะทุลงตามขนาด
(เคล็ดลับความชั่วร้าย: locate /
คุณอาจจะได้รับรายชื่อไฟล์ทั้งหมดในระบบ!)
มีสายพันธุ์มีความlocate(1)
เหมือนslocate(1)
ที่ จำกัด การส่งออกขึ้นอยู่กับสิทธิ์ของผู้ใช้ แต่ตอนนี้ไม่ได้เป็นรุ่นเริ่มต้นของlocate
ในระบบปฏิบัติการใด ๆ ที่สำคัญ
find(1)
สามารถทำสิ่งต่าง ๆกับไฟล์ที่ค้นพบนอกเหนือจากการค้นหาเพียงอย่างเดียว ผู้ประกอบการดังกล่าวมีประสิทธิภาพมากที่สุดและได้รับการสนับสนุนอย่างกว้างขวาง-exec
แต่ก็มีบางราย ใน GNU และ BSD ล่าสุดค้นหาการใช้งานตัวอย่างเช่นคุณมี-delete
และ-execdir
โอเปอเรเตอร์
find(1)
ทำงานแบบเรียลไทม์ดังนั้นผลลัพธ์ของมันจะเป็นข้อมูลล่าสุดเสมอ
เนื่องจากlocate(1)
อาศัยฐานข้อมูลชั่วโมงหรือวันที่อัปเดตในอดีตเอาต์พุตของมันจึงล้าสมัย (นี่เป็นปัญหาแคชเก่า ) เหรียญนี้มีสองด้าน:
locate
สามารถตั้งชื่อไฟล์ที่ไม่มีอยู่อีกต่อไป
GNU locate
และmlocate
มี-e
ธงที่จะทำให้มันตรวจสอบไฟล์ดำรงอยู่ก่อนที่จะพิมพ์ออกมาชื่อของแต่ละไฟล์ค้นพบในอดีตที่ผ่านมา แต่ตอนนี้กินไปบางส่วนของlocate
ประโยชน์จากความเร็วและไม่สามารถใช้ได้ใน BSD locate
นอกเหนือจาก
locate
จะล้มเหลวในการตั้งชื่อไฟล์ที่สร้างขึ้นตั้งแต่การอัพเดทฐานข้อมูลครั้งล่าสุด
คุณเรียนรู้ที่จะไม่locate
มั่นใจในการส่งออกโดยรู้ว่ามันอาจจะผิด
มีวิธีการแก้ไขปัญหานี้ แต่ฉันไม่ได้ตระหนักถึงการใช้งานอย่างแพร่หลาย ตัวอย่างเช่นมีrlocate
แต่ดูเหมือนว่าจะไม่ทำงานกับเคอร์เนล Linux ที่ทันสมัย
find(1)
ไม่เคยมีสิทธิพิเศษมากกว่าที่ผู้ใช้เรียกใช้
เนื่องจากlocate
ให้บริการทั่วโลกแก่ผู้ใช้ทุกคนในระบบจึงต้องการให้updatedb
กระบวนการทำงานตามroot
เพื่อให้สามารถเห็นระบบไฟล์ทั้งหมด สิ่งนี้นำไปสู่การเลือกปัญหาความปลอดภัย:
เรียกใช้updatedb
เป็นรูท แต่ทำให้ไฟล์เอาต์พุตสามารถอ่านได้ทั่วโลกเพื่อให้locate
สามารถรันได้โดยไม่มีสิทธิ์พิเศษ นี่เป็นการเปิดเผยชื่อของไฟล์ทั้งหมดในระบบให้กับผู้ใช้ทั้งหมดอย่างมีประสิทธิภาพ นี่อาจเป็นการละเมิดความปลอดภัยที่เพียงพอที่จะทำให้เกิดปัญหาจริง
BSD ได้locate
รับการกำหนดค่าด้วยวิธีนี้ใน Mac OS X และ FreeBSD
เขียนฐานข้อมูลเป็นแบบอ่านได้เท่านั้นroot
และสร้างlocate
setuid
รูทเพื่อให้สามารถอ่านฐานข้อมูลได้ ซึ่งหมายความว่าlocate
ต้องปรับใช้ระบบการอนุญาตของ OS อีกครั้งอย่างมีประสิทธิภาพดังนั้นจึงไม่แสดงไฟล์ที่คุณไม่สามารถเห็นได้ตามปกติ นอกจากนี้ยังเพิ่มพื้นผิวการโจมตีของระบบของคุณโดยเฉพาะการเสี่ยงต่อการโจมตีที่เพิ่มขึ้น
สร้างlocate
ผู้ใช้หรือกลุ่มพิเศษเพื่อเป็นเจ้าของไฟล์ฐานข้อมูลและทำเครื่องหมายlocate
ไบนารีเป็นsetuid/setgid
ชื่อผู้ใช้ / กลุ่มนั้นเพื่อให้สามารถอ่านฐานข้อมูล สิ่งนี้ไม่ได้ป้องกันการโจมตีการเลื่อนระดับด้วยตัวเอง แต่มันลดความเสียหายที่อาจเกิดขึ้นได้อย่างมาก
mlocate
มีการกำหนดค่าด้วยวิธีนี้ในRed Hat Enterprise Linux
คุณยังคงมีปัญหาอยู่เพราะถ้าคุณสามารถใช้ดีบักเกอร์locate
หรือทำให้การถ่ายโอนข้อมูลหลักคุณจะได้รับในส่วนที่ได้รับการยกเว้นของฐานข้อมูล
ฉันไม่เห็นวิธีการสร้างlocate
คำสั่ง"ปลอดภัย" อย่างแท้จริงโดยขาดการทำงานแยกจากกันสำหรับผู้ใช้แต่ละรายบนระบบซึ่งขัดแย้งกับประโยชน์find(1)
มากมาย
บรรทัดล่างทั้งสองมีประโยชน์มาก locate(1)
จะดีกว่าเมื่อคุณแค่พยายามค้นหาไฟล์ตามชื่อที่คุณรู้ว่ามีอยู่ แต่คุณจำไม่ได้ว่ามันอยู่ตรงไหน find(1)
จะดีกว่าเมื่อคุณมีพื้นที่โฟกัสเพื่อทำการตรวจสอบหรือเมื่อคุณต้องการข้อได้เปรียบมากมาย
find -- "$dir"
ไม่แข็งแกร่ง ( $dir
อาจใช้สำหรับภาคแสดง) ไม่มีทางที่จะทดสอบคุณลักษณะของ symlink ปัญหาการแข่งขัน ... สำหรับฉันfind
และlocate
แก้ไขปัญหาที่แตกต่างกันสองรายการ มีหลายสถานที่ที่ใช้การค้นหาไม่เหมือนจริง (เช่นไดเรกทอรีที่มีไฟล์นับล้าน) locator เป็นระบบการจัดทำดัชนีที่ จำกัด เฉพาะชื่อไฟล์
locate
เป็นสิ่งที่ชอบประมาณคร่าว ๆfind / -type f | gzip > locate.gz
และzgrep "$1" <locate.gz
locate
อยู่ในfindutils
แพคเกจและโปรแกรมจะดำเนินการในแง่ของupdatedb
find(1)
ดังนั้นในแง่ที่ว่าlocate(1)
จริงต้อง find(1)
:)
find
, locate
ฯลฯ ในส่วนอื่น ๆ ดังนั้นจึงไม่จำเป็นต้องมีการกระจ่างชื่อเดียวกันที่ใช้ในส่วนต่างๆของ คู่มือ (เช่นunlink(1)
vs unlink(2)
) พวกเราคุ้นเคยกับการประชุมเห็นว่าเป็นการอ้างอิงหน้าคน
locate
ใช้ฐานข้อมูลที่สร้างไว้ล่วงหน้าซึ่งควรได้รับการอัปเดตเป็นประจำในขณะที่find
วนซ้ำระบบไฟล์เพื่อค้นหาไฟล์
ดังนั้นlocate
จะเร็วกว่าfind
มาก แต่อาจไม่ถูกต้องหากฐานข้อมูล - สามารถมองว่าเป็นแคช - ไม่ได้รับการปรับปรุง (ดูupdatedb
คำสั่ง)
นอกจากนี้ยังfind
สามารถให้ความละเอียดมากขึ้นในขณะที่คุณสามารถกรองไฟล์ได้ทุกคุณสมบัติในขณะที่locate
ใช้รูปแบบที่ตรงกับชื่อไฟล์
find
เป็นไปไม่ได้ที่ผู้ใช้มือใหม่หรือผู้ใช้ระบบปฏิบัติการ Unix จะสามารถใช้งานได้สำเร็จ ในอดีตบางรุ่นfind
ไม่ได้ตั้งค่า-print
ตัวเลือกเพิ่มให้กับผู้ใช้ที่เป็นมิตร
locate
มีความยืดหยุ่นน้อยลง แต่ใช้งานง่ายกว่าในกรณีทั่วไป
find . -name 'nametosearch'
หรือ-iname
สำหรับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ แทนที่.
ด้วยเส้นทางไดเรกทอรีเพื่อค้นหาอื่นที่ไม่ใช่ไดเรกทอรีปัจจุบัน นั่นคือ 90% ของความต้องการของผู้ใช้มือใหม่ที่ครอบคลุมโดยไม่ต้องไปแม้แต่การจัดเก็บไฟล์ (ฉันมักจะใช้find . -iname '*partialfilename*'
และถ้าฉันค้นหาจาก/
ผมใช้find / -maxdepth 5 -iname '*partialname*'
ที่ลดลงเวลาการค้นหาขณะที่การหาทุกอย่างที่ฉันสนใจ 90% ของเวลาที่มี 75% ของความต้องการของผู้ใช้ระดับกลาง..) :)
ข้อเสียเปรียบเล็กน้อยในการค้นหาคืออาจไม่สามารถสร้างดัชนีพื้นที่ของระบบไฟล์ที่คุณสนใจบนระบบเดสก์ท็อปเดเบียนเช่น Linux Mint 17.2, ไฟล์ /etc/updatedb.conf ถูกกำหนดค่าเพื่อแยกพื้นที่บางส่วนออกจากการพิจารณา รวมถึง / tmp, / var / spool และ /home/.ecryptfs
การเพิกเฉย /home/.ecryptfs ป้องกันชื่อไฟล์ในไดเรกทอรีที่เข้ารหัสไม่ให้เปิดเผยกับผู้ใช้ที่ไม่ได้รับอนุญาต อย่างไรก็ตามหากไดเรกทอรีบ้านของคุณถูกเข้ารหัสด้วย ecryptfs ก็หมายความว่าไดเรกทอรีบ้านของคุณไม่ได้รับการจัดทำดัชนีและค้นหาจึงจะไม่พบสิ่งใดในไดเรกทอรีบ้านของคุณ สิ่งนี้อาจทำให้ไร้ประโยชน์มากสำหรับคุณ (ทำเพื่อฉัน) นอกเหนือจากการไม่ค้นหาผลลัพธ์กระบวนการที่ได้รับการอัพเดทจะโหลดดิสก์ของคุณเป็นระยะเพื่อไม่ได้รับประโยชน์และอาจถูกปิดใช้งานหากคุณเป็นผู้ใช้หลักหรือผู้ใช้รายเดียวของระบบ