در دو قسمت قبل یاد گرفتیم:
اما در عمل، کارهای مدیریتی معمولاً روی یک فایل انجام نمیشوند.
بلکه روی:
- چندین فایل log
- چندین اسکریپت
- چندین دایرکتوری
- چندین کاربر
برای انجام کارهای تکراری در Bash از حلقهها (Loops) استفاده میکنیم.
مهمترین حلقه در اسکریپتهای مدیریتی Linux:
for
ساختار پایه حلقه for
ساختار کلی:
for variable in list
do
commands
done
مثال ساده:
for i in 1 2 3
do
echo "Number: $i"
done
خروجی:
Number: 1
Number: 2
Number: 3
حلقه روی فایلها (کاربرد واقعی DBA)
یکی از رایجترین کاربردها، اجرای عملیات روی چند فایل است.
مثلاً بررسی همه فایلهای .log در یک مسیر:
for file in /var/log/*.log
do
echo "Checking $file"
done
در اینجا:
*.log
به آن globbing میگویند.
یعنی Bash تمام فایلهایی که با این الگو match میشوند را جایگزین میکند.
ترکیب for با شرط
فرض کنید بخواهیم فقط فایلهایی را پردازش کنیم که واقعاً وجود دارند.
for file in /var/log/*.log
do
if [[ -f "$file" ]]; then
echo "Processing $file"
fi
done
این ترکیب for + if پایه بسیاری از اسکریپتهای automation است.
اجرای چند اسکریپت پشت سر هم
فرض کنید چند اسکریپت در یک دایرکتوری دارید و میخواهید همه را اجرا کنید.
for script in /opt/scripts/*.sh
do
if [[ -x "$script" ]]; then
echo "Executing $script"
"$script"
fi
done
در اینجا:
- ابتدا بررسی میکنیم فایل executable است (
-x) - سپس آن را اجرا میکنیم
این الگو در اسکریپتهای ماژولار بسیار رایج است.
استفاده از {} برای تولید عدد
گاهی میخواهیم یک کار را تعداد مشخصی بار انجام دهیم.
for i in {1..5}
do
echo "Run number $i"
done
این روش به آن brace expansion میگویند.
حلقه روی خروجی یک دستور
یکی از کاربردیترین حالتها:
for user in $(cut -d: -f1 /etc/passwd)
do
echo "User: $user"
done
اینجا:
cut -d:فایل passwd را بر اساس:جدا میکند- فقط ستون اول (نام کاربر) را میگیرد
- حلقه روی همه کاربران اجرا میشود
⚠ نکته حرفهای:
این روش در فایلهایی که فاصله دارند میتواند مشکل ایجاد کند. در نسخههای پیشرفتهتر از while read استفاده میشود که در مقالههای بعدی بررسی میکنیم.
استفاده از break
برای خروج از حلقه:
for i in {1..10}
do
if [[ $i -eq 5 ]]; then
break
fi
echo $i
done
حلقه در عدد 5 متوقف میشود.
استفاده از continue
برای رد کردن یک iteration:
for i in {1..5}
do
if [[ $i -eq 3 ]]; then
continue
fi
echo $i
done
عدد 3 چاپ نمیشود.
مثال عملی واقعی
فرض کنید میخواهیم بررسی کنیم کدام فایلهای یک دایرکتوری permission ناامن دارند.
for file in /tmp/*
do
if [[ -f "$file" ]]; then
mode=$(stat -c %a "$file")
if [[ "$mode" == "777" ]]; then
echo "Insecure permission: $file"
fi
fi
done
در این مثال:
- روی همه فایلهای
/tmploop میزنیم - permission را میخوانیم
- اگر 777 بود هشدار میدهیم
این دقیقاً همان نوع منطقی است که در اسکریپتهای امنیتی استفاده میشود.
اشتباه رایج
❌ اشتباه:
for file in /var/log/*.log
do
echo $file
done
✅ بهتر:
for file in /var/log/*.log
do
echo "$file"
done
همیشه متغیرها را در کوتیشن قرار دهید.
تمرین
یک اسکریپت بنویسید که:
- روی تمام فایلهای
/etc/*.confloop بزند - بررسی کند کدام فایلها قابل خواندن نیستند
- نام آنها را چاپ کند