ทำไมมันจึงfind
พิมพ์ออกมานำ./
ไปสู่ผลลัพธ์หากไม่มีการกำหนดเส้นทาง
$ find
./file1
./file2
./file3
อะไรคือสาเหตุที่ไม่พิมพ์ออกมา?
$ find
file1
file2
file3
ทำไมมันจึงfind
พิมพ์ออกมานำ./
ไปสู่ผลลัพธ์หากไม่มีการกำหนดเส้นทาง
$ find
./file1
./file2
./file3
อะไรคือสาเหตุที่ไม่พิมพ์ออกมา?
$ find
file1
file2
file3
คำตอบ:
เหตุผลว่าทำไมคุณเห็นนี้เป็นเพราะการพัฒนาของ GNU เลือกเพื่อให้พฤติกรรมที่ "เหมาะสม" สำหรับเมื่อไม่มีเส้นทางที่จะได้รับ ในทางตรงกันข้ามPOSIXไม่ได้ระบุว่าพารามิเตอร์เป็นตัวเลือก:find
find
find
ยูทิลิตี้จะซ้ำลงไดเรกทอรีลำดับชั้นจากแต่ละไฟล์ระบุโดยเส้นทาง , การประเมินนิพจน์บูลีนประกอบด้วยพรรคอธิบายไว้ในส่วนถูกดำเนินการสำหรับแต่ละไฟล์พบ แต่ละตัวถูกดำเนินการเส้นทางจะถูกประเมินไม่เปลี่ยนแปลงตามที่มันถูกจัดเตรียมไว้รวมถึง<slash>
อักขระต่อท้ายทั้งหมด ชื่อพา ธ ทั้งหมดสำหรับไฟล์อื่น ๆ ที่พบในลำดับชั้นจะประกอบด้วยการรวมกันของตัวถูกดำเนินการเส้นทางปัจจุบัน a<slash>
หากตัวถูกดำเนินการเส้นทางปัจจุบันไม่ได้จบในหนึ่งและชื่อไฟล์ที่เกี่ยวข้องกับเส้นทางตัวถูกดำเนินการ ส่วนที่สัมพันธ์กันจะต้องไม่มีส่วนประกอบของจุดหรือจุดใดจุดหนึ่งไม่มีส่วนท้ายอักขระและ<slash>
อักขระเดียวเท่านั้นระหว่างส่วนประกอบชื่อพา ธ
คุณสามารถเห็นความแตกต่างในบทสรุปสำหรับแต่ละคน GNU มีรายการเสริม (เช่นเดียวกับการประชุม) ในวงเล็บเหลี่ยม:
find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
[expression]
ในขณะที่ POSIX ไม่ได้ระบุว่าสามารถเลือกได้:
find [-H|-L] path... [operand_expression...]
ในโปรแกรม GNU ทำในftsfind.c
:
ถ้า (ว่างเปล่า) { / * * เราใช้ตัวแปรชั่วคราวที่นี่เพราะการกระทำบางอย่างแก้ไข * เส้นทางชั่วคราว ดังนั้นถ้าเราใช้ค่าคงที่สตริง * เราได้รับ coredump ตัวอย่างที่ดีที่สุดคือถ้าเราพูด * "find -printf% H" (หมายเหตุไม่ใช่ "find. -printf% H") * / char defaultpath [2] = "."; return find (defaultpath); }
และตัวอักษร"."
ถูกใช้เพื่อความเรียบง่าย ดังนั้นคุณจะเห็นผลลัพธ์เดียวกันกับ
find
และ
find .
เพราะ (และ POSIX ตกลง) เส้นทางที่กำหนดจะถูกใช้เพื่อนำหน้าผลลัพธ์ (ดูด้านบนสำหรับการต่อข้อมูล )
ด้วยการทำงานเพียงเล็กน้อยเราสามารถกำหนดได้ว่าเมื่อใดที่มีการเพิ่มสถานที่นั้น มันมีอยู่ในการสร้างครั้งแรกของ "findutils" ในปี 1996 (ดูfind.c
):
+ /* If no paths are given, default to ".". */
+ for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+ process_top_path (argv[i]);
+ if (i == 1)
+ process_top_path (".");
+
+ exit (exit_status);
+}
จากรายการเปลี่ยนแปลงสำหรับการค้นหา 3.8 ดูเหมือนว่าจะเป็นเช่นนี้
Sat Dec 15 19:01:12 1990 David J. MacKenzie (djm at egypt)
* find.c (main), util.c (usage): Make directory args optional,
defaulting to "."
./
โดยปกติแล้วใครไม่โพสต์ของไฟล์และในกรณีที่อาจมีประโยชน์มากที่จะเริ่มต้นกับชื่อไฟล์ โดยเฉพาะอย่างยิ่งถ้าชื่อไฟล์เริ่มต้นด้วย-
คำสั่งที่ตามมาสามารถตีความตัวเลือกชื่อไฟล์ที่ ./
หลีกเลี่ยงสิ่งนั้น
เป็นตัวอย่างให้พิจารณาไดเร็กทอรีที่มีไฟล์เหล่านี้:
$ ls
--link --no-clobber
ตอนนี้ลองนึกภาพว่าคำสั่งนี้จะทำงานอย่างไรหากชื่อไฟล์ถูกจัดเตรียมไว้โดยไม่มี./
ด้านหน้า:
$ find -type f -exec cp -t ../ {} +
เราสามารถอธิบายปัญหาด้วยfind
ตัวเอง ลองเรียกใช้ในไดเรกทอรีเดียวกันกับข้างบน ผลงานดังต่อไปนี้:
$ find ./*
./--link
./--no-clobber
ล้มเหลวต่อไปนี้:
$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.
file
ต้องการให้ผู้ใช้ระบุพา ธ (เช่น BSD find บน OS X) find . -type f ...
ดังนั้นคุณจะต้องชัดเจนพูดอะไรบางอย่างเช่น จากตรงนั้นมันไม่ใช่ขั้นตอนที่ยิ่งใหญ่สำหรับการค้นหาบางรุ่น (เช่น GNU find) เพื่อเริ่มต้น.
และปล่อยให้ทุกอย่างเป็นไป
find *
ไม่ได้แสดงให้เห็น.
เป็นเพราะ*
รายชื่อไฟล์และโฟลเดอร์ทั้งหมด .
แต่ไม่รวม ทำecho *
ในไดเรกทอรีที่มีเพียงหนึ่งหรือสองไฟล์และคุณจะเห็นว่า .
ไม่มีในรายการ ดังนั้นfind *
ดำเนินการกับแต่ละไฟล์ที่ขยาย มันเหมือนกับว่าคุณพูดfind Desktop/
จากไดเรกทอรีบ้าน คุณจะเห็นผลลัพธ์เป็นDesktop/foo_bar.txt
find
จะทำเช่นนั้น คุณมีข้อมูลอ้างอิงที่เชื่อถือได้เพื่อสนับสนุนการอ้างสิทธิ์โดยนัยที่find
ออกแบบมาเพื่อทำงานในลักษณะนี้ด้วยเหตุผลนี้หรือไม่?
find
คำสั่งต้องการเส้นทาง (s) เพื่อค้นหา หากเราไม่ได้ระบุไว้มันจะใช้ไดเรกทอรีปัจจุบัน ( .
) เป็นจุดเริ่มต้น ในทำนองเดียวกันหากคุณผ่านเส้นทางเช่น/tmp
จะถือว่าเป็นจุดเริ่มต้น และผลลัพธ์ก็คือ
หากไดเรกทอรีปัจจุบัน:
$ find
or
$ find .
output:
./file1
./file2
./file3
หาก/tmp
ไดเรกทอรี:
$ find /tmp
output:
/tmp/file4
/tmp/file5
หากabc
ไดเรกทอรีภายใต้ไดเรกทอรีปัจจุบัน:
$ find abc
output:
abc/file6
abc/file7
หากหลายไดเรกทอรีภายใต้ไดเรกทอรีปัจจุบัน:
$ find fu bar
output:
fu/file10
fu/file11
bar/file8
bar/file9
find
ต้องใช้พา ธ เพื่อค้นหาอะไรก็ได้และมันจะเป็นค่าเริ่มต้นไปยังไดเรกทอรีปัจจุบัน คำถามคือทำไมมันพิมพ์ออกชั้นนำ./
เมื่อเป็นเพียงเช่นเดียวกับfile.txt
./file.txt
หากคุณไม่ได้ระบุพา ธfind
คำสั่งจะถือว่า${PWD}
พา ธ นั้นและพิมพ์ออกมาบนเอาต์พุต ผู้ใช้ที่ไม่ระบุเส้นทางจะไม่เปลี่ยนวิธีการfind
ทำงาน และค้นหาทำงานได้เสมอกับเส้นทางตามค่าเริ่มต้น
/tmp
แล้ว$PWD
คือไม่ได้/tmp
./
/tmp
ให้รันคำสั่งfind /tmp
หากคุณไม่ได้ระบุพา ธ มันจะเป็นไดเรกทอรีปัจจุบันเสมอซึ่งก็คือ./
/tmp
มันไม่ใช่ว่าผมอยากจะเห็นเทมเพลตก่อนหน้า $PWD
มันเป็นเรื่องที่เป็นไปไม่ได้
${PWD}
คือการใช้คำฟุ่มเฟือยที่ไม่ถูกต้อง
find .
, find $PWD
และfind
(ไม่มีเส้นทางถ้าหาของคุณสนับสนุน)
find *
เมื่อคุณเรียกใช้