Bash for Oracle DBAs Part 9: Pattern Matching, grep, sed, and awk

Bash for Oracle DBAs — قسمت ۹: Pattern Matching، grep، sed و awk

اسکریپت‌های Oracle DBA و اسکریپت‌های Hardening سیستم‌عامل به‌ندرت تنها با مقادیر ثابت کار می‌کنند. در محیط‌های عملیاتی، یک اسکریپت اغلب نیاز دارد تا پروسس‌های Oracle را شناسایی کند، در فایل‌های پارامتر جستجو انجام دهد، دستورالعمل‌های SSH را اعتبارسنجی کند، وضعیت دیتابیس را از خروجی دستورات استخراج کند یا با امنیت کامل یک فایل پیکربندی را تغییر دهد.

چهار ابزار و مفهوم مهم برای انجام این وظایف به ما کمک می‌کنند:

  • Bash pattern matching برای مقایسه‌های ساده با Wildcard؛
  • grep برای جستجوی متن با استفاده از عبارات منظم (Regular Expressions)؛
  • sed برای ویرایش جریان (Stream Editing) و جایگزینی کنترل‌شده متن؛
  • awk برای پردازش ستونی و تولید گزارش.

این ابزارها در اسکریپت‌های Audit و Remediation به‌شدت استفاده می‌شوند. درک آن‌ها به یک Oracle DBA کمک می‌کند تا اسکریپت‌های عملیاتی را بخواند، اعتبارسنجی کند، عیب‌یابی نماید و به‌صورت ایمن گسترش دهد.

۱) تفاوت Wildcard در Bash و عبارات منظم (Regular Expressions)

یک سردرگمی رایج، تفاوت بین الگوی Wildcard و عبارات منظم است. این دو یکی نیستند:

  • الگوهای Wildcard معمولاً توسط Bash استفاده می‌شوند، به‌ویژه درون [[ ... ]].
  • عبارات منظم (Regex) توسط ابزارهایی مانند grep، sed و awk استفاده می‌شوند.

کاراکترهای Wildcard زیر در Bash بسیار کاربردی هستند:

  • * — صفر یا چند کاراکتر؛
  • ? — دقیقاً یک کاراکتر؛
  • [abc] — یکی از کاراکترهای موجود در لیست؛
  • [0-9] — یک کاراکتر از یک محدوده عددی.

۲) تطبیق الگو (Pattern Matching) با [[ ... ]]

Bash می‌تواند یک متغیر را با استفاده از عملگر == درون [[ ... ]] با یک الگوی ساده مقایسه کند.

CURRENT_POLICY="DEFAULT:NO-SHA1:CIS-SSH"

if [[ "$CURRENT_POLICY" == *"CIS-SSH"* ]]; then
  echo "CIS SSH crypto policy module is enabled."
else
  echo "CIS SSH crypto policy module is not enabled."
fi

در این مثال، الگوی *"CIS-SSH"* به این معناست: مقدار متغیر می‌تواند هر کاراکتری قبل و بعد از عبارت CIS-SSH داشته باشد.

این یک الگوی رایج در اسکریپت‌های Hardening برای اعتبارسنجی خروجی دستوراتی مانند زیر است:

CURRENT_POLICY=$(update-crypto-policies --show 2>/dev/null)

یک DBA می‌تواند از همین رویکرد هنگام بررسی نام سرویس‌ها، مسیرهای Oracle Home، نقش‌های دیتابیس یا خروجی Listener استفاده کند.

DATABASE_ROLE=$(sqlplus -s / as sysdba <

۳) اهمیت کوتیشن‌ها (Quoting) در الگوهای Bash

هنگام استفاده از الگوی Wildcard، متغیر را در کوتیشن قرار دهید اما کل عبارت Wildcard را کوتیشن‌گذاری نکنید.

VALUE="Oracle Database 19c"

# صحیح: VALUE در کوتیشن است؛ Wildcard فعال می‌ماند.
if [[ "$VALUE" == *"19c"* ]]; then
  echo "Oracle 19c detected."
fi

حالت زیر عمل تطبیق الگو (Wildcard Matching) را انجام نمی‌دهد، زیرا کل الگو در کوتیشن قرار گرفته است:

