ในเชลล์ลินุกซ์ทำไมแบ็กสแลช - นิวไลน์จึงไม่แนะนำช่องว่าง?


3

เมื่อใช้เปลือก Linux ฉันเจอสถานการณ์ต่อไปนี้:

$ A=B\
> C
$ echo $A
BC

ในใจของฉันเมื่อขึ้นบรรทัดใหม่พบตัวละครหนีมันไม่สามารถเป็นตัวละคร CR แต่มันก็ยังเป็นบรรทัดใหม่ echo $A ควรตีความว่าเป็น echo B newline C และขึ้นบรรทัดใหม่ควรเป็น IFS สำหรับ echo. ดังนั้นผลลัพธ์ควรเป็น B C แทน BC.

เหตุใดฉันจึงได้รับผลลัพธ์ที่ฉันทำ


สวัสดีผู้ใช้ 3872279 ฉันได้แก้ไขคำถามของคุณเล็กน้อยสำหรับการจัดรูปแบบเป็นหลัก (เพื่อเน้นว่าคำถามของคุณคืออะไร) และเปลี่ยนชื่อเป็นคำอธิบายเพิ่มเติม หากคุณรู้สึกว่าฉันเปลี่ยนเจตนาของคุณในทางใดทางหนึ่งรู้สึกอิสระที่จะย้อนกลับการแก้ไขหรือ แก้ไข เพิ่มเติมด้วยตัวคุณเอง
a CVn

@ MichaelKjörlingอันที่จริงแล้วเนื่องจากภาษาอังกฤษไม่ดีฉันไม่สามารถอธิบายสิ่งที่ฉันต้องการได้อย่างสง่างาม ฉันขอขอบคุณที่คุณมีสิ่งที่อยู่ในใจของฉันและขอบคุณมาก!
user3872279

คำตอบ:


3

quoting man bashส่วน quoting :

แบ็กสแลชที่ไม่มีการอ้างอิง ( \ ) เป็นตัวละครหนี มันรักษาคุณค่าที่แท้จริงของตัวละครต่อไปที่ตามมาด้วยข้อยกเว้น <newline>. ถ้า \<newline> คู่ปรากฏขึ้นและเครื่องหมายทับขวาไม่ได้อ้างถึงตัวเอง \<newline> จะถือว่าเป็นความต่อเนื่องของบรรทัด (นั่นคือจะถูกลบออกจากอินพุตสตรีมและละเว้นอย่างมีประสิทธิภาพ)

สิ่งนี้ช่วยให้คุณสามารถแบ่งคำสั่ง / ลำดับคำสั่งที่ยาวมาก (การไพพ์และการแปลงเอาต์พุต ฯลฯ ) ในสคริปต์เป็นหลายบรรทัดเพื่อให้สามารถอ่านได้


หากต้องการให้มันขึ้นบรรทัดใหม่ตามที่คุณคาดไว้ให้ตัดค่า (และการใช้ตัวแปรในภายหลัง) ในเครื่องหมายคำพูด

$ A="B
> C"
$ echo "$A"
B
C

จากส่วนเดียวกัน:

การใส่อักขระในเครื่องหมายคำพูดเดียวจะคงคุณค่าของตัวอักษรแต่ละตัวไว้ในเครื่องหมายคำพูด ...

