แก้ไขการใช้อักษรตัวพิมพ์ใหญ่ของตัวแปรสคริปต์ Bash และ shell


193

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

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

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

นั่นเป็นสิ่งที่ฉันทำ มีแหล่งข้อมูลที่เชื่อถือได้ซึ่งเห็นด้วยหรือไม่เห็นด้วยกับวิธีการนี้หรือเป็นเรื่องของสไตล์อย่างหมดจดหรือไม่?

คำตอบ:


262

โดยการประชุมตัวแปรสภาพแวดล้อม ( PAGER, EDITOR, ... ) และตัวแปรเปลือกภายใน ( SHELL, BASH_VERSION, ... ) เป็นตัวพิมพ์ใหญ่ ชื่อตัวแปรอื่น ๆ ทั้งหมดควรเป็นตัวพิมพ์เล็ก

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

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


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

5
ฉันคิดว่าเหตุผลหลักสำหรับการใช้ชื่อตัวแปรตัวพิมพ์ใหญ่คือการหลีกเลี่ยงความขัดแย้งกับคำสั่งเชลล์ เมื่อเร็ว ๆ นี้เรามีชื่อโฮสต์ของหนึ่งในเซิร์ฟเวอร์ของเราเปลี่ยนเป็น '=' เนื่องจากสคริปต์ใช้ตัวแปร 'ชื่อโฮสต์'
ThisSuitIsBlackNot

25
@ThisSuitIsBlackNot ละเว้นรหัสเส็งเคร็งตัวแปรจะถูกนำหน้าด้วยดอลลาร์เมื่อขยายและใช้ในสถานที่ที่พวกเขาไม่สามารถสับสนกับชื่อคำสั่งเมื่อพวกเขาไม่ได้ เห็นได้ชัดว่าการทำชื่อโฮสต์ = หมู่จะทำให้คุณมีปัญหา ไม่ใช่เพราะคุณใช้ "ชื่อโฮสต์" ที่ต่ำกว่า แต่เพราะคุณไม่ได้ใช้ไวยากรณ์การกำหนดที่ถูกต้อง การมอบหมายเสร็จสิ้นด้วย hostname = moo ไม่มีช่องว่าง สมมติว่ารหัสถูกต้องคุณไม่ต้องกังวลเกี่ยวกับชื่อตัวแปรที่ขัดแย้งกับชื่อคำสั่ง
lhunath

3
หนังสือข้อความทั้งหมดที่ฉันได้ดูเป็นตัวพิมพ์ใหญ่ของผู้ใช้เสมอสำหรับตัวแปรเชลล์ทั้งหมด ในขณะที่ชื่อตัวแปรตัวพิมพ์เล็กสามารถใช้ตัวพิมพ์ใหญ่ได้
Brian S. Wilson

3
ฉันไม่รู้สิ่งนี้และฉันเพิ่งเสียเวลาสองสามชั่วโมง มากกว่าการใช้USER="username"ในสคริปต์ทุบตีอัตโนมัติระยะไกลคำสั่งบางอย่างผ่าน SSH user="username"แทน ฮึ ดีใจที่ฉันรู้ตอนนี้!
Gabriel Staples

28

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

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

    ตัวอย่าง:

    • ตัวแปรที่ส่งออกพร้อมคำนำหน้าทั่วไป: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • ค่าคงที่: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • ใช้ "กรณีงู" ( ตัวพิมพ์เล็กและขีดล่างทั้งหมด) สำหรับตัวแปรทั้งหมดที่ถูกกำหนดขอบเขตให้กับสคริปต์หรือบล็อกเดียว

    ตัวอย่าง: input_file first_value max_amount num_errors

    ใช้ตัวพิมพ์ผสมเมื่อตัวแปรโลคัลมีความสัมพันธ์กับตัวแปรสภาพแวดล้อมเช่น: old_IFS old_HOME

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

    ตัวอย่าง: _debug _debug_level _current_log_file

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

    ตัวอย่าง: inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


ดูสิ่งนี้ด้วย:


1
นี่คือการประชุม แต่มันก็แทบจะไม่เป็นที่ยอมรับในระดับสากล เหตุผลต่อคดีอูฐนั้นไม่น่าเชื่อถืออย่างสิ้นเชิง คำแนะนำในการใช้ SHOUTING สำหรับตัวแปรที่ส่งออกเป็นข้อโต้แย้งเล็กน้อย
tripleee

3
ฉันไม่ได้อ้างว่ามันเป็นเรื่องธรรมดา ฉันได้เห็นว่าโปรแกรมเมอร์ส่วนใหญ่ไม่คิดอย่างจริงจังเกี่ยวกับการทำตามอนุสัญญาที่แข็งแกร่งในเชลล์สคริปและคิดที่จะจดบันทึกความคิดของฉันตามสิ่งที่ฉันทำ
codeforester

