Bash for Oracle DBAs قسمت اول شرط‌ ها در Bash if، test

دنیای مدیریت Oracle Database در عمل فقط به دستورات SQL و RMAN محدود نمی‌شود. یک DBA حرفه‌ای هر روز ناچار است با Oracle Linux, فایل‌های پیکربندی, permissionها, logها, و automation سر و کار داشته باشد.

ابزار اصلی ما برای این کارها Bash است.

این مجموعه با عنوان Bash for Oracle DBAs برای کمک به DBAهایی نوشته شده که می‌خواهند:

  • اسکریپت‌های آماده دیگران (مثل اسکریپت‌های hardening، health check، یا automation) را کاملاً بفهمند
  • خودشان بتوانند اسکریپت‌های سبک و کاربردی بسازند
  • درک درستی از شرط‌ها، حلقه‌ها، sed، awk، tr، و مفاهیم پایه داشته باشند
  • بدون نیاز به متخصص سیستم، اکثر کارهای روزمره Oracle/Linux را مدیریت کنند

این دوره قرار نیست جای دوره‌های تخصصی Bash یا Linux را بگیرد

هدف این سری آموزش Bash در حدی است که یک Oracle DBA بتواند کار خود را راه بیندازد و به شکل حرفه‌ای و بدون سردرگمی اسکریپت‌های واقعی را درک و اصلاح کند.

مواردی که در این دوره پوشش نمی‌دهیم:

این مجموعه وارد مباحث پیچیده زیر نخواهد شد:

  • نحوه کار داخلی shellها، subshellها و job control
  • scripting پیشرفته شامل associative arrays، process substitution و محاسبات چندفرایندی
  • آموزش کامل امنیت اسکریپت‌نویسی پیشرفته
  • مدیریت کامل systemd، SELinux یا شبکه در سطح enterprise
  • معماری و نحوه کار هسته Bash

تمرکز ما دقیقاً روی مواردی است که یک DBA به آن نیاز عملی دارد

یعنی:

  • شرط‌ها و تست‌های واقعی
  • پردازش متن از نوعی که در logها و configها دیده می‌شود
  • sed / awk / tr در کاربردهای واقعی
  • permission و ownership
  • ساخت پیکربندی با heredoc
  • حلقه‌ها و اجرای ماژول‌ها
  • ساخت اسکریپت‌های استاندارد و قابل نگهداری

با این مقدمه، به سراغ شروع این مقالات می رویم.:

یک Oracle DBA در عمل فقط با دیتابیس کار نمی‌کند.

قبل از اجرای backup، قبل از تغییر فایل‌های پیکربندی، قبل از اجرای اسکریپت‌های maintenance، باید مطمئن شود:

  • کاربر درست اجرا می‌کند؟
  • مسیر مورد نظر وجود دارد؟
  • فایل مورد نظر قابل اجراست؟
  • مقدار ورودی معتبر است؟

همه این‌ها با شرط‌ها در Bash انجام می‌شود.

در این مقاله یاد می‌گیریم:

  • ساختار if چگونه کار می‌کند
  • تفاوت [ ] و [[ ]] چیست
  • چگونه فایل، دایرکتوری و کاربر root را بررسی کنیم
  • چگونه شرط‌های ترکیبی بنویسیم
  • اشتباهات رایج در شرط‌نویسی Bash

هدف این مقاله:

شما بتوانید منطق تصمیم‌گیری در اسکریپت‌های مدیریتی Linux را بخوانید و خودتان پیاده‌سازی کنید.


1️⃣ ساختار پایه if در Bash

ساختار کلی:

if condition; then
  commands
fi

مثال ساده:

 

if [[ 5 -gt 3 ]]; then
  echo "5 is greater than 3"
fi

[ ] در Bash چیست؟

در بسیاری از اسکریپت‌های Bash شرط‌ها به این شکل نوشته می‌شوند:

if [ -f /etc/passwd ]; then
  echo "File exists"
fi

در نگاه اول ممکن است تصور شود [ ] بخشی از ساختار if است، اما در واقع این‌طور نیست.

در حقیقت:

[ ... ]

در Bash یک دستور (command) است.

این دستور در واقع همان دستور قدیمی test است.

بنابراین این دو کاملاً معادل هستند:

