ความคิดเห็น Multiline shell script - มันทำงานอย่างไร


92

เมื่อเร็ว ๆ นี้ฉันได้พบกับประเภทความคิดเห็นหลายบรรทัดที่ฉันไม่เคยเห็นมาก่อน - นี่คือตัวอย่างสคริปต์:

echo a
#
: aaa 
: ddd 
#
echo b

ดูเหมือนว่าจะใช้งานได้แม้กระทั่งvimไวยากรณ์ - ไฮไลท์ รูปแบบการแสดงความคิดเห็นนี้เรียกว่าอะไรและฉันจะหาข้อมูลเพิ่มเติมเกี่ยวกับมันได้อย่างไร


1
ถ้าคุณห่อโค้ดของคุณลงในฟังก์ชั่นเพื่อแสดงความคิดเห็น CommentedOutBlock() { echo "test"; }
Buksy

คำตอบ:


135

นั่นไม่ใช่ความคิดเห็นแบบหลายบรรทัด #เป็นความคิดเห็นบรรทัดเดียว :(โคลอน)ไม่ใช่ความคิดเห็นเลย แต่เป็นคำสั่งในตัวของเชลล์ซึ่งโดยทั่วไปคือNOPซึ่งเป็นการดำเนินการที่ไม่ทำอะไรเลยยกเว้นคืนค่าจริงเช่นtrue(และตั้งค่า$?เป็น 0 เป็นผลข้างเคียง) อย่างไรก็ตามเนื่องจากเป็นคำสั่งจึงสามารถรับอาร์กิวเมนต์ได้และเนื่องจากมันละเว้นการขัดแย้งในกรณีส่วนใหญ่มันจึงทำตัวเหมือนผิวเผิน ปัญหาหลักของ kludge นี้คือข้อโต้แย้งที่ยังคงขยายตัวนำไปสู่โฮสต์ของผลกระทบที่ไม่ได้ตั้งใจ อาร์กิวเมนต์ยังคงได้รับผลกระทบจากข้อผิดพลาดทางไวยากรณ์การเปลี่ยนเส้นทางยังคงดำเนินการดังนั้น: > fileจะถูกตัดทอนfileและการ: $(dangerous command)แทนที่จะยังคงทำงาน

#น่าแปลกใจวิธีที่ปลอดภัยอย่างสมบูรณ์ไม่น้อยกว่าที่จะแทรกความคิดเห็นในเชลล์สคริปต์อยู่กับ ทำตามนั้นแม้กระทั่งสำหรับความคิดเห็นหลายบรรทัด อย่าพยายามใช้ (ab) :เพื่อแสดงความคิดเห็น ไม่มีกลไกการแสดงความคิดเห็นหลายบรรทัดโดยเฉพาะในเชลล์ที่คล้ายคลึงกับ/* */รูปแบบสแลชสตาร์ในCภาษาที่เหมือนกัน


เพื่อความสมบูรณ์ แต่ไม่ใช่เพราะมันเป็นแนวทางปฏิบัติที่แนะนำฉันจะพูดถึงว่าเป็นไปได้ที่จะใช้เอกสารที่นี่เพื่อทำ "ความคิดเห็น" หลายบรรทัด:

: <<'end_long_comment'
This is an abuse of the null command ':' and the here-document syntax
to achieve a "multi-line comment".  According to the POSIX spec linked 
above, if any character in the delimiter word ("end_long_comment" in 
this case) above is quoted, the here-document will not be expanded in 
any way.  This is **critical**, as failing to quote the "end_long_comment" 
will result in the problems with unintended expansions described above. 
All of this text in this here-doc goes to the standard input of :, which 
does nothing with it, hence the effect is like a comment.  There is very 
little point to doing this besides throwing people off.  Just use '#'.
end_long_comment

29
+1 สำคัญมากที่จะเก็บราคาเดียวไว้ใน<<บรรทัดซึ่งจะปิดการทดแทนและการขยาย
เกล็นแจ็คแมน

