ไม่อนุญาตให้ใช้พื้นที่ในชื่อไฟล์หรือไม่?


31

ว่ากันว่าใน Unix และ Linux โดยทั่วไปคุณควรหลีกเลี่ยงช่องว่างในชื่อไฟล์ของไฟล์ (ไฟล์ธรรมดา, dir, ลิงค์, ไฟล์อุปกรณ์, ... )

แต่ฉันทำอย่างนั้นตลอดเวลา สำหรับชื่อไฟล์ที่มีช่องว่างด้านใน

  • ใน Nautilus อักขระช่องว่างจะแสดงเป็นช่องว่าง
  • ในเทอร์มินัล Bash ฉันใช้\ เพื่อแทนช่องว่างหรือใส่ชื่อไฟล์ในเครื่องหมายคำพูดคู่
  • ในการใช้งานไฟล์บาง (Nautilus ไม่แน่ใจว่า OS จะยังทำเช่นนั้น) %20ชื่อไฟล์เขียนด้วยพื้นที่ที่ถูกแทนที่ด้วย

พื้นที่ไม่ได้รับอนุญาตจริงๆในชื่อไฟล์หรือไม่?

คุณใช้หรือจัดการช่องว่างในชื่อไฟล์อย่างถูกต้องได้อย่างไร


17
อนุญาต แต่มันน่ารำคาญจริงๆ ไม่มีเหตุผลเลย อย่าทำมัน
การแข่งขัน Lightness กับโมนิก้า

3
คุณยังสามารถสร้างไฟล์ชื่อ-rf ~(ใช้touch -- "-rf ~") แต่ฉันจะไม่แนะนำ
Ian D. Scott

5
คุณสามารถทำได้มันได้รับอนุญาตเช่นการสร้างสคริปต์ทำลายตนเองที่เรียกว่า "cd" แต่คุณไม่ควรทำ ไฟล์ของคุณมีลักษณะแตกต่างกันใน 3 เครื่องมือที่แตกต่างกันมันไม่ดีพอใช่ไหม
Falco

7
ไม่ใช่ทุกคนที่แบ่งปันความเห็นว่ามันน่ารำคาญจริงๆ และ "ไม่มีเหตุผลสำหรับมัน" เป็นเท็จอย่างเห็นได้ชัดว่ามันไม่จำเป็นต้อง refuting ฉันให้และเรียนรู้วิธีจัดการช่องว่างอย่างถูกต้องเมื่อหลายปีก่อนและส่วนใหญ่มันไม่ใช่เรื่องใหญ่

2
@snailboat Spaces เป็นอาการของปัญหาที่แท้จริงซึ่งขาดมาตรฐาน ระบบไฟล์ Unix อนุญาตให้ "ชื่อ" ไฟล์ถึง blobs ไบนารีที่ไม่ จำกัด เกือบ ไบต์ที่ผิดกฎหมายเท่านั้นคือ 0 และ 47 ( /ตัวคั่น) การใช้จำนวนไบต์ที่เหลือทั้งหมด 254 รายการจะเปิดประตูสู่มารยาท "eldritch" ชื่อที่ไม่สามารถบรรยายได้ทั้งหมด เห็นได้ชัดว่านี่เป็นบ้า แต่ทุกคนไม่เห็นด้วยกับสิ่งที่ "มีเหตุผล" และตัวละครที่แตกต่างกันจะทำลายเครื่องมือที่แตกต่างกัน จุดตัดของสุขภาพจิตของทุกคนเป็นเรื่องที่ค่อนข้างเล็ก
jw013

คำตอบ:


48