if [[ "$VALUE" == "*19c*" ]]; then
  echo "This checks for the literal text *19c*."
fi

۴) استفاده از grep برای جستجوی متن

grep خطوطی از متن را جستجو می‌کند که با یک الگو مطابقت دارند. این یکی از مهم‌ترین ابزارهای لینوکس برای DBAها است، زیرا فایل‌های پیکربندی Oracle و سیستم‌عامل مبتنی بر متن هستند.

برای مثال، جستجوی Oracle SID در فایل /etc/oratab:

grep '^ORCL:' /etc/oratab

کاراکتر ^ به معنی «ابتدای خط» است. بنابراین، این دستور خطوطی را پیدا می‌کند که با ORCL: شروع می‌شوند.

۵) گزینه‌های مهم grep

  •  
  • -i — نادیده گرفتن بزرگی/کوچکی حروف؛
  •  
  • -v — نمایش خطوطی که مطابقت ندارند (معکوس)؛
  •  
  • -E — استفاده از عبارات منظم توسعه‌یافته (Extended Regex)؛
  •  
  • -h — حذف نام فایل در خروجی؛
  •  
  • -n — نمایش شماره خط؛
  •  
  • -q — حالت ساکت (Quiet)؛ فقط از Exit Status استفاده کنید.
  •  

برای یافتن ورودی‌های غیرکامنت و غیرخالی در /etc/oratab:

grep -Ev '^\s*($|#)' /etc/oratab

۶) عبارات منظم توسعه‌یافته با grep -E

اسکریپت‌های Hardening اغلب نیاز دارند چندین دستورالعمل (Directive) را در یک فایل پیکربندی جستجو کنند. عبارات منظم توسعه‌یافته این کار را شفاف‌تر می‌کنند.

grep -h -E -i '^\s*(Ciphers|MACs|KexAlgorithms|HostKeyAlgorithms|PubkeyAcceptedKeyTypes)\b' \
  /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf 2>/dev/null

این دستور دستورالعمل‌های مرتبط با رمزنگاری SSH را فارغ از بزرگی یا کوچکی حروف جستجو می‌کند. این عبارت از موارد زیر استفاده می‌کند:

  •  
  • | درون عبارت برای «یا»؛
  •  
  • (...) برای گروه‌بندی گزینه‌ها؛
  •  
  • ^\s* برای مجاز دانستن فضاهای خالی ابتدای خط؛
  •  
  • \b برای مشخص کردن مرز کلمه.
  •  

۷) استفاده از grep -q در شرط‌ها

وقتی اسکریپت فقط نیاز دارد بداند آیا یک الگو وجود دارد یا خیر، از حالت quiet استفاده کنید. این دستور خروجی تولید نمی‌کند؛ شرط فقط از Exit Status آن استفاده می‌کند.

if grep -qE '^[[:space:]]*compatible[[:space:]]*=' "$ORACLE_HOME/network/admin/sqlnet.ora"; then
  echo "The compatible directive exists."
else
  echo "The compatible directive was not found."
fi

۸) استفاده از sed برای جایگزینی ایمن متن

sed یک ویرایشگر جریان است. متن را خط‌به‌خط می‌خواند و می‌تواند محتوای منطبق را چاپ، حذف یا جایگزین کند.

سینتکس پایه جایگزینی به شکل زیر است:

sed 's/pattern/replacement/' input_file

مثال: نمایش پورت Listener مورد انتظار پس از جایگزینی 1521 با 1522:

sed 's/1521/1522/g' "$ORACLE_HOME/network/admin/listener.ora"

۹) کامنت کردن دستورالعمل‌های قدیمی پیکربندی

یک عملیات معمول در Remediation، غیرفعال کردن یک خط پیکربندی قدیمی به جای حذف فوری آن است. این کار تاریخچه‌ای قابل مشاهده در فایل باقی می‌گذارد و ریسک از دست رفتن اطلاعات را کاهش می‌دهد.

sed -i.bak -E \
  's/^[[:space:]]*(Ciphers|MACs|KexAlgorithms)[[:space:]]+/# &/' \
  /etc/ssh/sshd_config