การใส่อักขระในเครื่องหมายคำพูดคู่จะเก็บรักษาค่าตัวอักษรของอักขระทั้งหมดภายในเครื่องหมายคำพูดยกเว้น $, `, \และเมื่อเปิดใช้งานการขยายประวัติ! อักขระ $ และ `รักษาความหมายพิเศษไว้ในเครื่องหมายคำพูดคู่ แบ็กสแลชจะคงความหมายพิเศษไว้เฉพาะเมื่อตามด้วยอักขระตัวใดตัวหนึ่งต่อไปนี้: $, `,", \, หรือ .


1

ตอบ "สาเหตุ" ว่า "ทำไมจึงมีประโยชน์":

Backslash-newline ใช้สำหรับ ความต่อเนื่องของเส้น เพื่อแยกสายยาว ovely:

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

ตัวอย่างเช่นคำสั่ง

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD --graph --decorate --pretty=oneline --simplify-by-decoration

สามารถเขียนเป็น

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD \
    --graph --decorate --pretty=oneline --simplify-by-decoration

0
A=B\
C

หมายถึง "A เท่ากับสตริง B ตามด้วยขึ้นบรรทัดใหม่ที่ฉันไม่สนใจตามด้วย C"

ไม่มี CR ในสิ่งที่คุณพิมพ์ตราบใดที่เชลล์เห็น Linux / Unix End Of Line เป็น Line Feed (LF) ไม่ใช่ CR CR ถูกปล่อยออกมาเป็นส่วนหนึ่งของการจัดการขั้ว เทอร์มินัลส่วนใหญ่ต้องการ Line Feed เพื่อวางสายและ Carriage Return เพื่อส่งเคอร์เซอร์กลับไปทางซ้าย เคอร์เนล CR ถูกแทรกโดยเคอร์เนลเมื่อส่ง Line Feed ไปยังเทอร์มินัลเมื่อเทอร์มินัลต้องการ - IOW เชลล์จะไม่สามารถมองเห็นได้ โปรดทราบว่าตัวอย่างเช่นโปรแกรมแก้ไขภาพอาจแยกการใช้ CR และ LF - ตัวละครที่น้อยที่สุดในชิ้นส่วนของหน้าจอถัดไปที่จะเขียนใหม่อาจเกี่ยวข้องกับ LF (เพื่อเลื่อนหน้าลงโดยไม่เปลี่ยนคอลัมน์)

สับสนเล็กน้อยอีกทั้งยังมีการแปลอินพุตสำหรับคีย์บอร์ด ปุ่ม Enter มักจะส่ง Carriage Return (Control-M) แต่เพื่อให้จดจำคำสั่งได้แล้วเชลล์จำเป็นต้องเห็น End Of Line ส่วนเพิ่มเติม stty พารามิเตอร์จึงอธิบายถึงการจัดการเทอร์มินัลเคอร์เนลว่า CR อินพุตควรถูกแปลเป็น End Of Line ดังนั้นเปลือก ยังคง ไม่เห็น CR

ผลลัพธ์ที่ได้คือเทอร์มินัลส่ง:

A=B\<CR>C<CR>

เชลล์ได้รับ:

A=B\<LF>C<LF>

เชลล์วิเคราะห์คำว่า "oh, backslash newline - ฉันแค่เพิกเฉยต่อสิ่งนั้น" และจบลงด้วย:

A=BC<LF>

และในเอาต์พุตเคอร์เนลจะแก้ไขลำดับที่ส่งไปยังเทอร์มินัลระหว่างอินพุตคำสั่งดังนี้:

A=B\<CR><LF>C<CR><LF>

การประมวลผลเคอร์เนลของการจัดการเทอร์มินัลได้รับการจัดการโดยคำสั่งเชลล์ stty และขึ้นอยู่กับการใช้งาน (Linux, Mac OS X, * BSD) รายละเอียดพื้นฐานควรอยู่ภายใต้ man termios, man tty_ioctl. man console_ioctlฯลฯ


คุณมีวัสดุใด ๆ ที่แนะนำให้ฉันรู้เพิ่มเติมเกี่ยวกับ การแปลอินพุตสำหรับคีย์บอร์ด และ " เคอร์เนล CR ถูกแทรกโดยเคอร์เนลเมื่อส่ง Line Feed ไปยังเทอร์มินัลเมื่อเทอร์มินัลต้องการ - IOW เชลล์จะไม่สามารถมองเห็นได้ "
user3872279
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.