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

ทำให้คุณอยู่ในวง - ทุบตีในขณะที่จนถึงตัวอย่างวง

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

ลูปดำเนินการจนกว่าค่าของนิพจน์ควบคุมจะเป็น 0 นิพจน์ควบคุมอาจเป็นประเภทข้อมูลสเกลาร์ใดก็ได้

ภาษาเชลล์ยังมีคำสั่งวนซ้ำหรือวนซ้ำหลายรายการ ในบทความนี้ให้เราตรวจสอบคำสั่งวนรอบซึ่ง bash ให้โดยใช้ตัวอย่าง

Bash รองรับคำสั่งวนซ้ำสามประเภทต่อไปนี้

  1. สำหรับวนซ้ำ
  2. ขณะวนซ้ำ
  3. จนกว่าจะวนซ้ำ

บทความนี้เป็นส่วนหนึ่งของชุดการสอน Bash ที่กำลังดำเนินอยู่

สามารถซ้อนลูปได้ เช่นเดียวกับภาษาการเขียนโปรแกรมอื่น ๆ bash ยังรองรับคำสั่ง break เพื่อออกจากลูปปัจจุบันและดำเนินการคำสั่งต่อเพื่อดำเนินการซ้ำครั้งต่อไปของคำสั่งลูป

Bash For Loop – วิธีแรก

สำหรับลูปมักจะใช้เมื่อทราบจำนวนการวนซ้ำก่อนเข้าสู่ bash loop Bash รองรับ for loop สองประเภท รูปแบบแรกของ bash for loop คือ:

for varname in list
	do
		commands ##Body of the loop
	done

ในไวยากรณ์ด้านบน:

  • สำหรับ ใน ทำ และทำ เป็นคำหลัก
  • รายการ คือ รายการใดๆ ที่มีรายการของรายการ
  • varname คือชื่อตัวแปรของ Bash

ในแบบฟอร์มนี้ คำสั่ง for จะดำเนินการคำสั่งที่อยู่ในเนื้อหา หนึ่งครั้งสำหรับแต่ละรายการในรายการ รายการปัจจุบันจากรายการจะถูกเก็บไว้ในตัวแปร "varname" แต่ละครั้งผ่านลูป varname นี้สามารถประมวลผลในเนื้อหาของลูปได้ รายการนี้สามารถเป็นตัวแปรที่มีคำหลายคำคั่นด้วยช่องว่าง หาก list หายไปในคำสั่ง for จะใช้พารามิเตอร์ตำแหน่งที่ส่งผ่านไปยังเชลล์

Bash For Loop Example 1. Unzip ไฟล์ Zip ทั้งหมด

ตัวอย่างต่อไปนี้จะค้นหารายการไฟล์ที่ตรงกับ “*.zip*” ในไดเร็กทอรีราก และสร้างไดเร็กทอรีใหม่ในตำแหน่งเดียวกันกับที่มีไฟล์ zip และคลายซิปเนื้อหาไฟล์ zip

# cat zip_unzip.sh
#! /bin/bash
# Find files which has .zip
for file in `find /root -name "*.zip*" -type f`
do

# Skip the extension .zip
dirname=`echo ${file} | awk -F'.' '{print $1}'`

# Create the directory
mkdir $dirname

# Copy the zip file
cp ${file} ${dirname}
cd $dirname