8

หากตัวแปรเชลล์กำลังจะถูกส่งออกไปยังสภาพแวดล้อมจะมีมูลค่าการพิจารณาว่า POSIX (ฉบับที่ 7, 2018 รุ่น) นิยามตัวแปรสภาพแวดล้อมระบุ:

ชื่อตัวแปรสภาพแวดล้อมที่ใช้โดยยูทิลิตี้ในปริมาณเชลล์และยูทิลิตี้ของ POSIX.1-2017 ประกอบด้วยตัวอักษรตัวพิมพ์ใหญ่ตัวเลขและขีดล่าง ( _) จากอักขระที่กำหนดในชุดอักขระแบบพกพาเท่านั้นและไม่ขึ้นต้นด้วยตัวเลข

...

พื้นที่ชื่อของชื่อตัวแปรสภาพแวดล้อมที่มีตัวอักษรตัวเล็กถูกสงวนไว้สำหรับการใช้งาน แอปพลิเคชันสามารถกำหนดตัวแปรสภาพแวดล้อมใด ๆ ด้วยชื่อจากพื้นที่ชื่อนี้โดยไม่ต้องปรับเปลี่ยนพฤติกรรมของยูทิลิตี้มาตรฐาน


6

ฉันทำสิ่งที่คุณทำ ฉันสงสัยว่ามีแหล่งข้อมูลที่เชื่อถือได้ แต่ดูเหมือนว่าเป็นมาตรฐานที่ครอบคลุมโดยทั่วไป


1
ฉันเห็นด้วย. มันเป็นเพราะ ALL_CAPS นั้นน่าเกลียด แต่ก็เป็นเรื่องดีที่จะทำให้ตัวแปรสภาพแวดล้อมโดดเด่นด้วยการเป็นคนน่าเกลียด
ผอม

1
ฉันเห็นด้วยกับคุณในรูปแบบการเข้ารหัส แต่ฉันไม่เห็นด้วยอย่างแน่นอนว่ามันแพร่หลาย! เชลล์สคริปเป็นหนึ่งในภาษาด้านที่ผู้คนเพิ่งเรียนรู้อย่างไม่เป็นทางการและดังนั้นฉันรู้สึกว่าทุกคนมักจะพูดว่า LOCATION =cat /tmp/location.txt
JasonSmith

@jhs - ฉันโชคดีมากในสคริปต์เชลล์ที่ฉันต้องทำงานด้วย!
Draemon

4
"พื้นที่ชื่อของชื่อตัวแปรสภาพแวดล้อมที่มีตัวอักษรพิมพ์เล็กถูกสงวนไว้สำหรับแอปพลิเคชัน" - POSIX IEEE Std
1003.1-2008

5

ที่จริงแล้วคำว่า "ตัวแปรสภาพแวดล้อม" ดูเหมือนว่าจะเป็นเหรียญที่ค่อนข้างใหม่ Kernighan และ Pike ในหนังสือคลาสสิกของพวกเขา "The UNIX Programming Environment" ตีพิมพ์ในปี 1984 พูดเพียง "ตัวแปรตัวแปร" - ไม่มีแม้แต่รายการสำหรับ "สภาพแวดล้อม" ในดัชนี!


8
ฉันคิดว่านั่นคือการละเว้นของหนังสือ getenv (), setenv () และสภาพแวดล้อมได้รับการแนะนำใน UNIX เวอร์ชัน 7 (1979) en.wikipedia.org/wiki/Version_7_Unix
Juliano

3
หนังสือเล่มนั้นดูเหมือนจะทราบว่าตัวแปรตัวพิมพ์ใหญ่มีความหมายพิเศษ
ashawley

3

มันเป็นเพียงการประชุมที่จัดขึ้นอย่างกว้างขวางฉันสงสัยว่ามีแหล่ง "เผด็จการ" สำหรับมัน


1

ฉันมักจะใช้ ALL_CAPS ทั้งสำหรับสภาพแวดล้อมและตัวแปรทั่วโลก แน่นอนใน Bash ไม่มีขอบเขตของตัวแปรที่แท้จริงดังนั้นจึงมีส่วนที่ดีของตัวแปรที่ใช้เป็น globals (ส่วนใหญ่เป็นการตั้งค่าและการติดตามสถานะ) และ 'locals' ที่ค่อนข้างน้อย (เคาน์เตอร์ตัววนซ้ำสตริงที่สร้างขึ้นบางส่วน


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