Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

คู่มือการดูแลระบบสำหรับ Bash

การค้าขายแต่ละครั้งมีเครื่องมือที่เชี่ยวชาญในการค้าขายนั้นบ่อยที่สุด สำหรับผู้ดูแลระบบหลายๆ คน เครื่องมือนั้นคือเชลล์ สำหรับ 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 อันดับแรกของฉันเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุด (หรือดี อย่างน้อย ฉันไม่อ้างสิทธิ์สัจธรรม) เมื่อเขียนสคริปต์ทุบตี

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

  1. ใส่ชื่อตัวแปรทั้งหมดของคุณในวงเล็บปีกกา เช่น ${myvariable} . การทำให้สิ่งนี้เป็นนิสัยทำให้สิ่งต่างๆ เช่น ${variable}_suffix เป็นไปได้และปรับปรุงความสอดคล้องตลอดทั้งสคริปต์ของคุณ
  1. อย่าใช้ backticks ในการประเมินนิพจน์ ใช้ $() ไวยากรณ์แทน ใช้:
    for  file in $(ls); do

    ไม่

    for  file in `ls`; do

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

  1. ความสม่ำเสมอเป็นสิ่งที่ดี เลือกรูปแบบการทำสิ่งใดสิ่งหนึ่งและปฏิบัติตามตลอดทั้งสคริปต์ของคุณ แน่นอน ฉันชอบถ้ามีคนเลือก $() ไวยากรณ์ทับ backticks และรวมตัวแปรไว้ในวงเล็บปีกกา ฉันอยากให้คนใช้ช่องว่างสองหรือสี่ช่อง—ไม่ใช่แท็บ—เพื่อเยื้อง แต่ถึงแม้ว่าคุณจะเลือกทำผิด ก็ยังทำผิดอย่างต่อเนื่อง
  1. ใช้ shebang ที่เหมาะสมสำหรับสคริปต์ทุบตี ในขณะที่ฉันกำลังเขียนสคริปต์ Bash ด้วยความตั้งใจที่จะรันมันด้วย Bash เท่านั้น ฉันมักจะใช้ #!/usr/bin/bash เป็น shebang ของฉัน อย่าใช้ #!/bin/sh หรือ #!/usr/bin/sh . สคริปต์ของคุณจะทำงาน แต่จะทำงานในโหมดความเข้ากันได้—อาจมีผลข้างเคียงที่ไม่ได้ตั้งใจมากมาย (ยกเว้นกรณีที่คุณต้องการ โหมดความเข้ากันได้)
  1. เมื่อเปรียบเทียบสตริง คุณควรอ้างอิงตัวแปรของคุณใน if-statement เพราะหากตัวแปรของคุณว่างเปล่า Bash จะแสดงข้อผิดพลาดสำหรับบรรทัดเหล่านี้:
    if [ ${myvar} == "foo" ]; then
      echo "bar"
    fi

    และจะประเมินเป็นเท็จสำหรับบรรทัดดังนี้:

    if [ "${myvar}" == "foo" ]; then
      echo "bar"
    fi  

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

  1. มันเป็นเรื่องของรสนิยม ฉันเดาว่า แต่ฉันชอบใช้เครื่องหมายเท่ากับ (== ) แม้เมื่อเปรียบเทียบสตริงใน Bash มันเป็นเรื่องของความสม่ำเสมอ และแม้ว่าสำหรับการเปรียบเทียบสตริงเท่านั้น เครื่องหมายเท่ากับเดียวก็ใช้ได้ ใจของฉันก็คิดทันทีว่า "ตัวดำเนินการมอบหมายค่าเท่ากับตัวเดียว!"
  1. ใช้รหัสทางออกที่เหมาะสม ตรวจสอบให้แน่ใจว่าหากสคริปต์ของคุณไม่สามารถทำอะไรได้ แสดงว่าคุณแสดงข้อความแสดงความผิดพลาดเป็นลายลักษณ์อักษรแก่ผู้ใช้ (ควรมีวิธีแก้ไขปัญหา) และส่งรหัสทางออกที่ไม่เป็นศูนย์:
    # we have failed
    echo "Process has failed to complete, you need to manually restart the whatchamacallit"
    exit 1

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

  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}
  1. โดยเฉพาะอย่างยิ่ง หากคุณกำลังเขียนสคริปต์ขนาดใหญ่ และโดยเฉพาะอย่างยิ่ง ถ้าคุณทำงานกับสคริปต์ขนาดใหญ่นั้นร่วมกับผู้อื่น ให้พิจารณาใช้ local คีย์เวิร์ดเมื่อกำหนดตัวแปรภายในฟังก์ชัน local คีย์เวิร์ดจะสร้างตัวแปรโลคัล ซึ่งเป็นตัวแปรที่มองเห็นได้เฉพาะในฟังก์ชันนั้นเท่านั้น สิ่งนี้จำกัดความเป็นไปได้ของตัวแปรที่ขัดแย้งกัน
  1. ผู้ดูแลระบบทุกคนต้องทำในบางครั้ง:ดีบักบางอย่างบนคอนโซล ไม่ว่าจะเป็นของจริงในดาต้าเซ็นเตอร์หรืออันเสมือนผ่านแพลตฟอร์มเวอร์ชวลไลเซชัน หากคุณต้องดีบักสคริปต์ด้วยวิธีนั้น คุณจะขอบคุณตัวเองที่จดจำสิ่งนี้:อย่าเขียนบรรทัดในสคริปต์ของคุณยาวเกินไป!



    ในหลายระบบ ความกว้างเริ่มต้นของคอนโซลยังคงเป็น 80 อักขระ หากคุณต้องการดีบักสคริปต์บนคอนโซลและสคริปต์นั้นมีบรรทัดที่ยาวมาก คุณจะเป็นแพนด้าที่น่าเศร้า นอกจากนี้ สคริปต์ที่มีบรรทัดที่สั้นกว่า—โดยค่าเริ่มต้นยังคงเป็น 80 อักขระ—อ่านและเข้าใจได้ง่ายกว่ามากในตัวแก้ไขทั่วไปเช่นกัน!

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