فصل ۲۵ – شروع یک پروژه
در فصل گذشته نخستین شلاسکریپت خود را ساختیم و با اصولی مانند شبانگ، مجوز اجرا و استفاده از here document آشنا شدیم.
از اینجا به بعد میخواهیم یک پروژهٔ واقعی را گامبهگام توسعه دهیم تا مهارتهای تازهای که یاد میگیریم فوراً در عمل به کار گرفته شوند.
پروژهٔ ما اسکریپتی به نام sys_info_page است که گزارشی HTML از وضعیت سیستم تولید میکند.
این فصل روی آمادهسازی، جمعآوری نیازمندیها و ایجاد چهارچوب پروژه تمرکز دارد تا در فصلهای بعدی به تدریج قابلیتهای پیچیدهتر را اضافه کنیم.
تصویر کلی
در نسخهٔ اولیهٔ اسکریپت صفحهای ساده با اطلاعات عمومی (مانند زمان، نام سیستم و خروجی چند فرمان) تولید میکردیم.
اکنون میخواهیم نیازمندیها را دقیقتر مشخص کنیم:
- عنوان صفحه باید شامل نام میزبان و زمان تولید گزارش باشد.
- گزارشی خلاصه از وضعیت سیستم (معماری، نسخهٔ کرنل، تعداد پردازندهها) نمایش داده شود.
- زمان کارکرد (uptime) و میانگین بار سیستم در دسترس باشد.
- فهرستی از کاربران فعلی چاپ شود.
- فضای دیسک موجود در سیستم و وضعیت شاخهٔ خانگی کاربران بررسی شود.
- در پایان پیام مناسبی دربارهٔ محل ذخیرهشدن فایل نمایش داده شود.
پیش از نوشتن کد بهتر است بدانیم هر بخش گزارش از کدام فرمان یا داده به دست میآید.
جدول زیر چند فرمان کلیدی را یادآوری میکند:
| موضوع | فرمان پیشنهادی |
|---|---|
| معماری و نسخهٔ سیستم | uname -mp و uname -sr |
| زمان کارکرد | uptime |
| کاربران متصل | who |
| فضای دیسک | df -h |
| فضای شاخهٔ خانگی | du -sh /home/* (نیازمند دسترسی) |
ممکن است بخواهید فرمانهای دیگری مانند lscpu یا lsblk را نیز بیازمایید، اما برای سادگی فعلاً به همینها بسنده میکنیم.
سازماندهی فایلها
بهتر است پروژهٔ خود را در یک دایرکتوری اختصاصی نگهداریم.
اگر از قبل شاخهٔ ~/bin را ساختهاید، همانجا اسکریپت را قرار دهید؛ در غیر این صورت آن را ایجاد کنید:
[me@linuxbox ~]$ mkdir -p ~/bin
[me@linuxbox ~]$ cp sys_info_page ~/bin/
[me@linuxbox ~]$ chmod 755 ~/bin/sys_info_page
برای فایل خروجی نیز دایرکتوری معینی مانند /tmp یا ~/tmp انتخاب کنید تا نیاز به مجوز ریشه نباشد و فایلهای موقتی به هم ریخته نشوند.
در ادامه فرض میکنیم مسیر پیشفرض /tmp/system_info.html است.
نگارش نسخهٔ پایه
ابتدا نسخهای مینویسیم که تمام بخشهای اصلی را تولید میکند، گرچه ممکن است قالببندی نهایی هنوز کامل نباشد.
در ویرایشگر دلخواه (برای مثال nano) فایل sys_info_page را باز کنید و ساختار کلی زیر را جایگزین نسخهٔ قبلی کنید:
#!/bin/bash
# sys_info_page - تولید گزارش HTML از وضعیت سیستم
TITLE="گزارش وضعیت سیستم برای $HOSTNAME"
RIGHT_NOW=$(date +"%x %r %Z")
TIME_STAMP="گزارش تولید شده در $RIGHT_NOW توسط $USER"
REPORT_FILE=/tmp/system_info.html
cat << _EOF_ > "$REPORT_FILE"
<html>
<head>
<title>$TITLE</title>
</head>
<body>
<h1>$TITLE</h1>
<p>$TIME_STAMP</p>
<h2>اطلاعات کلی سیستم</h2>
<pre>$(uname -mp)</pre>
<pre>$(uname -sr)</pre>
<h2>زمان کارکرد سیستم</h2>
<pre>$(uptime)</pre>
<h2>کاربران حاضر</h2>
<pre>$(who)</pre>
<h2>فضای دیسک موجود</h2>
<pre>$(df -h)</pre>
<h2>وضعیت شاخهٔ خانگی</h2>
<pre>$(du -sh /home/* 2>/dev/null)</pre>
</body>
</html>
_EOF_
if [[ $? -eq 0 ]]; then
echo "گزارش در $REPORT_FILE ذخیره شد."
else
echo "خطا در ایجاد فایل گزارش." >&2
fi
این نسخه همان کاری را انجام میدهد که به دنبالش هستیم، اما چند نکتهٔ مهم را باید در نظر داشته باشیم:
- اجرای
du -sh /home/*ممکن است برای کاربران غیر ریشه پیامهای خطای مجوز ایجاد کند؛ برای جلوگیری از نمایش خطاها از2>/dev/nullاستفاده کردیم. - خروجی فرمانهایی مثل
dfوwhoطولانی است؛ در فصلهای بعدی بخشهایی را اضافه میکنیم که خروجی را مرتبتر نشان دهند یا تنها خطوط مهم را انتخاب کنند. - برای بررسی وضعیت اجرای
catاز مقدار بازگشتی ($?) استفاده کردیم. در فصل آینده راه بهتری معرفی میکنیم.
آزمودن اسکریپت
پس از ذخیرهٔ فایل، آن را اجرا کنید:
[me@linuxbox ~]$ ~/bin/sys_info_page
گزارش در /tmp/system_info.html ذخیره شد.
[me@linuxbox ~]$ xdg-open /tmp/system_info.html
اگر دستور xdg-open در سیستم شما موجود نیست، فایل را به صورت دستی با مرورگر دلخواه باز کنید.
حالا باید صفحهای ببینید که حاوی عنوان، مهر زمان و بخشهای مختلف گزارش است.
بررسی صحت خروجی
- آیا عنوان صفحه شامل نام میزبان است؟ اگر نه، مقدار
TITLEرا بررسی کنید. - آیا زمان و منطقهٔ زمانی صحیح نمایش داده میشود؟ قالببندی
dateرا تغییر دهید. - اگر بخش «وضعیت شاخهٔ خانگی» طولانی است، میتوانید به جای
*شاخههای خاص یا گزینهٔ--max-depthرا بهduبدهید.
مستندسازی اسکریپت
اکنون که نسخهٔ پایه آماده است، چند مورد مستندسازی را فراموش نکنید:
- در ابتدای فایل توضیح کوتاهی دربارهٔ هدف اسکریپت بنویسید.
- نسخه یا تاریخ آخرین تغییر را در نظر بگیرید:
VERSION="1.0"
- اگر اسکریپت از فرمانهای خارجی استفاده میکند، آنها را در بالای فایل فهرست کنید تا در صورت نبودن، به راحتی متوجه شوید چه وابستگیهایی دارید.
مسیر آینده
اسکریپت فعلی کار میکند اما میدانیم که میتوان بهترش کرد. برای مثال:
- بخشهای تکراری (مانند تولید عنوان و قالب HTML) را در توابع جداگانه قرار دهیم.
- امکان اجرای گزینشی بخشها را اضافه کنیم.
- با بررسی موفقیت هر فرمان خطاها را شفافتر گزارش دهیم.
در فصل بعدی سراغ روش «طراحی از بالا به پایین» میرویم تا اسکریپت را به قطعات منطقی تقسیم کنیم، از توابع استفاده کنیم و ساختار پروژه را انعطافپذیرتر سازیم.
تمرینها
- خروجی فرمان
hostnamectlرا در بخشی جداگانه به گزارش اضافه کنید. برای جلوگیری از طولانیشدن صفحه فقط خطوط مهم را نمایش دهید. - متغیری به نام
REPORT_DIRتعریف کنید و مسیر فایل گزارش را بر اساس آن بسازید. سپس با تغییر مقدار متغیر مطمئن شوید که فایل در مکان جدید ایجاد میشود. - گزینهای خط فرمان (
-f FILE) اضافه کنید که کاربر بتواند نام فایل خروجی را تعیین کند. هنوز لازم نیست اعتبارسنجی پیچیدهای انجام دهید؛ تنها بررسی کنید که آرگومان داده شده باشد.
مطالعهٔ بیشتر
- صفحهٔ راهنمای
man dateبرای آشنایی با الگوهای قالببندی زمان. - مستندات
who,w,lastبرای مشاهدهٔ انواع متفاوت گزارش کاربران. - مقالهٔ «Filesystem Hierarchy Standard» برای شناخت بهتر مسیرهای مناسب فایلهای موقتی.