เว้นวรรคและแน่นอนว่าทุกตัวละครยกเว้น/และ NUL ได้รับอนุญาตในชื่อไฟล์ คำแนะนำในการไม่ใช้ช่องว่างในชื่อไฟล์มาจากอันตรายที่ซอฟต์แวร์อาจตีความผิดที่พวกเขาสนับสนุนไม่ดี อาจกล่าวได้ว่าซอฟต์แวร์ดังกล่าวเป็นรถบั๊กกี้ แต่เนื้อหาของภาษาการเขียนโปรแกรมเช่นการเขียนสคริปต์เชลล์ทำให้ง่ายต่อการเขียนซอฟต์แวร์ที่หยุดพักเมื่อนำเสนอชื่อไฟล์ที่มีช่องว่างและข้อบกพร่องเหล่านี้มีแนวโน้มที่จะผ่านเพราะเชลล์สคริปต์ไม่ได้ทดสอบโดยนักพัฒนาโดยใช้ชื่อไฟล์ พวกเขา

ช่องว่างที่ถูกแทนที่ด้วย%20มักจะไม่เห็นในชื่อไฟล์ ส่วนใหญ่จะใช้สำหรับ (เว็บ) URL แม้ว่ามันจะเป็นความจริงที่บางครั้งการเข้ารหัส% จาก URL ก็ทำให้มันกลายเป็นชื่อไฟล์โดยบังเอิญ


6
มันคือ "การเข้ารหัส URL" หรือ "การเข้ารหัสเปอร์เซ็นต์" en.wikipedia.org/wiki/URL_encodingตามชื่อที่เหมาะสมที่สุดน่าจะเป็น "การเข้ารหัส URI" แต่ผู้คนพบว่าURLพูดง่ายกว่าURIดังนั้นนี่จึงเป็นรูปแบบทั่วไปของ การเรียกชื่อผิด ขอให้สังเกตว่าชุดของตัวละครที่สงวนไว้ใน URI นั้นมีขนาดใหญ่กว่าสำหรับ * ชื่อไฟล์ nix
goldilocks

1
@ Tim ผมไม่ทราบว่าคุณสามารถระบุตัวอักษร NUL ในใด ๆ bashอาร์กิวเมนต์บรรทัดคำสั่งใน ฉันลองบางสิ่งเช่นข้อความโดยใช้ Ctrl-V และบางอย่างเช่น$(echo -e \\0)แต่มันใช้งานไม่ได้ เหตุผลก็คือเหตุผลที่ NUL ไม่สามารถใช้ในชื่อไฟล์ได้ก็คือไม่สามารถใช้ในสตริง C ได้ (เพราะเป็นตัวถอดรหัสสตริง) และ API พื้นฐานทั้งหมดรวมถึงสตริงทั้งหมดที่จัดการโดยโปรแกรม C ใช้รูปแบบนั้น . เนื่องจากbashเขียนเป็น C จึงอาจไม่มีการสนับสนุนสำหรับสตริงใด ๆ ที่มี NUL อยู่ ฉันอาจจะผิดอาจจะมีบางวิธีปิดบัง ...
Celada

1
เรียงจากขึ้นอยู่กับบริบท ฟังก์ชั่นสตริงโดยทั่วไปจะไม่นับโมฆะสุดท้าย (หรือค่อนข้างเป็นโมฆะแรกคือจุดสิ้นสุดของสตริงแม้ว่าจะมีสิ่งหลังจากนั้น) ดังนั้นในแง่นั้นมันมีความยาวเป็นศูนย์และดังนั้นจึงจะถือว่าว่างเปล่า
goldilocks

3
@Celada ของหลักสูตรที่คุณสามารถใช้และทุบตีที่คุณต้องการNUL $'\0'ตัวอย่างเช่น:find . -print0 | while read -d $'\0' f; do echo "$f"; done
terdon

1
@goldilocks ผู้คนออกเสียง URL จริง ๆ ว่า 'url' โดยคร่าว ๆ กับ 'earl' หรือเปล่า?
Miles Rout

17

ช่องว่างที่จะได้รับอนุญาตในชื่อไฟล์ที่คุณได้สังเกตเห็น