test -f /etc/passwd

و

[ -f /etc/passwd ]

در هر دو حالت، دستور بررسی می‌کند آیا فایل وجود دارد یا نه.

اگر شرط برقرار باشد، کد خروجی دستور 0 خواهد بود و if آن را true در نظر می‌گیرد.

2️⃣ بررسی اینکه اسکریپت با root اجرا شده یا نه

یکی از مهم‌ترین شرط‌ها در اسکریپت‌های DBA همین است.

در Linux، شناسه کاربر root برابر با 0 است.

متغیر $EUID شناسه کاربر فعلی را نگه می‌دارد.

مثال کاربردی:

if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root"
  exit 1
fi

توضیح:

  • -ne یعنی “not equal”
  • اگر کاربر root نباشد، اسکریپت متوقف می‌شود
  • exit 1 یعنی خروج با خطا

✅ این الگو را تقریباً در تمام اسکریپت‌های حرفه‌ای مدیریتی می‌بینید.


3️⃣ بررسی وجود دایرکتوری

فرض کنید می‌خواهیم قبل از گرفتن backup مطمئن شویم مسیر وجود دارد:

BACKUP_DIR="/u01/backups"

if [[ ! -d "$BACKUP_DIR" ]]; then
  echo "Backup directory does not exist"
  exit 1
fi

نکات مهم:

  • -d یعنی آیا دایرکتوری وجود دارد؟
  • ! یعنی نقیض
  • حتماً متغیر را داخل " " قرار دهید

❗ اگر کوتیشن نگذارید و مسیر شامل فاصله باشد، اسکریپت خراب می‌شود.


4️⃣ بررسی وجود فایل

CONFIG_FILE="/etc/oracle.conf"

if [[ -f "$CONFIG_FILE" ]]; then
  echo "Config file found"
fi

  • -f یعنی فایل معمولی وجود دارد

5️⃣ بررسی executable بودن فایل

مثلاً قبل از اجرای یک اسکریپت:

SCRIPT="/opt/scripts/check.sh"

if [[ -f "$SCRIPT" && -x "$SCRIPT" ]]; then
  echo "Script is executable"
else
  echo "Script is missing or not executable"
fi

اینجا چه اتفاقی می‌افتد؟

  • -f بررسی می‌کند فایل وجود دارد
  • -x بررسی می‌کند قابل اجراست
  • && یعنی هر دو شرط باید برقرار باشند

6️⃣ مقایسه عددی در Bash

عملگرهای عددی:

عملگر معنی
-eq مساوی
-ne نامساوی
-gt بزرگ‌تر
-lt کوچک‌تر
-ge بزرگ‌تر مساوی
-le کوچک‌تر مساوی

مثال:

COUNT=3

if [[ $COUNT -lt 5 ]]; then
  echo "Less than 5"
fi

7️⃣ مقایسه رشته‌ای

ENV="prod"

if [[ "$ENV" == "prod" ]]; then
  echo "Running in production mode"
fi

برای چند حالت:

if [[ "$ENV" == "prod" || "$ENV" == "dr" ]]; then
  echo "Critical environment"
fi

  • || یعنی OR
  • && یعنی AND

8️⃣ تفاوت [ ] و [[ ]]

✅ [[ ]] (توصیه‌شده برای Bash)

  • مدرن‌تر
  • امن‌تر
  • پشتیبانی از regex
  • خطاهای کمتر

✅ [ ]

  • قدیمی‌تر
  • سازگار با sh
  • محدودتر

مثال:

if [ -f "$file" ]; then
  echo "File exists"
fi

و معادل بهتر:

if [[ -f "$file" ]]; then
  echo "File exists"
fi

✅ در اسکریپت‌های جدید Bash بهتر است از [[ ]] استفاده شود.


9️⃣ استفاده از Regex در شرط‌ها

در Bash می‌توان از Regular Expression (یا به اختصار Regex) برای بررسی الگوهای متنی استفاده کرد.

Regex در واقع یک زبان کوچک برای توصیف الگوهای متن است.

به جای اینکه دقیقاً یک رشته مشخص را بررسی کنیم، می‌توانیم بگوییم:

  • آیا متن با یک الگوی خاص مطابقت دارد؟
  • آیا فقط شامل اعداد است؟
  • آیا با یک مقدار مشخص شروع یا تمام می‌شود؟

