وقتی آخرین بار اسکریپتمان را ترک کردیم، چیزی مانند این بود:
#!/bin/bash # sysinfo_page - اطلاعات سیستم HTML اسکریپتی برای تولید یک فایل ##### ثابتها TITLE="System Information for $HOSTNAME" RIGHT_NOW=$(date +"%x %r %Z") TIME_STAMP="Updated on $RIGHT_NOW by $USER" ##### توابع system_info() { echo "<h2>System release info</h2>" echo "<p>Function not yet implemented</p>" } # system_info پایان تابع show_uptime() { echo "<h2>System uptime</h2>" echo "<pre>" uptime echo "</pre>" } # show_uptime پایان تابع drive_space() { echo "<h2>Filesystem space</h2>" echo "<pre>" df echo "</pre>" } # drive_space پایان تابع home_space() { # فقط کاربر ارشد میتواند این اطلاعات را به دست بیاورد if [ "$(id -u)" = "0" ]; then echo "<h2>Home directory space by user</h2>" echo "<pre>" echo "Bytes Directory" du -s /home/* | sort -nr echo "</pre>" fi } # home_space پایان تابع ##### Main cat <<- _EOF_ <html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> $(system_info) $(show_uptime) $(drive_space) $(home_space) </body> </html> _EOF_
موارد بسیاری آماده به کار داریم، اما چند ویژگی دیگر نیز هست که من میخواهم اضافه کنم:
تمام این ویژگیها، با کاربرد گزینههای فرمان و شناسهها ارتباط دارند. برای مدیریت گزینههای سطر فرمان، ما یک وسیله پوسته به نام
بیایید سطر فرمان زیر را فرض کنیم:
[me@linuxbox me]$ some_program word1 word2 word3
اگر some_program یک اسکریپت پوسته بود، ما میتوانستیم هر یک از اقلام سطر فرمان را بخوانیم زیرا پارامترهای مکانی محتوی این موارد میگردیدند:
این هم یک اسکریپت که شما میتوانید این مورد را آزمایش کنید:
#!/bin/bash echo "Positional Parameters" echo '$0 = ' $0 echo '$1 = ' $1 echo '$2 = ' $2 echo '$3 = ' $3
بیشتر اوقات، شما نیاز خواهید داشت وجود شناسهها را برای عمل کردن بر آنها بررسی کنید. چند روش برای انجام این کار وجود دارد. نخست، به سادگی میتوانید بررسی کنید که آیا
#!/bin/bash if [ "$1" != "" ]; then echo "Positional parameter 1 contains something" else echo "Positional parameter 1 is empty" fi
دوم، پوسته متغیری به نام
#!/bin/bash if [ $# -gt 0 ]; then echo "Your command line contains $# arguments" else echo "Your command line contains no arguments" fi
همانطور که قبلاً گفتیم، بسیاری از برنامهها مخصوصاً برنامههای پروژه گنو، از هر دو نوع گزینه خط فرمان کوتاه و بلند پشتیبانی میکنند. برای مثال، جهت نمایش یک پیغام راهنما برای بسیاری از این برنامهها، شما میتوانید یا از گزینه "
این هم کدی که برای پردازش سطر فرمانمان استفاده خواهیم نمود:
interactive= filename=~/sysinfo_page.html while [ "$1" != "" ]; do case $1 in -f | --file ) shift filename=$1 ;; -i | --interactive ) interactive=1 ;; -h | --help ) usage exit ;; * ) usage exit 1 esac shift done
این کد کمی ماهرانه است، بنابراین هنگامی که من تلاش میکنم آن را تشریح نمایم بردباری کنید.
دو سطر نخست نسبتاً ساده هستند. ما متغیر interactive را طوری تنظیم کردهایم که تهی باشد. این بیانگر آن است که وضعیت محاورهای در خواست نگردیده است. سپس متغیر filename را برای در بر داشتن نام فایل پیشفرض تنظیم کردیم. اگر نام دیگری در سطر فرمان تعیین نشود، این نام فایل به کار خواهد رفت.
پس از اینکه دو متغیر تنظیم شدند، در صورتیکه کاربر هیچ گزینهای به کار نبرد، ما تنظیمات پیشفرض را در اختیار داریم.
بعد، یک حلقه while میسازیم که در میان تمام اقلام سطر فرمان گردش میکنیم و هر یک را با case پردازش میکنیم. فرمان case هر گزینه ممکن را یافته و به طور مناسب پردازش خواهد نمود.
اکنون بخش ماهرانه. آن حلقه چگونه کار میکند؟ به جادوی shift استناد میکند.
shift یک فرمان داخلی است که روی پارامترهای مکانی عمل میکند. هر نوبت که شما فرمان shift را احضار میکنید، تمام پارامترهای مکانی را یکی به پایین جابه جا میکند.
#!/bin/bash echo "You start with $# positional parameters" # حلقه تا موقعی که تمام پارامترها مصرف شده باشند while [ "$1" != "" ]; do echo "Parameter 1 equals $1" echo "You now have $# positional parameters" # جا به جایی تمام پارامترها یکی به طرف پایین shift done
گزینه "
ما باید یک تابع نحوه استفاده اضافه کنیم و چند مورد را جابه جا کنیم تا این روال جدید را به صورت به هم پیوسته در اسکریپتمان داشته باشیم. همچنین مقداری کد تست برای بازبینی آنکه پردازشگر سطر فرمان به طور صحیح کار میکند اضافه خواهیم نمود. اکنون اسکریپت ما مانند این به نطر میآید:
#!/bin/bash # sysinfo_page - اطلاعات سیستم HTML اسکریپتی برای تولید یک فایل ##### ثابتها TITLE="System Information for $HOSTNAME" RIGHT_NOW=$(date +"%x %r %Z") TIME_STAMP="Updated on $RIGHT_NOW by $USER" ##### توابع system_info() { echo "<h2>System release info</h2>" echo "<p>Function not yet implemented</p>" } # system_info پایان تابع show_uptime() { echo "<h2>System uptime</h2>" echo "<pre>" uptime echo "</pre>" } # show_uptime پایان تابع drive_space() { echo "<h2>Filesystem space</h2>" echo "<pre>" df echo "</pre>" } # drive_space پایان تابع home_space() { # فقط کاربر ارشد میتواند این اطلاعات را به دست بیاورد if [ "$(id -u)" = "0" ]; then echo "<h2>Home directory space by user</h2>" echo "<pre>" echo "Bytes Directory" du -s /home/* | sort -nr echo "</pre>" fi } # home_space پایان تابع write_page() { cat <<- _EOF_ <html> <head> <title>$TITLE</title> </head> <body> <h1>$TITLE</h1> <p>$TIME_STAMP</p> $(system_info) $(show_uptime) $(drive_space) $(home_space) </body> </html> _EOF_ } usage() { echo "usage: sysinfo_page [[[-f file ] [-i]] | [-h]]" } ##### Main interactive= filename=~/sysinfo_page.html while [ "$1" != "" ]; do case $1 in -f | --file ) shift filename=$1 ;; -i | --interactive ) interactive=1 ;; -h | --help ) usage exit ;; * ) usage exit 1 esac shift done # کد تست برای بازبینی صحت پردازش سطر فرمان if [ "$interactive" = "1" ]; then echo "interactive is on" else echo "interactive is off" fi echo "output file = $filename" # نوشتن اسکریپت (به صورت توضیح نشانگذاری شده تا تست کردن کامل شود) # write_page > $filename
وضعیت محاورهای با کد پایین پیادهسازی میگردد:
if [ "$interactive" = "1" ]; then response= echo -n "Enter name of output file [$filename] > " read response if [ -n "$response" ]; then filename=$response fi if [ -f $filename ]; then echo -n "Output file exists. Overwrite? (y/n) > " read response if [ "$response" != "y" ]; then echo "Exiting program." exit 1 fi fi fi
ابتدا، بررسی میکنیم آیا وضعیت محاورهای فعال هست، در غیر اینصورت کاری برای انجام نداریم. بعد، نام فایل را از کاربر سوال میکنیم. روشی را که اعلان بیان میشود ملاحظه کنید:
echo -n "Enter name of output file [$filename] > "
ما مقدار فعلی filename را نمایش میدهیم، چون این قسمت طوری کدنویسی میشود که اگر کاربر فقط کلید اینتر را بزند، مقدار پیشفرض filename استفاده خواهد شد. این مطلب در دو سطر بعدی جایی که مقدار response بررسی میشود انجام گردیده است. اگر response تهی نباشد، آنوقت مقدار response به filename تخصیص داده میشود. در غیر اینصورت filename تغییر نیافته با حفظ کردن مقدار پیشفرض آن باقی گذاشته میشود.
پس از اینکه دارای نام فایل خروجی هستیم، بررسی میکنیم که آیا از قبل موجود است. اگر باشد، به کاربر اخطار میدهیم. اگر پاسخ کاربر "y" نباشد، منصرف شده و خارج میشویم، وگرنه میتوانیم پیش برویم.