หากคุณดูรายการ "ระบบไฟล์ UNIX ส่วนใหญ่" ในแผนภูมินี้ในวิกิพีเดียคุณจะสังเกตเห็น:

  • อนุญาตให้ใช้ชุดอักขระ 8 บิตใด ๆ เราสามารถ subsume ASCII ขนาด 7 บิตภายใต้ร่มนี้ด้วยเช่นกันเนื่องจากมันเป็นเซตย่อยของชุด 8 บิตที่หลากหลายและถูกนำไปใช้เสมอโดยใช้ 8 บิตไบต์

  • อักขระต้องห้ามเท่านั้นคือ/และ "null" "Null" หมายถึงศูนย์ไบต์ แต่สิ่งเหล่านี้ไม่ได้รับอนุญาตในข้อมูลตัวอักษร

อย่างไรก็ตามถ้าคุณใช้ประโยชน์จากเชลล์คุณอาจรู้ว่ามีตัวละครบางตัวที่จะสร้างความยุ่งยากอย่างมีนัยสำคัญ*ซึ่งเป็นตัวดำเนินการแบบ POSIX

ทั้งนี้ขึ้นอยู่กับวิธีที่คุณต้องการกำหนด "ความยุ่งยาก" คุณสามารถรวมช่องว่าง (ช่องว่างแท็บบรรทัดใหม่ ฯลฯ ) ไว้ในนั้นเนื่องจากสิ่งนี้สร้างความต้องการในการอ้างอิงด้วย""ในการมีเช่นนี้สร้างความจำเป็นในการอ้างกับ แต่นี่เป็นสิ่งที่หลีกเลี่ยงไม่ได้เนื่องจากอนุญาตให้เว้นวรรคดังนั้น ...

คุณใช้หรือจัดการช่องว่างในชื่อไฟล์อย่างถูกต้องได้อย่างไร

ในบริบทของเชลล์ / บรรทัดคำสั่งให้ตัดชื่อไฟล์ในเครื่องหมายคำพูดเดี่ยวหรือคู่ (แต่โปรดทราบว่าไม่ใช่ปัญหาอื่น ๆ ของ WRT เดียวกัน ) หรือหลีกเลี่ยงช่องว่างด้วย\เช่น:

> foo my\ file\ with\ spaces\ in\ the\ name

1
คุณจะระบุอักขระ NUL ใน bash ได้อย่างไร ฉันต้องการทดสอบในชื่อไฟล์
ทิม

1
คุณทำไม่ได้ "ความหมาย execve" หมายถึงความจริงที่ว่าใน C (และทุกภาษาอื่น ๆ ที่ฉันรู้) สตริงข้อความจะสิ้นสุดลงเป็นโมฆะ เปลือกจะดำเนินการในสิ่งที่ซี sneakest ฉันจะคิดเป็นtouch $(echo -e "foo\00bar")- -eกระบวนการ\0Nเป็นค่าฐานแปด foobarแต่ก็ยังได้รับหายไปที่ไหนสักแห่งเช่นที่เพิ่งสร้างไฟล์ชื่อ แน่นอนว่า NULL ไม่สามารถพิมพ์ได้ แต่ฉันรับประกันว่ามันหายไปจากที่นั่นเพราะข้อ จำกัด ของสตริง C
goldilocks

"สตริงข้อความสิ้นสุดลงด้วยค่า null" -> เพื่ออธิบายเพิ่มเติม: สตริงจะถูกจัดเก็บด้วยศูนย์ไบต์เสมอในตอนท้ายซึ่งเป็นสาเหตุว่าทำไม "ไม่อนุญาตให้ใช้" ในข้อความ: หากคุณแทรกหนึ่งสตริงคุณจะสิ้นสุดสตริงอย่างมีประสิทธิภาพ ตรงจุดนั้น เช่นfoo[NULL]barจะจบลงด้วยfooการตั้งใจและจุดประสงค์ส่วนใหญ่ ความจริงที่ไม่ได้เกิดขึ้นกับสิ่งที่echo -eแสดงให้เห็นว่าNULL นั้นถูกตัดออกไปที่ไหนซักแห่ง
goldilocks