4
และในฐานะที่เป็นโน้ตเสริมการเติมเชลล์สคริปต์ด้วย:สิ่งที่ควรเป็นความคิดเห็นจะทำให้ปริมาณการใช้ RAM / CPU เพิ่มขึ้น มันจะไม่เก่าสำหรับสิ่งที่ง่ายบนเดสก์ทอปของคุณ แต่ถ้ามันเป็นสิ่งที่ดำเนินการหลายร้อยหรือหลายพันครั้งที่สองคุณจะไม่มีอะไรที่จะทำอย่างรวดเร็วอันยิ่งใหญ่
bahamat

3
@bahamat: ถ้าคุณรันบางสิ่งหลายร้อยหรือหลายพันครั้งต่อวินาทีฉันหวังว่าคุณจะไม่เขียนมันในเชลล์ ... = /
7heo.tk

1
บางครั้งการใช้ยูทิลิตี null สำหรับข้อความหลายบรรทัดอาจมีประโยชน์ เริ่มต้นความคิดเห็นที่มี: <<=cutทำให้มันเป็นไปได้ที่จะเขียน POD ในสคริปต์เปลือกดูตัวอย่างนี้สำหรับรายละเอียด ทำให้สามารถใช้งานperldoc script.shได้ อย่างไรก็ตามความคิดเห็นหลายบรรทัดที่แสดงในคำตอบนี้เป็นสิ่งที่ควรเป็นบล็อกความคิดเห็น (แต่ละบรรทัดที่ขึ้นต้นด้วย# )
พื้นฐาน 6

นี่คือการอภิปรายที่ดีเกี่ยวกับ heredocs ใช้สำหรับความคิดเห็นและกรณีการใช้งานที่น่าสนใจอื่น ๆ (รวมถึงการสร้างสคริปต์ dynaimc): tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz

28

มันไม่ได้เป็นรูปแบบของการแสดงความคิดเห็นใด ๆ :คำสั่งในตัวไม่ทำอะไรเลยอย่าง; มันถูกทารุณกรรมสำหรับการแสดงความคิดเห็นที่นี่

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

25

ในเปลือกต้นโคลอนเป็นวิธีเดียวที่จะสร้างความคิดเห็น

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

: ${a:=x} # assigns the value 'x' to the variable, 'a'

: $(command) # executes 'command'

(บางครั้งเครื่องหมายโคลอนจะใช้เพื่อจุดประสงค์ในการเรียกใช้ผลข้างเคียงเหล่านั้น แต่ก็ไม่ได้ใช้เป็นความคิดเห็น)

บางครั้งการใช้โคลอนเพื่อแสดงความคิดเห็นในส่วนของสคริปต์ทำได้สะดวก

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'

นี่เป็นเครื่องบันทึกเวลาที่ยอดเยี่ยมก่อนหน้าแต่ละบรรทัดด้วย#โดยเฉพาะอย่างยิ่งหากการแสดงความคิดเห็นเป็นเพียงชั่วคราว


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

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

ทางเลือกของการเสนอราคาเดี่ยวหรือการเสนอราคาคู่ควรได้รับอิทธิพลจากสิ่งที่น่ากังวลเล็กน้อยและไม่เกี่ยวข้องกับความกังวลว่าข้อความในสคริปต์ของคุณเป็นสตริงเดี่ยวที่ถูกต้องหรือไม่ ใช้เครื่องหมายคำพูดเดี่ยวเพื่อป้องกันการขยายในขณะที่เครื่องหมายอัญประกาศคู่อนุญาตการขยายที่แน่นอนและต้องการการแยกวิเคราะห์พิเศษ นี่คือเกณฑ์ที่แท้จริงสำหรับการพิจารณาว่าจะใช้อย่างไร
jw013

นี่เป็นวิธีที่เก๋ที่สุดในการทำ เหมาะสำหรับบล็อกเอกสารขนาดเล็ก ฉันชอบมันมากกว่า/* */และไม่ได้เริ่ม<!-- -->เลย!
alex grey

1

หากความคิดเห็นของคุณอยู่ท้ายสคริปต์คุณสามารถทำสิ่งนี้ได้:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.