ทำไม bash here-string จึงเพิ่มอักขระขึ้นบรรทัดใหม่


34

ตัวอย่างต่อไปนี้แสดงให้เห็นว่าการขึ้นบรรทัดใหม่จะถูกเพิ่มที่นี่สตริง
ทำไมถึงทำเช่นนี้?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a

คำตอบ:


38

คำตอบที่ง่ายคือเนื่องจาก ksh เขียนขึ้นในลักษณะนั้น (และ bash เข้ากันได้) แต่มีเหตุผลสำหรับตัวเลือกการออกแบบนั้น

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

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

Bash และ ksh ไม่สามารถจัดการกับข้อมูลไบนารี่ได้ (มันไม่สามารถรับมือกับตัวละครที่ไม่มีค่า null) ได้ดังนั้นจึงไม่น่าแปลกใจที่สิ่งอำนวยความสะดวกของพวกเขาจะมุ่งเน้นไปที่ข้อมูลตัวอักษร

<<<ไวยากรณ์ที่นี่สตริงส่วนใหญ่จะเป็นเพียงเพื่อความสะดวกสบายอยู่แล้วเช่น<<ที่นี่เอกสาร หากคุณไม่ต้องการเพิ่มบรรทัดใหม่ให้ใช้echo -n(เป็น bash) หรือprintfและไปป์ไลน์


ละเอียดยิ่งกว่าคำตอบของฉัน
Mike

2
ทุบตีอาจจะยืมนี่สตริงจาก ksh93 แต่ ksh ในทางกลับกันพวกเขาจากการยืม zsh ซึ่งพวกเขาได้จากแผน 9 เปลือกRC
Mark Reed

2
<<<ได้รับการแนะนำให้รู้จักกับโลกโดยบอร์นไม่ได้zsh kshและมันก็ได้รับแรงบันดาลใจจากโอเปอเรเตอร์ที่คล้ายกันในพอร์ต Unix rcซึ่งไม่ได้เพิ่มอักขระบรรทัดใหม่พิเศษนั้น น่าสนใจ=(<<<text)ผู้ประกอบการจะไม่เพิ่มบรรทัดใหม่zshนั้น
Stéphane Chazelas

หากคุณสงสัยเกี่ยวกับความสนใจในคำตอบนี้เป็นเพราะคำถามนี้ใน SO
fedorqui

1
มีวิธีใดในการเขียน here-string (โดยไม่ต้องใช้ยูทิลิตี้อื่น ๆ เช่นprintfฯลฯ ) เพื่อหลีกเลี่ยงการขึ้นบรรทัดใหม่ในส่วนท้ายbashหรือไม่? Like @ StéphaneChazelasแหลมเป็นไปได้zshค่ะ
CTodea

3

สถานการณ์หนึ่งที่เป็นประโยชน์ในการเพิ่มบรรทัดใหม่ต่อท้ายที่นี่คือการใช้readคำสั่งเมื่อset -eโหมดใช้งานอยู่ เรียกคืนที่set -eทำให้สคริปต์หยุดทำงานเมื่อมีการใช้คำสั่ง (มากหรือน้อย) ที่สร้างรหัสสถานะที่ไม่เป็นศูนย์ พิจารณาว่าreadจะสร้างรหัสสถานะที่ไม่เป็นศูนย์เมื่อพบสตริงโดยไม่มีการขึ้นบรรทัดใหม่:

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'

-3

ฉันคิดว่านั่นเป็นวิธีเดียวที่จะได้รับการขึ้นบรรทัดใหม่ในตอนท้ายของสตริงที่นี่พิสูจน์:

xxd <<<`echo -ne "a\n"`

ดูเหมือนว่าผู้ประกอบการที่นี่สตริงตัดบรรทัดใหม่ยกเว้นว่าพวกเขาจะได้รับในไวยากรณ์ที่คุณส่ง


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