ทำไมมันจึง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 *เมื่อคุณเรียกใช้