# Unzip the zip file from newly created directory
unzip ${dirname}/$(echo ${file##/*/})
done
  • ในตัวอย่างนี้ คำสั่ง find จะคืนค่ารายการไฟล์ ซึ่งแต่ละไฟล์จะถูกประมวลผลผ่านลูป
  • สำหรับแต่ละรายการ จะสร้างไดเร็กทอรีด้วยชื่อของไฟล์ zip และคัดลอกไฟล์ zip ไปยังไดเร็กทอรีที่สร้างขึ้นใหม่ และแตกไฟล์ zip จากที่นั่น
  • คำสั่ง echo echo ${file##/*/} ให้เฉพาะชื่อไฟล์เท่านั้น ไม่ใช่พาธ
# ./zip_unzip.sh
Archive:  /root/test2/test2.zip
 extracting: t1/p
 extracting: t1/q
 extracting: t1/r
 extracting: t1/s
 extracting: t1/t
 extracting: t1/u
 extracting: t1/v
Archive:  /root/test1/test1.zip
 extracting: t/a
 extracting: t/b
 extracting: t/c
 extracting: t/d
 extracting: t/e

คล้ายกับ Bash loop Awk ยังมี for loop และ while loop ตามที่เราพูดถึงในบทความ Awk While และ For Loop

Bash For Loop – วิธีที่สอง

รูปแบบที่สองของ for loop คล้ายกับ for loop ในภาษาการเขียนโปรแกรม 'C' ซึ่งมีสามนิพจน์ (การกำหนดค่าเริ่มต้น เงื่อนไข และการอัปเดต)

for (( expr1; expr2; expr3 ))
         do
		commands
         done
  • ใน bash ด้านบนสำหรับไวยากรณ์คำสั่ง ก่อนการวนซ้ำครั้งแรก expr1 จะถูกประเมิน โดยปกติจะใช้เพื่อเริ่มต้นตัวแปรสำหรับลูป
  • คำสั่งทั้งหมดระหว่าง do และ done จะถูกดำเนินการซ้ำๆ จนกว่าค่าของ expr2 จะเป็น TRUE
  • หลังจากการวนซ้ำแต่ละครั้งจะมีการประเมิน expr3 โดยปกติแล้วจะใช้เพื่อเพิ่มตัวนับลูป

ตัวอย่างต่อไปนี้สร้างตัวเลขสุ่มจำนวน n ตัว

ทุบตีตัวอย่าง 2 สร้างตัวเลขสุ่ม n ตัว

$ cat random.sh
#! /bin/bash

echo -e "How many random numbers you want to generate"
read max

for (( start = 1; start <= $max; start++ ))
do
        echo -e $RANDOM
done

$ ./random.sh
How many random numbers you want to generate
5
6119
27200
1998
12097
9181

ในข้อมูลโค้ดด้านบน for loop จะสร้างตัวเลขสุ่มที่จำนวนครั้งสูงสุด RANDOM เป็นฟังก์ชันทุบตีภายในที่คืนค่าจำนวนเต็มแบบสุ่มในแต่ละคำขอ

ทุบตีขณะวนซ้ำ

คำสั่งวนซ้ำอื่นที่นำเสนอโดยภาษาโปรแกรมเชลล์คือคำสั่ง while

Syntax:
while expression
do
	commands
done

ในไวยากรณ์ลูปด้านบน:

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

Bash while Example 3 เขียนเนื้อหาลงในไฟล์

ตัวอย่างต่อไปนี้จะอ่านข้อมูลจาก stdout และเขียนลงในไฟล์

$ cat writefile.sh
#! /bin/bash

echo -e "Enter absolute path of the file name you want to create"
read file
while read line
do
echo $line >> $file
done

$ sh writefile.sh
Enter absolute path of the file name you want to create
/tmp/a
while
for
until

$ cat /tmp/a
while
for
until

ตัวอย่างข้างต้น อ่านชื่อไฟล์จากผู้ใช้ และอ่านบรรทัดข้อมูลจาก stdin และต่อท้ายแต่ละบรรทัดกับชื่อไฟล์ที่กำหนด เมื่อ EOF เข้ามา การอ่านจะล้มเหลว ดังนั้นการวนซ้ำจึงสิ้นสุดที่นั่น

หากคุณกำลังเขียน bash script จำนวนมาก คุณสามารถใช้ตัวแก้ไข Vim เป็น Bash IDE โดยใช้ปลั๊กอิน Vim bash-support ดังที่เราได้กล่าวไว้ก่อนหน้านี้

ทุบตีในขณะที่ตัวอย่างที่ 4 อ่านเนื้อหาของไฟล์

ในตัวอย่างก่อนหน้านี้ จะอ่านข้อมูลจาก stdout และเขียนลงในไฟล์ ในตัวอย่างนี้ จะอ่านไฟล์
เนื้อหาและเขียนลงใน stdout

$ cat read.sh
#! /bin/bash
echo -e "Enter absolute path of the file name you want to read"
read file
exec <$file # redirects stdin to a file
while read line
do
echo $line
done

$ ./read.sh

Enter absolute path of the file name you want to read
/tmp/a
while
for
until

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

ทุบจนวนซ้ำ

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

syntax:

until expression
	do
	   commands #body of the loop
	done

ใน bash ด้านบนจนถึง syntax:
where until, do, done คือคีย์เวิร์ด
นิพจน์เงื่อนไขใดๆ

ทุบตีจนถึงตัวอย่างที่ 5 ตรวจสอบไฟล์บันทึก

ตัวอย่างนี้ตรวจสอบขนาดของไฟล์บันทึก เมื่อขนาดไฟล์บันทึกถึง 2000 ไบต์ ระบบจะคัดลอกไฟล์บันทึกนั้นไป

$ cat monitor.sh

file=/tmp/logfile
until [ $(ls -l $file | awk '{print $5}') -gt 2000 ]
        do
            echo "Sleeping for next 5 seconds"
            sleep 5
        done
date=`date +%s`
cp $file "$file-"$date.bak

$ ./monitor.sh
Sleeping for next 5 seconds
Sleeping for next 5 seconds

$ ls -l /tmp/logfile*
-rw-r--r-- 1 sss sss      2010 Jun 24 12:29 logfile
-rw-r--r-- 1 sss sss      2005 Jun 24 16:09 logfile-1277474574.bak

คำสั่ง until ยังคงดำเนินการเนื้อหาของลูปต่อไป จนกว่าเงื่อนไขจะเป็นจริง ในตัวอย่างนี้ เงื่อนไขคือขนาดของไฟล์ที่มากกว่า 2,000 ไบต์ ดังนั้นจึงคัดลอกไฟล์เมื่อถึง 2,000 ไบต์

นอกจากนี้ อย่าลืมอ้างอิงถึงตัวอย่าง Bash Array ก่อนหน้าของเรา

ทุบตีจนถึงตัวอย่างที่ 6 รอให้เครื่องขึ้นมา

ตัวอย่างนี้ใช้เพื่อรอจนกว่าเครื่องจะทำงานก่อนที่จะทำ ssh กับเครื่องนั้น คำสั่ง until loop จะสิ้นสุดเมื่อ ping ตอบกลับเท่านั้น

$ cat mac_wait.sh
#! /bin/bash

read -p "Enter IP Address:" ipadd
echo $ipadd
until ping -c 1 $ipadd
do
        sleep 60;
done
ssh $ipadd

$./mac_wait.sh
Enter IP Address:192.143.2.10
PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data.

--- 192.143.2.10 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

PING 192.143.2.10 (192.143.2.10) 56(84) bytes of data.
64 bytes from 192.143.2.10: icmp_seq=1 ttl=64 time=0.059 ms

--- 192.143.2.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.059/0.059/0.059/0.000 ms
The authenticity of host '192.143.2.10 (192.143.2.10)' can't be established.
Are you sure you want to continue connecting (yes/no)? yes

จนกว่าการวนซ้ำจะมีประโยชน์มากที่บรรทัดคำสั่ง เพื่อเป็นการรอให้เหตุการณ์บางอย่างเกิดขึ้น