در قسمت قبل با حلقه for آشنا شدیم.
for زمانی مناسب است که لیست مشخصی از آیتمها داشته باشیم، مثل:
- فایلها
- اسکریپتها
- اعداد
اما در بسیاری از اسکریپتهای مدیریتی لازم است دادهها را خط به خط پردازش کنیم.
اینجاست که حلقه while اهمیت پیدا میکند.
این حلقه یکی از مهمترین ابزارها برای کارهایی مثل:
- پردازش فایلها
- تحلیل logها
- خواندن خروجی دستورات
است.
ساختار پایه while
ساختار کلی:
while conditions
do
commands
done
مثال ساده:
i=1
while [[ $i -le 5 ]]
do
echo "Number: $i"
((i++))
done
در این مثال:
- متغیر
iاز 1 شروع میشود - تا زمانی که شرط برقرار باشد حلقه اجرا میشود
- در هر تکرار مقدار آن افزایش مییابد
مهمترین کاربرد while: خواندن فایل خط به خط
یکی از الگوهای بسیار رایج در Bash:
while read line
do
echo "$line"
done < file.txt
در اینجا:
- فایل
file.txtخط به خط خوانده میشود - هر خط در متغیر
lineقرار میگیرد - سپس دستورات داخل حلقه اجرا میشوند
این روش پایه بسیاری از اسکریپتهای پردازش فایل است.
مثال واقعی: بررسی کاربران سیستم
فایل /etc/passwd اطلاعات کاربران سیستم را نگه میدارد.
میتوانیم آن را خط به خط بخوانیم:
while read line
do
echo "User entry: $line"
done < /etc/passwd
اما معمولاً فقط بخشی از اطلاعات برای ما مهم است.
مثلاً نام کاربر.
استفاده از IFS برای جدا کردن فیلدها
در فایل /etc/passwd فیلدها با : جدا شدهاند.
میتوانیم هنگام خواندن فایل این جداکننده را مشخص کنیم:
while IFS=: read user x uid gid home shell
do
echo "User: $user | UID: $uid | Shell: $shell"
done < /etc/passwd
در این مثال:
IFS=:تعیین میکند جداکننده:است- هر فیلد در یک متغیر قرار میگیرد
این تکنیک برای parsing فایلها بسیار مهم است.
پردازش logها با while
فرض کنید میخواهیم فایل log را بررسی کنیم.
while read line
do
if [[ "$line" == *ERROR* ]]; then
echo "Error found: $line"
fi
done < /var/log/messages
در این مثال:
- هر خط از log خوانده میشود
- اگر کلمه
ERRORوجود داشته باشد چاپ میشود
این نوع اسکریپت پایه بسیاری از System Health Check Scriptها است.
خواندن خروجی یک دستور
گاهی لازم است خروجی یک دستور را خط به خط پردازش کنیم.
مثلاً بررسی فرآیندها:
ps -ef | while read line
do
echo "$line"
done
در این حالت:
- خروجی
psوارد حلقه میشود - هر خط جداگانه پردازش میشود
نکته مهم: استفاده از read -r
در اسکریپتهای حرفهای معمولاً از این فرم استفاده میشود:
while read -r line
do
echo "$line"
done < file.txt
گزینه -r باعث میشود Bash کاراکترهای escape را تفسیر نکند و دادهها دقیقتر خوانده شوند.
مثال عملی
اسکریپتی که فایلهای .conf را بررسی میکند:
ls /etc/*.conf 2>/dev/null | while read -r file
do
if [[ ! -r "$file" ]]; then
echo "File not readable: $file"
fi
done
این اسکریپت:
- فایلهای
.confرا لیست میکند - آنها را خط به خط میخواند
- بررسی میکند کدام فایل قابل خواندن نیست
اشتباه رایج
❌ اشتباه:
cat file.txt | while read line
این کار غیرضروری است.
✅ بهتر:
while read line
do
echo "$line"
done < file.txt
این روش سادهتر و کارآمدتر است.
تمرین
اسکریپتی بنویسید که:
- فایل
/etc/passwdرا بخواند - فقط کاربرانی را چاپ کند که shell آنها
/bin/bashاست