ค้นหาเว็บไซต์

การทำความเข้าใจและการเรียนรู้เชลล์สคริปต์พื้นฐานและการแก้ไขปัญหาระบบไฟล์ Linux - ตอนที่ 10


Linux Foundation เปิดตัวการรับรอง LFCS (Linux Foundation Certified Sysadmin) ซึ่งเป็นโครงการริเริ่มใหม่ล่าสุดที่มีจุดประสงค์เพื่อให้บุคคลทุกที่ (และทุกที่) ได้รับการรับรองในระดับพื้นฐานถึงระดับกลาง การสนับสนุนการปฏิบัติงานสำหรับระบบ Linux ซึ่งรวมถึงการสนับสนุนระบบและบริการที่ทำงานอยู่ พร้อมด้วยการตรวจสอบและการวิเคราะห์โดยรวม รวมถึงการตัดสินใจอย่างชาญฉลาดเมื่อต้องแจ้งปัญหาให้กับทีมสนับสนุนระดับสูง

ลองชมวิดีโอต่อไปนี้ที่จะแนะนำคุณเกี่ยวกับโปรแกรมการรับรอง Linux Foundation

นี่คือบทความสุดท้าย (ตอนที่ 10) ของซีรีส์ยาว 10 บทช่วยสอนปัจจุบัน ในบทความนี้ เราจะเน้นที่เชลล์สคริปต์พื้นฐานและการแก้ไขปัญหาระบบไฟล์ Linux ทั้งสองหัวข้อจำเป็นสำหรับการสอบรับรอง LFCS

ทำความเข้าใจกับเทอร์มินัลและเชลล์

มาชี้แจงแนวคิดบางประการก่อน

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

  1. [ -a ไฟล์ ] → มีไฟล์อยู่
  2. [ -d file ] → มีไฟล์อยู่และเป็นไดเร็กทอรี
  3. [ -f file ] →file มีอยู่แล้วและเป็นไฟล์ปกติ
  4. [ -u file ] →มีไฟล์อยู่แล้ว และบิต SUID (ตั้งค่า ID ผู้ใช้) ถูกกำหนดไว้แล้ว
  5. [ -g file ] →มีไฟล์อยู่และตั้งค่าบิต SGID แล้ว
  6. [ -k file ] →file มีอยู่แล้วและตั้งค่า Sticky Bit ไว้
  7. [ -r file ] →file มีอยู่แล้วและสามารถอ่านได้
  8. [ -s file ]→ มีไฟล์อยู่และไม่ว่างเปล่า
  9. [ -w file ]→มีไฟล์อยู่และสามารถเขียนได้
  10. [ -x file ] เป็นจริงหากมีไฟล์อยู่และสามารถเรียกใช้งานได้
  11. [ string1=string2 ] → สตริงมีค่าเท่ากัน
  12. [ string1 != string2 ] → สตริงไม่เท่ากัน

[ int1 op int2 ] ควรเป็นส่วนหนึ่งของรายการก่อนหน้า ในขณะที่รายการที่ตามมา (เช่น -eq –> เป็นจริงหาก int1 เท่ากับ int2.) ควรเป็นรายการ “children” ของ [ int1 op int2 ] โดยที่ op เป็นหนึ่งในตัวดำเนินการเปรียบเทียบต่อไปนี้

  1. -eq –> เป็นจริงหาก int1 เท่ากับ int2
  2. -ne –> เป็นจริง ถ้า int1 ไม่เท่ากับ int2
  3. -lt –> เป็นจริงหาก int1 น้อยกว่า int2
  4. -le –> เป็นจริง ถ้า int1 น้อยกว่าหรือเท่ากับ int2
  5. -gt –> เป็นจริงหาก int1 มากกว่า int2
  6. -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

อ่านเพิ่มเติม:

  1. เรียนรู้การเขียนสคริปต์เชลล์: คำแนะนำจากมือใหม่ถึงผู้ดูแลระบบ
  2. 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

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

หากคุณมีคำถามหรือความคิดเห็น เรายินดีเสมอ ดังนั้นอย่าลังเลที่จะติดต่อเราผ่านแบบฟอร์มด้านล่าง!