Bash for Oracle DBAs — قسمت ۱۰: Arrays، Case و آرگومانهای اسکریپت
تا اینجا یاد گرفتیم چگونه جریان دادهها را مدیریت کنیم و با ابزارهای پردازش متن کار کنیم. اما برای نوشتن اسکریپتهای سطح بالا (Advanced) که در فرآیند Hardening و Audit استفاده میشوند، نیاز داریم اسکریپتهایمان "هوشمندتر" باشند. هوشمند بودن یعنی اسکریپت بتواند چندین مقدار را همزمان مدیریت کند (Arrays)، بر اساس ورودیهای مختلف تصمیمگیری کند (Case) و از طریق خط فرمان دستورالعمل دریافت کند (Arguments).
۱) آرایهها (Arrays) در Bash
در اسکریپتهای DBA، ما اغلب با لیستهایی سروکار داریم؛ مثلاً لیستی از SIDها، لیستی از مسیرهای Oracle Home، یا لیستی از سرویسهای حساس که باید مانیتور شوند. آرایهها به شما اجازه میدهند این لیستها را در یک متغیر واحد ذخیره کنید.
تعریف و دسترسی به آرایهها:
# تعریف آرایه از SIDهای دیتابیس
DB_SIDS=("ORCL" "PROD1" "PROD2" "TEST1")
# دسترسی به اولین عنصر (ایندکس از 0 شروع میشود)
echo ${DB_SIDS[0]}
# دسترسی به تمام عناصر آرایه
echo ${DB_SIDS[@]}
# دریافت تعداد عناصر آرایه
echo ${#DB_SIDS[@]}
کاربرد عملی در اسکریپت Hardening: فرض کنید میخواهید وضعیت امنیت را برای لیستی از مسیرهای حساس بررسی کنید.
SENSITIVE_PATHS=("/etc/passwd" "/etc/shadow" "$ORACLE_HOME/network/admin")
for path in "${SENSITIVE_PATHS[@]}"; do
echo "Checking permissions for: $path"
# در اینجا دستورات Audit قرار میگیرند
done
۲) ساختار شرطی case
در حالی که if-elif-else برای شرطهای منطقی پیچیده عالی است، اما وقتی میخواهید یک متغیر را با چندین مقدار ثابت مقایسه کنید، case بسیار خواناتر و سریعتر است.
مثال: انتخاب محیط عملیاتی
ENVIRONMENT="PROD"
case "$ENVIRONMENT" in
"PROD" | "PRODUCTION")
echo "WARNING: Running in PRODUCTION mode. No destructive changes allowed!"
# در اینجا منطق جلوگیری از تغییرات خطرناک قرار میگیرد
;;
"TEST" | "DEV")
echo "Running in TEST/DEV mode. It is safe to proceed."
;;
*)
echo "Unknown environment. Exiting to be safe."
exit 1
;;
esac
*) به عنوان حالت پیشفرض (Default) عمل میکند که در اسکریپتهای امنیتی بسیار حیاتی است تا از اجرای ناخواسته دستورات در صورت عدم شناسایی محیط جلوگیری شود.
۳) آرگومانهای خط فرمان (Script Arguments)
یک اسکریپت حرفهای نباید مقادیر حساس را درون خود (Hardcoded) داشته باشد. اسکریپت باید بتواند از طریق خط فرمان دستور بگیرد. Bash از متغیرهای شمارهگذاری شده برای این کار استفاده میکند:
$0— نام خود اسکریپت؛$1, $2, ...— اولین، دومین و... آرگومانهای پاس داده شده؛$#— تعداد آرگومانهای پاس داده شده؛$@— تمام آرگومانها بهصورت جداگانه؛$!— آخرین ID پروسهای که در پسزمینه اجرا شد.
یک اسکریپت نمونه برای Audit دیتابیس:
#!/bin/bash
# بررسی اینکه آیا حداقل یک آرگومان (SID) داده شده است یا خیر
if [[ $# -lt 1 ]]; then
echo "Usage: $0 [MODE: audit|remediate]"
exit 1
fi
ORACLE_SID=$1
MODE=${2:-audit} # اگر آرگومان دوم داده نشد، پیشفرض audit در نظر گرفته شود
echo "Target SID: $ORACLE_SID"
echo "Mode: $MODE"
case "$MODE" in
"audit")
echo "Running audit for $ORACLE_SID..."
;;
"remediate")
echo "Running remediation for $ORACLE_SID..."
;;
*)
echo "Invalid mode. Use 'audit' or 'remediate'."
exit 1
;;
esac
۴) ترکیب مفاهیم: اسکریپت هوشمند برای Hardening
بیایید همه اینها را با هم ترکیب کنیم. فرض کنید اسکریپتی میخواهیم بنویسیم که لیستی از سرویسها را بگیرد و بر اساس یک فلگ (Flag)، آنها را بررسی یا اصلاح کند.
#!/bin/bash
# لیست سرویسهای حساس سیستمعامل
SERVICES=("sshd" "auditd" "crond")
# گرفتن آرگومانها
ACTION=$1 # audit یا fix
TARGET_SERVICE=$2 # نام یک سرویس خاص یا "all"
if [[ -z "$ACTION" ]]; then
echo "Error: Action (audit|fix) is required."
exit 1
fi
for svc in "${SERVICES[@]}"; do
# اگر کاربر سرویس خاصی را انتخاب کرده باشد، بقیه را رد کن
if [[ "$TARGET_SERVICE" != "all" && "$TARGET_SERVICE" != "$svc" ]]; then
continue
fi
case "$ACTION" in
"audit")
echo "[AUDIT] Checking service: $svc"
systemctl is-active --quiet "$svc" || echo " -> ALERT: $svc is NOT running!"
;;
"fix")
echo "[FIX] Attempting to start $svc..."
sudo systemctl start "$svc"
;;
*)
echo "Invalid action."
exit 1
;;
esac
done
۵) نکات امنیتی برای DBAها
- Validation: همیشه آرگومانهای ورودی را با
[[ ... ]]یاcaseاعتبارسنجی کنید تا از تزریق دستورات (Command Injection) جلوگیری شود. - Default Values: از قابلیت
${VAR:-default}استفاده کنید تا اگر کاربر مقداری وارد نکرد، اسکریپت با حالت امن (Safe Mode) ادامه یابد. - Array Quoting: همیشه هنگام استفاده از آرایهها در حلقهها، آنها را داخل کوتیشن قرار دهید:
"${ARRAY[@]}". این کار از بروز خطا در مواردی که عناصر آرایه حاوی فاصله (Space) هستند، جلوگیری میکند.
جمعبندی
در این قسمت آموختیم که چگونه با استفاده از آرایهها لیستهای پیچیده را مدیریت کنیم، با case تصمیمگیریهای منطقی و تمیز انجام دهیم و با استفاده از آرگومانهای خط فرمان، اسکریپتهای خود را منعطف و قابل استفاده در محیطهای مختلف کنیم. این مهارتها پایه و اساس نوشتن اسکریپتهای خودکار برای Audit و Remediation در محیطهای Oracle هستند.
مقاله قبلی:
Bash for Oracle DBAs — Part 9: Pattern Matching, grep, sed, and awk
مقاله بعدی:
Bash for Oracle DBAs — Part 11: Functions and Error Handling