این قابلیت زمانی بسیار مفید است که بخواهیم ورودی کاربر، نام فایل‌ها، مقادیر configuration یا permissionها را بررسی کنیم.

در Bash، زمانی که از [[ ]] استفاده می‌کنیم، می‌توانیم از عملگر زیر برای بررسی regex استفاده کنیم:

=~

ساختار کلی:

if [[ STRING =~ REGEX ]]; then
    commands
fi

مثال:

MODE="755"

if [[ "$MODE" =~ ^(755|750)$ ]]; then
  echo "Mode is secure"
fi

یعنی:

  • فقط 755 یا 750 مجاز است
  • این برای بررسی permission فایل‌ها کاربرد زیادی دارد

بررسی دقیق Regex استفاده‌شده

الگوی ما این است:

^(755|750)$

هر بخش از این الگو معنی خاصی دارد.

^

نشان می‌دهد ابتدای رشته.

یعنی بررسی باید از اولین کاراکتر شروع شود.


(755|750)

این قسمت یعنی:

755 یا 750

در Regex:

A|B

یعنی A یا B

بنابراین:

(755|750)

یعنی رشته باید یکی از این دو مقدار باشد.


$

علامت $ یعنی انتهای رشته.


نتیجه کل الگو

^(755|750)$

یعنی:

رشته باید دقیقاً یکی از این دو مقدار باشد:

755
750

و هیچ چیز اضافی قبل یا بعد از آن وجود نداشته باشد.


چند مثال برای درک بهتر

مقدار نتیجه
755 ✅ معتبر
750 ✅ معتبر
700 ❌ رد می‌شود
7555 ❌ رد می‌شود
1755 ❌ رد می‌شود

چون الگو دقیقاً فقط دو مقدار را قبول می‌کند.


مثال کاربردی واقعی‌تر

فرض کنید اسکریپت شما قرار است permission یک فایل حساس را بررسی کند.

MODE=$(stat -c %a /etc/passwd)

if [[ "$MODE" =~ ^(644|640)$ ]]; then
  echo "Permission is acceptable"
else
  echo "Permission is not secure"
fi

در اینجا:

stat -c %a

permission فایل را به صورت عددی برمی‌گرداند (مثلاً 644).

سپس با regex بررسی می‌کنیم که مقدار قابل قبول است یا نه.


نکته مهم

Regex فقط در این حالت در Bash کار می‌کند:

[[ string =~ regex ]]

اگر از [ ] استفاده کنید، این قابلیت وجود ندارد.

بنابراین برای کار با regex در Bash باید از [[ ]] استفاده شود.

 


🔟 اشتباهات رایج

❌ بدون کوتیشن

if [[ $DIR == /tmp ]]; then

✅ درست:

if [[ "$DIR" == "/tmp" ]]; then

❌ استفاده اشتباه از =

در [ ] باید از = استفاده شود نه == در برخی shellها.


الگوی استاندارد مدیریت خطا

در اسکریپت‌های حرفه‌ای معمولاً این الگو را می‌بینیم:

if [[ ! -d "$DIR" ]]; then
  echo "Directory not found"
  exit 1
fi

این یعنی:

  1. بررسی شرط
  2. چاپ پیام واضح
  3. توقف اجرای اسکریپت

این سه مرحله ستون اصلی اسکریپت‌های production هستند.


تمرین عملی

یک اسکریپت بنویسید که:

  1. فقط توسط root اجرا شود
  2. بررسی کند /u01/app/oracle وجود دارد
  3. اگر وجود نداشت آن را ایجاد کند

راهنمایی:

mkdir -p /u01/app/oracle

جمع‌بندی

در این مقاله یاد گرفتیم:

  • ساختار if
  • تفاوت [ ] و [[ ]]
  • مقایسه عددی و رشته‌ای
  • بررسی فایل و دایرکتوری
  • ترکیب شرط‌ها با && و ||
  • استفاده از regex در شرط‌ها
  • الگوی استاندارد error handling

در مقاله بعد به سراع این بخش می رویم:

Bash for Oracle DBAs قسمت دوم بررسی فایل و دایرکتوری