การทำความเข้าใจและการเรียนรู้เชลล์สคริปต์พื้นฐานและการแก้ไขปัญหาระบบไฟล์ Linux - ตอนที่ 10
Linux Foundation เปิดตัวการรับรอง LFCS (Linux Foundation Certified Sysadmin) ซึ่งเป็นโครงการริเริ่มใหม่ล่าสุดที่มีจุดประสงค์เพื่อให้บุคคลทุกที่ (และทุกที่) ได้รับการรับรองในระดับพื้นฐานถึงระดับกลาง การสนับสนุนการปฏิบัติงานสำหรับระบบ Linux ซึ่งรวมถึงการสนับสนุนระบบและบริการที่ทำงานอยู่ พร้อมด้วยการตรวจสอบและการวิเคราะห์โดยรวม รวมถึงการตัดสินใจอย่างชาญฉลาดเมื่อต้องแจ้งปัญหาให้กับทีมสนับสนุนระดับสูง
ลองชมวิดีโอต่อไปนี้ที่จะแนะนำคุณเกี่ยวกับโปรแกรมการรับรอง Linux Foundation
นี่คือบทความสุดท้าย (ตอนที่ 10) ของซีรีส์ยาว 10 บทช่วยสอนปัจจุบัน ในบทความนี้ เราจะเน้นที่เชลล์สคริปต์พื้นฐานและการแก้ไขปัญหาระบบไฟล์ Linux ทั้งสองหัวข้อจำเป็นสำหรับการสอบรับรอง LFCS
ทำความเข้าใจกับเทอร์มินัลและเชลล์
มาชี้แจงแนวคิดบางประการก่อน
- เชลล์คือโปรแกรมที่รับคำสั่งและมอบให้ระบบปฏิบัติการที่จะดำเนินการ
- เทอร์มินัลคือโปรแกรมที่อนุญาตให้เราในฐานะผู้ใช้ปลายทางสามารถโต้ตอบกับเชลล์ได้ ตัวอย่างหนึ่งของเทอร์มินัลคือเทอร์มินัล GNOME ดังที่แสดงในภาพด้านล่าง
เมื่อเราเริ่มเชลล์ครั้งแรก มันจะแสดงพรอมต์คำสั่ง (หรือที่เรียกว่าบรรทัดคำสั่ง) ซึ่งบอกเราว่าเชลล์พร้อมที่จะเริ่มรับคำสั่งจากอุปกรณ์อินพุตมาตรฐาน ซึ่งโดยปกติจะเป็นคีย์บอร์ด
คุณอาจต้องการอ้างอิงถึงบทความอื่นในชุดนี้ (ใช้คำสั่งเพื่อสร้าง แก้ไข และจัดการไฟล์ - ส่วนที่ 1) เพื่อตรวจสอบคำสั่งที่มีประโยชน์
Linux มีตัวเลือกมากมายสำหรับเชลล์ โดยตัวเลือกที่พบบ่อยที่สุดมีดังนี้:
ทุบตีเชลล์
Bash ย่อมาจาก Bourne Again SHell และเป็นเชลล์เริ่มต้นของโครงการ GNU ประกอบด้วยคุณสมบัติที่เป็นประโยชน์จาก Korn เชลล์ (ksh) และ C เชลล์ (csh) จึงมีการปรับปรุงหลายอย่างในเวลาเดียวกัน นี่คือเชลล์เริ่มต้นที่ใช้โดยการกระจายที่ครอบคลุมในการรับรอง LFCS และเป็นเชลล์ที่เราจะใช้ในบทช่วยสอนนี้
sh เชลล์
Bourne SHell เป็นเชลล์ที่เก่าแก่ที่สุด ดังนั้นจึงเป็นเชลล์เริ่มต้นของระบบปฏิบัติการที่คล้ายกับ UNIX หลายระบบมาหลายปีแล้ว
เคเอสเอช เชลล์
Korn SHell เป็น Unix Shell ซึ่งพัฒนาโดย David Korn ที่ Bell Labs ในช่วงต้นทศวรรษ 1980 มันเข้ากันได้แบบย้อนหลังกับเชลล์ Bourne และมีคุณสมบัติมากมายของเชลล์ C
เชลล์สคริปต์ไม่มีอะไรมากไปกว่าไฟล์ข้อความที่กลายเป็นโปรแกรมปฏิบัติการที่รวมคำสั่งต่าง ๆ ที่ถูกเรียกใช้งานโดยเชลล์ทีละคำสั่ง
การเขียนสคริปต์เชลล์ขั้นพื้นฐาน
ตามที่กล่าวไว้ข้างต้น เชลล์สคริปต์เกิดเป็นไฟล์ข้อความธรรมดา ดังนั้นจึงสามารถสร้างและแก้ไขได้โดยใช้โปรแกรมแก้ไขข้อความที่เราต้องการ คุณอาจต้องการพิจารณาใช้ vi/m (อ้างอิงถึงการใช้งาน vi Editor - ส่วนที่ 2 ของซีรีส์นี้) ซึ่งมีการเน้นไวยากรณ์เพื่อความสะดวกของคุณ
พิมพ์คำสั่งต่อไปนี้เพื่อสร้างไฟล์ชื่อ myscript.sh แล้วกด Enter
vim myscript.sh
บรรทัดแรกของเชลล์สคริปต์ต้องเป็นดังนี้ (หรือที่เรียกว่า shebang)
#!/bin/bash
มัน “บอก ” ระบบปฏิบัติการถึงชื่อของล่ามที่ควรใช้เพื่อเรียกใช้ข้อความที่ตามมา
ถึงเวลาเพิ่มคำสั่งของเราแล้ว เราสามารถชี้แจงวัตถุประสงค์ของแต่ละคำสั่งหรือทั้งสคริปต์ได้โดยการเพิ่มความคิดเห็นด้วย โปรดทราบว่าเชลล์จะละเว้นบรรทัดเหล่านั้นที่ขึ้นต้นด้วยเครื่องหมายปอนด์ # (ความคิดเห็นที่อธิบาย)
#!/bin/bash
echo This is Part 10 of the 10-article series about the LFCS certification
echo Today is $(date +%Y-%m-%d)
เมื่อสคริปต์ถูกเขียนและบันทึกแล้ว เราจำเป็นต้องทำให้สคริปต์นั้นสามารถเรียกใช้งานได้
chmod 755 myscript.sh
ก่อนที่จะรันสคริปต์ เราต้องพูดสักสองสามคำเกี่ยวกับตัวแปรสภาพแวดล้อม ` PATH ถ้าเราวิ่ง
echo $PATH
จากบรรทัดคำสั่ง เราจะเห็นเนื้อหาของ ` PATH: รายการไดเร็กทอรีที่คั่นด้วยโคลอนซึ่งจะถูกค้นหาเมื่อเราป้อนชื่อของโปรแกรมที่ปฏิบัติการได้ มันถูกเรียกว่าตัวแปรสภาพแวดล้อมเนื่องจากเป็นส่วนหนึ่งของสภาพแวดล้อมเชลล์ ซึ่งเป็นชุดข้อมูลที่พร้อมใช้งานสำหรับเชลล์และกระบวนการย่อยเมื่อเชลล์เริ่มทำงานครั้งแรก
เมื่อเราพิมพ์คำสั่งแล้วกด Enter เชลล์จะค้นหาในไดเร็กทอรีทั้งหมดที่อยู่ในตัวแปร ` PATH และดำเนินการอินสแตนซ์แรกที่พบ มาดูตัวอย่างกัน
หากมีไฟล์ปฏิบัติการสองไฟล์ที่มีชื่อเดียวกัน หนึ่งไฟล์ใน /usr/local/bin และอีกไฟล์หนึ่งใน /usr/bin ไฟล์หนึ่งในไดเร็กทอรีแรกจะถูกดำเนินการ อันดับแรก ในขณะที่อีกฝ่ายจะถูกละเลย
หากเราไม่ได้บันทึกสคริปต์ของเราไว้ในไดเร็กทอรีรายการใดรายการหนึ่งในตัวแปร ` PATH เราจำเป็นต้องต่อท้าย ./ ต่อท้ายชื่อไฟล์เพื่อที่จะดำเนินการ มัน. มิฉะนั้น เราสามารถรันมันได้เหมือนกับที่เราทำกับคำสั่งทั่วไป
pwd
./myscript.sh
cp myscript.sh ../bin
cd ../bin
pwd
myscript.sh
เงื่อนไข
เมื่อใดก็ตามที่คุณต้องการระบุแนวทางการดำเนินการที่แตกต่างกันในเชลล์สคริปต์ อันเป็นผลมาจากความสำเร็จหรือความล้มเหลวของคำสั่ง คุณจะใช้โครงสร้าง if เพื่อกำหนดเงื่อนไขดังกล่าว ไวยากรณ์พื้นฐานของมันคือ:
if CONDITION; then
COMMANDS;
else
OTHER-COMMANDS
fi
โดยที่ CONDITION สามารถเป็นหนึ่งในสิ่งต่อไปนี้ (อ้างถึงเฉพาะเงื่อนไขที่พบบ่อยที่สุดที่นี่) และประเมินค่าเป็นจริงเมื่อ:
- [ -a ไฟล์ ] → มีไฟล์อยู่
- [ -d file ] → มีไฟล์อยู่และเป็นไดเร็กทอรี
- [ -f file ] →file มีอยู่แล้วและเป็นไฟล์ปกติ
- [ -u file ] →มีไฟล์อยู่แล้ว และบิต SUID (ตั้งค่า ID ผู้ใช้) ถูกกำหนดไว้แล้ว
- [ -g file ] →มีไฟล์อยู่และตั้งค่าบิต SGID แล้ว
- [ -k file ] →file มีอยู่แล้วและตั้งค่า Sticky Bit ไว้
- [ -r file ] →file มีอยู่แล้วและสามารถอ่านได้
- [ -s file ]→ มีไฟล์อยู่และไม่ว่างเปล่า
- [ -w file ]→มีไฟล์อยู่และสามารถเขียนได้
- [ -x file ] เป็นจริงหากมีไฟล์อยู่และสามารถเรียกใช้งานได้
- [ string1=string2 ] → สตริงมีค่าเท่ากัน
- [ string1 != string2 ] → สตริงไม่เท่ากัน
[ int1 op int2 ] ควรเป็นส่วนหนึ่งของรายการก่อนหน้า ในขณะที่รายการที่ตามมา (เช่น -eq –> เป็นจริงหาก int1 เท่ากับ int2.) ควรเป็นรายการ “children” ของ [ int1 op int2 ] โดยที่ op เป็นหนึ่งในตัวดำเนินการเปรียบเทียบต่อไปนี้
- -eq –> เป็นจริงหาก int1 เท่ากับ int2
- -ne –> เป็นจริง ถ้า int1 ไม่เท่ากับ int2
- -lt –> เป็นจริงหาก int1 น้อยกว่า int2
- -le –> เป็นจริง ถ้า int1 น้อยกว่าหรือเท่ากับ int2
- -gt –> เป็นจริงหาก int1 มากกว่า int2
- -ge –> เป็นจริงหาก int1 มากกว่าหรือเท่ากับ int2
สำหรับลูป
การวนซ้ำนี้อนุญาตให้ดำเนินการหนึ่งคำสั่งขึ้นไปสำหรับแต่ละค่าในรายการค่า ไวยากรณ์พื้นฐานของมันคือ:
for item in SEQUENCE; do
COMMANDS;
done
โดยที่ item คือตัวแปรทั่วไปที่แสดงถึงแต่ละค่าใน SEQUENCE ระหว่างการวนซ้ำแต่ละครั้ง
ในขณะที่ลูป
การวนซ้ำนี้อนุญาตให้ดำเนินการชุดคำสั่งซ้ำ ๆ ตราบใดที่คำสั่งควบคุมดำเนินการโดยมีสถานะออกเท่ากับศูนย์ (สำเร็จ) ไวยากรณ์พื้นฐานของมันคือ:
while EVALUATION_COMMAND; do
EXECUTE_COMMANDS;
done
โดยที่ EVALUATION_COMMAND อาจเป็นคำสั่งใดๆ ที่สามารถออกด้วยสถานะสำเร็จ (0) หรือล้มเหลว (นอกเหนือจาก 0) และ EXECUTE_COMMANDS อาจเป็นโปรแกรม สคริปต์ หรือโครงสร้างเชลล์ใดๆ ก็ได้ รวมถึงลูปที่ซ้อนกันอื่นๆ
วางมันทั้งหมดเข้าด้วยกัน
เราจะสาธิตการใช้ if build และ for loop ดังตัวอย่างต่อไปนี้
การพิจารณาว่าบริการกำลังทำงานอยู่ใน distro แบบ systemd หรือไม่
มาสร้างไฟล์พร้อมรายการบริการที่เราต้องการตรวจสอบโดยสรุป
cat myservices.txt
sshd
mariadb
httpd
crond
firewalld
เชลล์สคริปต์ของเราควรมีลักษณะเช่นนี้
#!/bin/bash
This script iterates over a list of services and
is used to determine whether they are running or not.
for service in $(cat myservices.txt); do
systemctl status $service | grep --quiet "running"
if [ $? -eq 0 ]; then
echo $service "is [ACTIVE]"
else
echo $service "is [INACTIVE or NOT INSTALLED]"
fi
done
มาอธิบายวิธีการทำงานของสคริปต์กัน
1) for loop อ่านไฟล์ myservices.txt ทีละองค์ประกอบของ LIST องค์ประกอบเดียวนั้นแสดงโดยตัวแปรทั่วไปชื่อบริการ LIST เต็มไปด้วยผลลัพธ์ของ
cat myservices.txt
2) คำสั่งดังกล่าวอยู่ในวงเล็บและนำหน้าด้วยเครื่องหมายดอลลาร์เพื่อระบุว่าควรได้รับการประเมินเพื่อเติม LIST ที่เราจะทำซ้ำ
3) สำหรับแต่ละองค์ประกอบของ LIST (หมายถึงทุกอินสแตนซ์ของตัวแปรบริการ) คำสั่งต่อไปนี้จะถูกดำเนินการ
systemctl status $service | grep --quiet "running"
คราวนี้ เราจำเป็นต้องนำหน้าตัวแปรทั่วไปของเรา (ซึ่งแสดงถึงแต่ละองค์ประกอบใน LIST) ด้วยเครื่องหมายดอลลาร์เพื่อระบุว่าเป็นตัวแปร และด้วยเหตุนี้จึงควรใช้ค่าของมันในการวนซ้ำแต่ละครั้ง จากนั้นเอาต์พุตจะถูกส่งไปที่ grep
ธง –quiet ใช้เพื่อป้องกันไม่ให้ grep แสดงบรรทัดที่มีคำว่า running ปรากฏขึ้นบนหน้าจอ เมื่อสิ่งนั้นเกิดขึ้น คำสั่งดังกล่าวจะส่งคืนสถานะการออกเป็น 0 (แสดงโดย $? ในโครงสร้าง if) เพื่อยืนยันว่าบริการกำลังทำงานอยู่
สถานะการออกที่แตกต่างจาก 0 (หมายถึงไม่พบ คำ ที่ทำงานอยู่ในผลลัพธ์ของ systemctl status $service) บ่งชี้ว่าบริการไม่ วิ่ง.
เราอาจก้าวไปอีกขั้นหนึ่งและตรวจสอบการมีอยู่ของ myservices.txt ก่อนที่จะพยายามเข้าสู่ for loop
#!/bin/bash
This script iterates over a list of services and
is used to determine whether they are running or not.
if [ -f myservices.txt ]; then
for service in $(cat myservices.txt); do
systemctl status $service | grep --quiet "running"
if [ $? -eq 0 ]; then
echo $service "is [ACTIVE]"
else
echo $service "is [INACTIVE or NOT INSTALLED]"
fi
done
else
echo "myservices.txt is missing"
fi
ส่ง Ping ชุดเครือข่ายหรือโฮสต์อินเทอร์เน็ตเพื่อดูสถิติการตอบกลับ
คุณอาจต้องการรักษารายชื่อโฮสต์ไว้ในไฟล์ข้อความและใช้สคริปต์เพื่อพิจารณาว่าโฮสต์เหล่านั้นสามารถ ping ได้หรือไม่ (อย่าลังเลที่จะแทนที่เนื้อหาของ myhosts และลองด้วยตัวเอง ).
คำสั่งในตัวเชลล์อ่านจะบอกลูป while ให้อ่าน myhosts ทีละบรรทัด และกำหนดเนื้อหาของแต่ละบรรทัดให้กับโฮสต์ตัวแปร ซึ่งจากนั้นจะถูกส่งไปยังคำสั่ง ping
#!/bin/bash
This script is used to demonstrate the use of a while loop
while read host; do
ping -c 2 $host
done < myhosts
อ่านเพิ่มเติม:
- เรียนรู้การเขียนสคริปต์เชลล์: คำแนะนำจากมือใหม่ถึงผู้ดูแลระบบ
- 5 เชลล์สคริปต์เพื่อเรียนรู้การเขียนโปรแกรมเชลล์
การแก้ไขปัญหาระบบไฟล์
แม้ว่า Linux จะเป็นระบบปฏิบัติการที่เสถียรมาก แต่หากระบบล่มด้วยเหตุผลบางประการ (เช่น เนื่องจากไฟฟ้าดับ) ระบบไฟล์หนึ่งระบบ (หรือมากกว่า) ของคุณจะไม่ถูกถอดออกอย่างถูกต้อง และจะถูกตรวจสอบโดยอัตโนมัติเพื่อหาข้อผิดพลาดเมื่อ Linux ถูกรีสตาร์ท
นอกจากนี้ แต่ละครั้งที่ระบบบู๊ตระหว่างการบู๊ตปกติ ระบบจะตรวจสอบความสมบูรณ์ของระบบไฟล์ก่อนทำการติดตั้งเสมอ ในทั้งสองกรณี จะดำเนินการโดยใช้เครื่องมือชื่อ fsck (“การตรวจสอบระบบไฟล์ ”)
fsck ไม่เพียงแต่จะตรวจสอบความสมบูรณ์ของระบบไฟล์เท่านั้น แต่ยังพยายามซ่อมแซมระบบไฟล์ที่เสียหายหากได้รับคำแนะนำให้ทำเช่นนั้น ขึ้นอยู่กับความรุนแรงของความเสียหาย fsck อาจสำเร็จหรือไม่ เมื่อเป็นเช่นนั้น ส่วนที่กู้คืนของไฟล์จะถูกวางไว้ในไดเร็กทอรี lost+found ซึ่งอยู่ในรากของระบบไฟล์แต่ละระบบ
สุดท้ายแต่ไม่ท้ายสุด เราต้องทราบว่าความไม่สอดคล้องกันอาจเกิดขึ้นได้หากเราพยายามถอดไดรฟ์ USB ขณะที่ระบบปฏิบัติการยังเขียนข้อมูลอยู่ และอาจส่งผลให้ฮาร์ดแวร์เสียหายได้
ไวยากรณ์พื้นฐานของ fsck มีดังนี้:
fsck [options] filesystem
ตรวจสอบระบบไฟล์เพื่อหาข้อผิดพลาดและพยายามซ่อมแซมโดยอัตโนมัติ
ในการตรวจสอบระบบไฟล์ด้วย fsck เราต้องยกเลิกการต่อเชื่อมก่อน
mount | grep sdg1
umount /mnt
fsck -y /dev/sdg1
นอกจากแฟล็ก -y แล้ว เราสามารถใช้ตัวเลือก -a เพื่อซ่อมแซมระบบไฟล์โดยอัตโนมัติโดยไม่ต้องถามคำถามใดๆ และบังคับตรวจสอบแม้ว่าระบบไฟล์จะดูสะอาดก็ตาม
fsck -af /dev/sdg1
หากเราเพียงสนใจที่จะค้นหาว่ามีอะไรผิดปกติ (โดยไม่ได้พยายามแก้ไขสิ่งใดในขณะนี้) เราสามารถเรียกใช้ fsck ด้วยตัวเลือก -n ซึ่งจะส่งออกปัญหาระบบไฟล์ไปยังเอาต์พุตมาตรฐาน
fsck -n /dev/sdg1
ขึ้นอยู่กับข้อความแสดงข้อผิดพลาดในเอาต์พุตของ fsck เราจะทราบว่าเราสามารถลองแก้ไขปัญหาด้วยตนเองหรือส่งต่อไปยังทีมวิศวกรเพื่อทำการตรวจสอบฮาร์ดแวร์เพิ่มเติมได้หรือไม่
สรุป
เรามาถึงตอนท้ายของซีรีส์ 10 บทความ นี้แล้ว โดยได้พยายามครอบคลุมความสามารถพื้นฐานของโดเมนที่จำเป็นในการผ่านการสอบ LFCS
ด้วยเหตุผลที่ชัดเจน จึงเป็นไปไม่ได้ที่จะครอบคลุมทุกแง่มุมของหัวข้อเหล่านี้ในบทช่วยสอนใดๆ และนั่นเป็นเหตุผลที่เราหวังว่าบทความเหล่านี้จะนำคุณไปถูกทางในการลองสิ่งใหม่ๆ ด้วยตัวคุณเองและเรียนรู้ต่อไป
หากคุณมีคำถามหรือความคิดเห็น เรายินดีเสมอ ดังนั้นอย่าลังเลที่จะติดต่อเราผ่านแบบฟอร์มด้านล่าง!