การค้าขายแต่ละครั้งมีเครื่องมือที่เชี่ยวชาญในการค้าขายนั้นบ่อยที่สุด สำหรับผู้ดูแลระบบหลายๆ คน เครื่องมือนั้นคือเชลล์ สำหรับ Linux ส่วนใหญ่และระบบที่คล้าย Unix อื่นๆ เชลล์เริ่มต้นคือ Bash
Bash เป็นโปรแกรมที่ค่อนข้างเก่า—มีต้นกำเนิดในปลายทศวรรษ 1980—แต่มันสร้างจากเชลล์ที่เก่ากว่ามาก เช่น C shell (csh) ซึ่งมีอายุมากกว่า 10 ปี เนื่องจากแนวคิดของเชลล์นั้นเก่ามาก จึงมีความรู้ลึกลับจำนวนมหาศาลรอที่จะนำไปใช้เพื่อทำให้ชีวิตของผู้ดูแลระบบหรือสาว ๆ ง่ายขึ้นมาก
มาดูข้อมูลพื้นฐานกันบ้าง
มีใครบ้างที่เรียกใช้คำสั่งในฐานะรูทโดยไม่ได้ตั้งใจและทำให้เกิดปัญหาบางอย่าง ยกมือ
ฉันค่อนข้างแน่ใจว่าพวกเราหลายคนเคยเป็นผู้ชายหรือสาวคนนั้นมาก่อน เจ็บปวดมาก. ต่อไปนี้คือเคล็ดลับง่ายๆ บางประการที่จะป้องกันไม่ให้คุณตีหินก้อนนั้นเป็นครั้งที่สอง
ใช้นามแฝง
ขั้นแรก ตั้งค่านามแฝงสำหรับคำสั่งเช่น mv
และ rm
ที่ชี้ไปที่ mv -I
และ rm -I
. เพื่อให้แน่ใจว่าได้เรียกใช้ rm -f /boot
อย่างน้อยก็ขอให้คุณยืนยัน ใน Red Hat Enterprise Linux ชื่อแทนเหล่านี้ถูกกำหนดโดยค่าเริ่มต้นหากคุณใช้บัญชีรูท
หากคุณต้องการตั้งค่านามแฝงเหล่านั้นสำหรับบัญชีผู้ใช้ปกติของคุณเช่นกัน เพียงวางสองบรรทัดนี้ลงในไฟล์ชื่อ .bashrc ในโฮมไดเร็กตอรี่ของคุณ (สิ่งเหล่านี้จะใช้ได้กับ sudo ด้วย):
alias mv='mv -i'
alias rm='rm -i'
ทำให้ข้อความแจ้งรูทของคุณโดดเด่น
อีกสิ่งหนึ่งที่คุณสามารถทำได้เพื่อป้องกันอุบัติเหตุคือต้องแน่ใจว่าคุณตระหนักดีว่าคุณกำลังใช้บัญชีรูท ฉันมักจะทำอย่างนั้นโดยทำให้รูทพรอมต์โดดเด่นจากพรอมต์ที่ใช้สำหรับงานปกติในแต่ละวัน
หากคุณวางสิ่งต่อไปนี้ลงในไฟล์ .bashrc ในโฮมไดเร็กทอรีของ root คุณจะมีข้อความแจ้งรูทที่เป็นสีแดงบนพื้นดำ ทำให้ชัดเจนว่าคุณ (หรือใครก็ตาม) ควรดำเนินการอย่างระมัดระวัง
export PS1="\[$(tput bold)$(tput setab 0)$(tput setaf 1)\]\u@\h:\w # \[$(tput sgr0)\]"
ที่จริงแล้ว คุณควรละเว้นจากการเข้าสู่ระบบให้มากที่สุดเท่าที่จะเป็นไปได้ และให้รันคำสั่ง sysadmin ส่วนใหญ่ของคุณผ่าน sudo แทน แต่นั่นเป็นเรื่องที่แตกต่างออกไป
หลังจากใช้กลเม็ดเล็กๆ น้อยๆ สองสามข้อเพื่อช่วยป้องกัน "ผลข้างเคียงที่ไม่ได้ตั้งใจ" ของการใช้บัญชีรูท มาดูข้อดีสองสามอย่างของ Bash ที่จะช่วยคุณทำงานประจำวันได้
ควบคุมประวัติของคุณ
คุณอาจรู้ว่าเมื่อคุณกดแป้นลูกศรขึ้นใน Bash คุณสามารถดูและนำคำสั่งก่อนหน้าทั้งหมด (หลายๆ คำสั่ง) กลับมาใช้ใหม่ได้ นั่นเป็นเพราะคำสั่งเหล่านั้นได้รับการบันทึกลงในไฟล์ชื่อ .bash_history ในโฮมไดเร็กตอรี่ของคุณ ไฟล์ประวัตินั้นมาพร้อมกับการตั้งค่าและคำสั่งต่างๆ ที่เป็นประโยชน์มาก
ขั้นแรก คุณสามารถดูประวัติคำสั่งล่าสุดทั้งหมดได้โดยพิมพ์ history
หรือจำกัดให้เหลือเพียง 30 คำสั่งสุดท้ายโดยพิมพ์ history 30
. แต่นั่นเป็นวานิลลาสวย คุณสามารถควบคุมได้มากขึ้นว่า Bash จะบันทึกอะไรและจะบันทึกอย่างไร
ตัวอย่างเช่น หากคุณเพิ่มข้อมูลต่อไปนี้ใน .bashrc คำสั่งใดๆ ที่ขึ้นต้นด้วยการเว้นวรรคจะไม่ถูกบันทึกลงในรายการประวัติ:
HISTCONTROL=ignorespace
สิ่งนี้มีประโยชน์หากคุณต้องการส่งรหัสผ่านไปยังคำสั่งในรูปแบบข้อความธรรมดา (ใช่ มันแย่มาก แต่ก็ยังเกิดขึ้น)
หากคุณไม่ต้องการให้คำสั่งที่ดำเนินการบ่อยปรากฏในประวัติของคุณ ให้ใช้:
HISTCONTROL=ignorespace:erasedups
ด้วยวิธีนี้ ทุกครั้งที่คุณใช้คำสั่ง เหตุการณ์ก่อนหน้าทั้งหมดจะถูกลบออกจากไฟล์ประวัติ และเฉพาะการเรียกครั้งสุดท้ายเท่านั้นที่จะถูกบันทึกลงในรายการประวัติของคุณ
การตั้งค่าประวัติที่ฉันชอบเป็นพิเศษคือ HISTTIMEFORMAT
การตั้งค่า สิ่งนี้จะเพิ่มการประทับเวลาก่อนรายการทั้งหมดในไฟล์ประวัติของคุณ ตัวอย่างเช่น ฉันใช้:
HISTTIMEFORMAT="%F %T "
เมื่อฉันพิมพ์ history 5
, ได้ข้อมูลดีๆ ครบถ้วน แบบนี้:
1009 2018-06-11 22:34:38 cat /etc/hosts
1010 2018-06-11 22:34:40 echo $foo
1011 2018-06-11 22:34:42 echo $bar
1012 2018-06-11 22:34:44 ssh myhost
1013 2018-06-11 22:34:55 vim .bashrc
ซึ่งช่วยให้เรียกดูประวัติคำสั่งได้ง่ายขึ้นมาก และค้นหาคำสั่งที่ฉันใช้เมื่อสองวันก่อนเพื่อตั้งค่าอุโมงค์ข้อมูล SSH ไปยังแล็บที่บ้านของฉัน (ซึ่งฉันลืมไปซ้ำแล้วซ้ำเล่า…)
แนวทางปฏิบัติที่ดีที่สุดสำหรับ Bash
ฉันจะสรุปสิ่งนี้ด้วย 11 อันดับแรกของฉันเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุด (หรือดี อย่างน้อย ฉันไม่อ้างสิทธิ์สัจธรรม) เมื่อเขียนสคริปต์ทุบตี
-
สคริปต์ทุบตีอาจซับซ้อนและความคิดเห็นมีราคาถูก หากคุณสงสัยว่าจะเพิ่มความคิดเห็นหรือไม่ ให้เพิ่มความคิดเห็น หากคุณกลับมาหลังจากวันหยุดสุดสัปดาห์และต้องใช้เวลาค้นหาสิ่งที่คุณพยายามจะทำเมื่อวันศุกร์ที่แล้ว แสดงว่าคุณลืมแสดงความคิดเห็น
- ใส่ชื่อตัวแปรทั้งหมดของคุณในวงเล็บปีกกา เช่น
${myvariable}
. การทำให้สิ่งนี้เป็นนิสัยทำให้สิ่งต่างๆ เช่น${variable}_suffix
เป็นไปได้และปรับปรุงความสอดคล้องตลอดทั้งสคริปต์ของคุณ
- อย่าใช้ backticks ในการประเมินนิพจน์ ใช้
$()
ไวยากรณ์แทน ใช้:for file in $(ls); do
ไม่
for file in `ls`; do
ตัวเลือกเดิมเป็นแบบซ้อนได้ อ่านง่ายกว่า และทำให้ประชากรระบบดูแลระบบทั่วไปมีความสุข ห้ามใช้ backticks
- ความสม่ำเสมอเป็นสิ่งที่ดี เลือกรูปแบบการทำสิ่งใดสิ่งหนึ่งและปฏิบัติตามตลอดทั้งสคริปต์ของคุณ แน่นอน ฉันชอบถ้ามีคนเลือก
$()
ไวยากรณ์ทับ backticks และรวมตัวแปรไว้ในวงเล็บปีกกา ฉันอยากให้คนใช้ช่องว่างสองหรือสี่ช่อง—ไม่ใช่แท็บ—เพื่อเยื้อง แต่ถึงแม้ว่าคุณจะเลือกทำผิด ก็ยังทำผิดอย่างต่อเนื่อง
- ใช้ shebang ที่เหมาะสมสำหรับสคริปต์ทุบตี ในขณะที่ฉันกำลังเขียนสคริปต์ Bash ด้วยความตั้งใจที่จะรันมันด้วย Bash เท่านั้น ฉันมักจะใช้
#!/usr/bin/bash
เป็น shebang ของฉัน อย่าใช้#!/bin/sh
หรือ#!/usr/bin/sh
. สคริปต์ของคุณจะทำงาน แต่จะทำงานในโหมดความเข้ากันได้—อาจมีผลข้างเคียงที่ไม่ได้ตั้งใจมากมาย (ยกเว้นกรณีที่คุณต้องการ โหมดความเข้ากันได้)
- เมื่อเปรียบเทียบสตริง คุณควรอ้างอิงตัวแปรของคุณใน if-statement เพราะหากตัวแปรของคุณว่างเปล่า Bash จะแสดงข้อผิดพลาดสำหรับบรรทัดเหล่านี้:
if [ ${myvar} == "foo" ]; then
echo "bar"
fiและจะประเมินเป็นเท็จสำหรับบรรทัดดังนี้:
if [ "${myvar}" == "foo" ]; then
echo "bar"
fiนอกจากนี้ หากคุณไม่แน่ใจเกี่ยวกับเนื้อหาของตัวแปร (เช่น เมื่อคุณแยกวิเคราะห์อินพุตของผู้ใช้) ให้อ้างอิงตัวแปรของคุณเพื่อป้องกันการตีความอักขระพิเศษบางตัว และตรวจสอบให้แน่ใจว่าตัวแปรนั้นถือเป็นคำเดียว แม้ว่าจะมีช่องว่างอยู่ก็ตาม
- มันเป็นเรื่องของรสนิยม ฉันเดาว่า แต่ฉันชอบใช้เครื่องหมายเท่ากับ (
==
) แม้เมื่อเปรียบเทียบสตริงใน Bash มันเป็นเรื่องของความสม่ำเสมอ และแม้ว่าสำหรับการเปรียบเทียบสตริงเท่านั้น เครื่องหมายเท่ากับเดียวก็ใช้ได้ ใจของฉันก็คิดทันทีว่า "ตัวดำเนินการมอบหมายค่าเท่ากับตัวเดียว!"
- ใช้รหัสทางออกที่เหมาะสม ตรวจสอบให้แน่ใจว่าหากสคริปต์ของคุณไม่สามารถทำอะไรได้ แสดงว่าคุณแสดงข้อความแสดงความผิดพลาดเป็นลายลักษณ์อักษรแก่ผู้ใช้ (ควรมีวิธีแก้ไขปัญหา) และส่งรหัสทางออกที่ไม่เป็นศูนย์:
# we have failed
echo "Process has failed to complete, you need to manually restart the whatchamacallit"
exit 1วิธีนี้ช่วยให้เรียกใช้สคริปต์จากสคริปต์อื่นโดยทางโปรแกรมได้ง่ายขึ้นและยืนยันว่าสคริปต์นั้นเสร็จสมบูรณ์
- ใช้กลไกในตัวของ Bash เพื่อให้ค่าเริ่มต้นที่สมเหตุสมผลสำหรับตัวแปรของคุณหรือส่งข้อผิดพลาดหากไม่ได้กำหนดตัวแปรที่คุณคาดว่าจะถูกกำหนด:
# this sets the value of $myvar to redhat, and prints 'redhat'
echo ${myvar:=redhat}# this throws an error reading 'The variable myvar is undefined, dear reader' if $myvar is undefined
${myvar:?The variable myvar is undefined, dear reader}
- โดยเฉพาะอย่างยิ่ง หากคุณกำลังเขียนสคริปต์ขนาดใหญ่ และโดยเฉพาะอย่างยิ่ง ถ้าคุณทำงานกับสคริปต์ขนาดใหญ่นั้นร่วมกับผู้อื่น ให้พิจารณาใช้
local
คีย์เวิร์ดเมื่อกำหนดตัวแปรภายในฟังก์ชันlocal
คีย์เวิร์ดจะสร้างตัวแปรโลคัล ซึ่งเป็นตัวแปรที่มองเห็นได้เฉพาะในฟังก์ชันนั้นเท่านั้น สิ่งนี้จำกัดความเป็นไปได้ของตัวแปรที่ขัดแย้งกัน
- ผู้ดูแลระบบทุกคนต้องทำในบางครั้ง:ดีบักบางอย่างบนคอนโซล ไม่ว่าจะเป็นของจริงในดาต้าเซ็นเตอร์หรืออันเสมือนผ่านแพลตฟอร์มเวอร์ชวลไลเซชัน หากคุณต้องดีบักสคริปต์ด้วยวิธีนั้น คุณจะขอบคุณตัวเองที่จดจำสิ่งนี้:อย่าเขียนบรรทัดในสคริปต์ของคุณยาวเกินไป!
ในหลายระบบ ความกว้างเริ่มต้นของคอนโซลยังคงเป็น 80 อักขระ หากคุณต้องการดีบักสคริปต์บนคอนโซลและสคริปต์นั้นมีบรรทัดที่ยาวมาก คุณจะเป็นแพนด้าที่น่าเศร้า นอกจากนี้ สคริปต์ที่มีบรรทัดที่สั้นกว่า—โดยค่าเริ่มต้นยังคงเป็น 80 อักขระ—อ่านและเข้าใจได้ง่ายกว่ามากในตัวแก้ไขทั่วไปเช่นกัน!
รักบาสจริงๆ ฉันสามารถใช้เวลาหลายชั่วโมงเขียนเกี่ยวกับเรื่องนี้หรือแลกเปลี่ยนลูกเล่นดีๆ กับเพื่อนที่กระตือรือร้น อย่าลืมทิ้งรายการโปรดของคุณในความคิดเห็น!