nullglob
ตัวเลือก (ซึ่ง BTW เป็นzsh
สิ่งประดิษฐ์เพียงเพิ่มปีต่อไปbash
( 2.0
)) จะไม่เหมาะในหลายกรณี และls
เป็นตัวอย่างที่ดี:
ls *.txt
หรือเทียบเท่าที่ถูกต้องมากขึ้น:
ls -- *.txt
ด้วยnullglob
on จะทำงานls
โดยไม่มีอาร์กิวเมนต์ซึ่งถือว่าเป็นls -- .
(แสดงรายการไดเรกทอรีปัจจุบัน) หากไม่มีไฟล์ที่ตรงกันซึ่งอาจแย่กว่าการเรียกls
ด้วยตัวอักษร*.txt
เป็นอาร์กิวเมนต์
คุณมีปัญหาคล้ายกันกับยูทิลิตี้ข้อความส่วนใหญ่:
grep foo *.txt
จะมองหาfoo
stdin หากไม่มีtxt
ไฟล์
ค่าเริ่มต้นที่สมเหตุสมผลมากขึ้นและหนึ่งใน csh, tcsh, zsh หรือ fish 2.3+ (และของกระสุน Unix ตอนต้น) คือการยกเลิกคำสั่งโดยสิ้นเชิงหาก glob ไม่ตรงกัน
bash
(ตั้งแต่รุ่น 3) มีfailglob
ตัวเลือกสำหรับการที่ (น่าสนใจที่จะสนทนานี้ตั้งแต่ขัดต่อash
, AT & T ksh
หรือzsh
, bash
ไม่สนับสนุนขอบเขตท้องถิ่นสำหรับตัวเลือก ( แต่ที่มีการเปลี่ยนแปลงได้ใน 4.4) ตัวเลือกที่สามารถใช้งานได้ทั่วโลกไม่ทำลายบางสิ่ง เช่นฟังก์ชั่น bash-completion)
โปรดทราบว่า csh tcsh และจะแตกต่างกันเล็กน้อยจากzsh
, fish
หรือbash -O failglob
ในกรณีเช่น:
ls -- *.txt *.html
ในกรณีที่คุณต้องการ globs ทั้งหมดที่ไม่ตรงกันเพื่อให้คำสั่งถูกยกเลิก ตัวอย่างเช่นหากมีไฟล์ txt หนึ่งไฟล์และไม่มีไฟล์ html นั่นจะกลายเป็น:
ls -- file.txt
คุณจะได้รับกับพฤติกรรมที่zsh
มีsetopt cshnullglob
แต่วิธีที่เหมาะสมมากขึ้นที่จะทำมันในzsh
จะใช้ glob เช่น:
ls -- *.(txt|html)
ในzsh
และksh93
คุณยังสามารถใช้nullglobบนพื้นฐานต่อซึ่งเป็นวิธี saner มากมายกว่าการปรับเปลี่ยนการตั้งค่าระดับโลก:
files=(*.txt(N)) # zsh
files=(~(N)*.txt) # ksh93
จะสร้างอาร์เรย์ว่างถ้าไม่มีtxt
ไฟล์แทนที่จะล้มเหลวคำสั่งด้วยข้อผิดพลาด (หรือทำให้เป็นอาร์เรย์ที่มี*.txt
อาร์กิวเมนต์หนึ่งตัวที่มีเชลล์ตัวอื่น)
รุ่นfish
ก่อนหน้า 2.3 จะทำงานเหมือนbash -O nullglob
แต่ให้คำเตือนเมื่อมีการโต้ตอบเมื่อ glob ไม่ตรงกัน ตั้งแต่ 2.3 มันทำงานเหมือนzsh
ยกเว้นสำหรับใช้ใน globs for
, หรือset
count
ตอนนี้ในบันทึกประวัติศาสตร์พฤติกรรมนั้นได้ถูกทำลายโดยเชลล์เป้าหมาย ในเวอร์ชันก่อนหน้าของ Unix นั้นการทำ globbing นั้นทำได้ผ่านตัว/etc/glob
ช่วยและผู้ช่วยนั้นทำตัวเหมือนcsh
: มันจะล้มเหลวในการออกคำสั่งหากไม่มี globs ที่ตรงกับไฟล์ใด ๆ และลบ globs โดยไม่ต้องจับคู่กัน
ดังนั้นสถานการณ์ที่เราอยู่ในวันนี้เกิดจากการตัดสินใจที่ไม่ถูกต้องในเชลล์เป้าหมาย
โปรดทราบว่าเชลล์เป้าหมาย (และเชลล์ C) มาพร้อมกับคุณสมบัติ Unix ใหม่: สภาพแวดล้อม นั่นหมายความว่าการขยายตัวของตัวแปร (มันบรรพบุรุษเท่านั้นมี$1
, $2
... พารามิเตอร์ตำแหน่ง) เชลล์เป้าหมายแนะนำการทดแทนคำสั่งด้วย
อีกประการหนึ่งการตัดสินใจการออกแบบที่ดีของบอร์นเปลือกก็จะดำเนินการ globbing (และแยก) เมื่อการขยายตัวของตัวแปรและแทนคำสั่ง (อาจจะเข้ากันได้ย้อนหลังกับเปลือก ธ อมป์สันที่echo $1
ยังคงเรียก/etc/glob
ถ้า$1
สัญลักษณ์ที่มีอยู่ (มันเป็นมากขึ้นเช่นก่อนการประมวลผลการขยายตัวแมโคร ที่นั่นเช่นเดียวกับในค่าที่ขยายได้ถูกแยกวิเคราะห์อีกครั้งเป็นรหัสเชลล์))
ความล้มเหลวที่ไม่ตรงกันจะหมายถึงตัวอย่างเช่น:
pattern='a.*b'
grep $pattern file
จะล้มเหลวคำสั่ง (เว้นแต่มีบางa.whateverb
ไฟล์ในไดเรกทอรีปัจจุบัน) csh
(ซึ่งยังดำเนินการ globbing เมื่อการขยายตัวของตัวแปร) ไม่ล้มเหลวคำสั่งการในกรณีที่ (และฉันเถียงจะดีกว่าออกจากข้อผิดพลาดอยู่เฉยๆมีแม้ถ้ามันไม่ดีเท่าที่ไม่ได้ทำ globbing ที่ทุกคนชอบในzsh
)