5
ภาษาการเขียนโปรแกรมส่วนใหญ่อนุญาตให้ใช้อักขระ null ในสตริง มันเกิดขึ้นว่าภาษาหลักที่ไม่ใช่ C ซึ่ง Unix สร้างขึ้น - และเชลล์ Unix ส่วนใหญ่ไม่อนุญาตให้ใช้อักขระ null ในสตริงเช่นกัน ไม่ว่าในกรณีใด @Tim อินเตอร์เฟส Unix ทั้งหมดใช้สตริงที่สิ้นสุดด้วยค่า null ดังนั้นไบต์ null จึงเป็นสิ่งหนึ่งที่คุณไม่เคยมีในชื่อไฟล์ (บวก/ซึ่งเป็นตัวคั่นไดเรกทอรีและไม่สามารถอ้างอิงได้ดังนั้นอาจอยู่ในชื่อพา ธ แต่ไม่อยู่ในชื่อไฟล์)
Gilles 'หยุดชั่วร้าย'

1
... แต่ [ไม่เป็นไรอีกแล้ว] ไม่ใช่สิ่งที่ฉันจะทำบ่อยเกินไป ในใจของฉันไม่มีเหตุผลที่พวกเขาจะอยู่ในข้อมูลที่เป็นข้อความ ฉันจะแก้ไขให้ถูกต้องแล้ว แต่มันเป็นความคิดเห็น
goldilocks

3

สาเหตุส่วนใหญ่เป็นประวัติการณ์ - ไม่อนุญาตให้ย้อนกลับไปในหมอกของการเว้นวรรคเวลาในชื่อไฟล์ดังนั้นจึงใช้ช่องว่างเป็นตัวคั่นคำหลัก / ชื่อไฟล์ ล่ามเปลือกในอนาคตจะต้องเข้ากันได้กับสคริปต์เก่าและทำให้เราติดอยู่กับอาการปวดหัวที่เรามีในปัจจุบัน

ผู้พัฒนากระบวนการที่ไม่จำเป็นต้องจัดการกับมนุษย์อย่างมากสามารถทำสิ่งต่าง ๆ ได้ง่ายขึ้นโดยการวางช่องว่างไว้ด้วยกัน Apple ทำสิ่งนี้เนื้อหาของ / System / Library / CoreServices / มีช่องว่างน้อยมากโปรแกรมที่มีช่องว่างถูกเปิดในนามของผู้ใช้และ WillLookStrangeIfCamelCased เส้นทางแบบยูนิกซ์เท่านั้นที่คล้ายกันนี้ยังหลีกเลี่ยงช่องว่าง

(เกร็ดเล็กเกร็ดน้อยที่เกี่ยวข้องค่อนข้าง: ในช่วงกลางปี ​​90 จมูกของ Windows กล่าวว่า "ชื่อสิ่งหนึ่งที่คุณสามารถทำได้บน Mac ที่ฉันไม่สามารถทำบน Windows" -> "ใช้ 12 ตัวอักษรในชื่อไฟล์" -> เงียบ สามารถทำได้ทั้ง 12 ตัวอักษร)


1
ฉันเคยใช้ V6 Unix (c. 1978) Spaces ถูกได้รับอนุญาตแล้ว ภารกิจหนึ่งที่ฉันต้องทำก็คือเขียนโปรแกรมเพื่อแยกวิเคราะห์ระบบไฟล์ (โดยใช้ direct disk i / o) แล้วค้นหาไฟล์ที่มีช่องว่างและแบ็คสเปซอยู่ในชื่อ
wallyk

พวกเขาจะลดช่องว่างทั้งหมดหรือไม่หรือชื่อไฟล์มีช่องว่างน้อยมาก?
mikeserv

2