نکات مهم:

  •  
  • -i.bak فایل را تغییر می‌دهد و یک نسخه پشتیبان با پسوند .bak می‌سازد؛
  •  
  • -E عبارات منظم توسعه‌یافته را فعال می‌کند؛
  •  
  • ^ تضمین می‌کند فقط خطوطی که با دستورالعمل شروع می‌شوند مطابقت داده شوند؛
  •  
  • & نشان‌دهنده کل متن منطبق شده است؛
  •  
  • جایگزین # & یک کاراکتر کامنت قبل از خط اصلی اضافه می‌کند.
  •  

۱۰) استفاده از awk برای پردازش ستونی

awk به‌ویژه زمانی مفید است که خروجی دستور دارای ستون باشد. به‌طور خودکار هر خط ورودی را به فیلدها تقسیم می‌کند:

  •  
  • $1 — فیلد اول؛
  •  
  • $2 — فیلد دوم؛
  •  
  • $0 — کل خط جاری؛
  •  
  • NF — تعداد فیلدها در خط جاری؛
  •  
  • NR — شماره خط ورودی جاری.
  •  

یک وظیفه رایج DBA، گزارش سیستم‌های فایلی با مصرف دیسک بالاست:

df -P -h | awk 'NR > 1 && $5+0 > 80 { print $1, $5, $6 }'

۱۱) استخراج اطلاعات Oracle با awk

فایل /etc/oratab از فیلدهای جدا شده با کولون (:) استفاده می‌کند. با -F: جداکننده فیلد را کولون مشخص می‌کنیم.

awk -F: '$1 == "ORCL" { print $2 }' /etc/oratab

این دستور Oracle Home مرتبط با SID دیتابیس ORCL را چاپ می‌کند.

۱۲) یک تابع عملیاتی برای Audit فضای دیسک

check_disk_usage() {
  local threshold="${1:-80}"

  df -P -h | awk -v limit="$threshold" '
    NR > 1 && $5+0 > limit {
      printf "WARN: %s is %s used (%s)\n", $6, $5, $1
    }
  '
}

check_disk_usage 85

۱۳) ترکیب grep، sed و awk

این ابزارها اغلب در یک Pipeline با هم ترکیب می‌شوند. برای کاهش پردازش‌های اضافی، تا حد امکان سعی کنید از قابلیت‌های awk به تنهایی استفاده کنید:

awk -F: '
  $0 !~ /^[[:space:]]*#/ &&
  NF >= 3 &&
  $3 == "Y" {
    print "SID=" $1 ", ORACLE_HOME=" $2
  }
' /etc/oratab

۱۴) دستورالعمل‌های ایمنی برای اسکریپت‌های DBA و Remediation

  •  
  • متغیرهای شل را کوتیشن‌گذاری کنید: "$FILE"، "$ORACLE_HOME" و "$ORACLE_SID".
  •  
  • زمانی که فقط وجود یک تطابق مهم است از grep -q استفاده کنید.
  •  
  • قبل از استفاده از sed -i، حتماً Backup بگیرید.
  •  
  • پیش از Restart کردن سرویس‌های حساس (SSH، Listener، Clusterware)، پیکربندی را اعتبارسنجی کنید (مثلاً با sshd -t).
  •  

۱۵) جمع‌بندی

ابزارهای پردازش متن برای اتوماسیون با Bash ضروری هستند:

  •  
  • از تطبیق الگوی Bash برای مقایسه‌های ساده متغیر استفاده کنید.
  •  
  • از grep برای جستجوی خطوط منطبق با عبارات منظم استفاده کنید.
  •  
  • از sed برای تغییر متن یا اصلاح فایل‌های پیکربندی با دقت بالا استفاده کنید.
  •  
  • از awk برای گزارش‌های ساختاریافته و محاسبات ستونی استفاده کنید.
  •  

مقاله قبلی:
Bash for Oracle DBAs — Part 8: Redirection, Pipes, and Streams in Bash

مقاله بعدی:
Bash for Oracle DBAs — Part 10: Arrays, case, and Script Arguments in Bash