ดังนั้นใช่ตามที่ระบุไว้หลายครั้งที่อื่นชื่อไฟล์สามารถมีได้เกือบทุกตัวอักษร แต่จะต้องมีการบอกว่าชื่อไฟล์คือไม่แฟ้ม มันมีน้ำหนักบางส่วนเป็นแอตทริบิวต์ของไฟล์โดยทั่วไปคุณต้องมีชื่อไฟล์เพื่อเปิดไฟล์ แต่ชื่อไฟล์จะชี้ไปที่ไฟล์จริงเท่านั้น มันคือลิงค์ที่เก็บไว้ในไดเรกทอรีที่บันทึกไว้ข้างๆหมายเลขไอโหนดซึ่งใกล้เคียงกับไฟล์จริงมากขึ้น

ดังนั้นคุณรู้หรือไม่ว่าอะไรก็ตามที่คุณต้องการ เคอร์เนลไม่สนใจ - การอ้างอิงไฟล์ทั้งหมดที่จะจัดการจะจัดการกับหมายเลข inode จริงต่อไป ชื่อไฟล์เป็นสิ่งที่มนุษย์บริโภค - ถ้าคุณต้องการทำให้มันเป็นสิ่งที่บ้ามันเป็นระบบไฟล์ของคุณ ที่นี่ฉันจะทำสิ่งที่บ้า:

ก่อนอื่นฉันจะสร้างไฟล์ 20 ไฟล์และตั้งชื่อไฟล์โดยไม่ใช้ช่องว่างชื่อไฟล์แต่ละชื่อจะมีช่องว่างมากกว่าหนึ่งไฟล์:

until [ $((i=$i+1)) -gt 20 ]
do  v=$v' ' && touch ./"$v"
done

มันตลกดีนะ ดูที่ฉันls:

ls -d ./*
./      ./          ./              ./                  ./                 
./      ./          ./              ./                  ./                  
./      ./          ./              ./                  ./                   
./      ./          ./              ./                  ./     

ตอนนี้ฉันจะสะท้อนไดเรกทอรีนี้:

set -- * ; mkdir ../mirror
ls -i1qdU -- "$@" |
sh -c 'while read inum na
    do  ln -T "$1" ../mirror/$inum
    shift ; done' -- "$@"
ls -d ../mirror/*

นี่คือ../mirror/เนื้อหาของ:

../mirror/423759  ../mirror/423764  ../mirror/423769  ../mirror/423774
../mirror/423760  ../mirror/423765  ../mirror/423770  ../mirror/423775
../mirror/423761  ../mirror/423766  ../mirror/423771  ../mirror/423776
../mirror/423762  ../mirror/423767  ../mirror/423772  ../mirror/423777
../mirror/423763  ../mirror/423768  ../mirror/423773  ../mirror/423778

ตกลง แต่คุณอาจถาม - แต่สิ่งที่ดีคืออะไร คุณจะบอกได้อย่างไรว่าอันไหน คุณจะแน่ใจได้อย่างไรว่าคุณเชื่อมโยงหมายเลข inode ที่ถูกต้องกับชื่อไฟล์ที่ถูกต้อง

ดี...

echo "heyhey" >>./'    ' 
tgt=$(ls -id ./'    ')
cat ../mirror/${tgt%% .*} \
    $(ls -1td ../mirror/* | head -n1) 

เอาท์พุท

heyhey
heyhey

ดูทั้งหมายเลขไอโหนดที่มีอยู่ใน../mirror/"${tgt%% .*}"และที่อ้างอิงโดย./' 'อ้างอิงถึงไฟล์เดียวกัน พวกเขาอธิบายไฟล์เดียวกัน พวกเขาตั้งชื่อมัน แต่ไม่มีอะไรเพิ่มเติม มีความลึกลับไม่จริงเพียงไม่สะดวกบางอย่างที่คุณอาจทำเพื่อตัวเอง แต่ในที่สุดจะมีผลต่อการดำเนินการของระบบไฟล์ยูนิกซ์ของคุณในที่สุด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.