در این پست از سری پست های دیباگ شل اسکریپت در لینوکس ما به بررسی و توضیح سومین mode دیباگ شل اسکریپت خواهیم پرداخت که shell tracing میباشد و به بررسی چندین مثال از نحوه کارکرد آن و همچنین شیوه های استفاده از آن میپردازیم.
بخش قبل از این سری مقالات درباره دو مد دیباگ اسکریپت : verbose mode و sysntax checking mode بحث کردیم و همچنین مثال های بسیار ساده و قابل درک درباره نحوه فعال سازی این دو مد نیز ارائه دادیم :
آموزش فعال کردن Debugging Mode در شل اسکریپت لینوکس (بخش اول)
آموزش فعال کردن مد دیباگ برای بررسی Syntax در شل اسکریپت
trace شل در حقیقت به معنای ساده یعنی trace کردن اجرای دستورات در یک shell script و برای سوئیج کردن به مد shell tracing باید از آپشن دیباگ -x استفاده کنید.
این گزینه در حقیقت شل را به سمت نمایش تمامی دستورات و argument های آنها روی ترمینال و در زمانیکه در حال اجرا شدن هستند، هدایت میکند.
ما از شل اسکریپت "sys_info.sh" که در زیر آمده استفاده خواهیم کرد که به طور مختصر date و time سیستم تعداد کاربران login و همچنین uptime سیستم را نمایش میدهد. به هر حال این اسکریپت دارای خطای syntax ی میباشد که ما نیاز داریم آنرا پیدا و رفع کنیم.
فایل را ذخیره و به اسکریپت permision اجرایی دهید. اسکریپت تنها در صورتی اجرا میشود که دسترسی root داشته باشید بنابراین از دستور sudo برای اجرا کردن آن همانند زیر استفاده کنید.
از خروجی بالا ما میتوانیم مشاهده کنیم که یک دستور ابتدا اجرا شده و سپس در خط بعد خروجی آن دستور به عنوان مقدار یک متغییر جایگزین میشود.
برای مثال date ابتدا اجرا شده و خروجی آن به عنوان مقدار متغییر DATE جایگزین میشود.
ما میتوانیم بررسی های syntax را به نحوی انجام دهیم که فقط error های syntax را همانند زیر نمایش دهد.
اگر شما به شل اسکریپت با دقت توجه کنید متوجه خواهید شد که "if statement" (که برای بستن کلمه "fi" استفاده میشود) در فایل کم است بنابراین آنرا به فایل اضافه میکنیم و اسکریپت جدید باید شبیه به نمونه زیر باشد.
فایل را ذخیره کنید و آنرا با پرمیژن root اجرا کنید تا syntax را مورد بررسی قرار دهیم.
نتیجه عملیات بررسی ساختار همچنان نمایش میدهد که یک باگ دیگر در اسکریپت ما و در خط 21 موجود است. در نتیجه ما همچنان نیاز به تصحیح ساختار داریم.
اگر بار دیگر اسکریپت را مورد آنالیز قرار دهیم متوجه خواهیم شد که خط 21 به دلیل کمبود یک دابل کوتیشن (") در آخرین دستور echo درون فانکشن "print_sys_info" میباشد.
در نتیجه ما دابل کوتیشن را در پایان دستور echo اضافه خواهیم کرد و فایل را ذخیره میکنیم. اسکریپت تغییر یافته باید شبیه به زیر باشد.
اکنون syntax را در اسکریپت یک بار دیگر بررسی میکنیم.
دستور بالا هیچ خروجی را نمیدهد زیرا در حال حاضر اسکریپت مان از لحاظ syntax ی کاملا درست است. در حال حاضر میتوانیم اجرای کامل اسکرپیت را برای یک لحظه trace کنیم و اسکریپت باید به درستی کار کند.
اکنون اسکریپت را اجرا میکنیم :
اهمیت اجرای tracing شل اسکریپت
trace کردن shell script به ما در تشخیص خطاهای syntax و مهم تر از آن error های logical (منطقی) کمک میکند. برای مثال از function (فانکشن) "check_root" در اسکریپت "sys_info.sh" استفاده میکنیم که برای تشخیص اینکه کاربری root هست یا نیست استفاده میشود و اجرای اسکریپت تنها برای سوپر یوزر مجاز است.
در اینجا کار اصلی توسط عبارت [ "$UID" -ne "$ROOT_ID" ] در "if statement" کنترل میشود زمانیکه ما از عملگر عددی مناسب استفاده نمیکنیم (در اینجا آپشن -ne به معنای "not equal" - نامساوی میباشد) یک logical error دریافت میکنیم.
فرض میکنیم که از آپشن -eq (به معنای مساوی با) استفاده کردیم که این آپشن به هر کاربر سیستمی و همچنین کاربر root اجازه اجرا کردن اسکریپت (حتی با وجود یک logical error) را میدهد.
نکته : اگر که به ابتدای این پست نگاه کنید گفتیم که دستور درونی shell به نام set میتواند دیباگ را در یک بخش خاصی از یک شل اسکریپت فعال کند.
بنابراین خط زیر به ما در یافتن این logical error در function و با استفاده از trace کردن اجرای اسکریپت کمک میکند.
اسکریپت به همراه یک logical error
فایل را ذخیره کنید و آنرا اجرا کنید همانطور که مشاهده میکنید یک کاربر معمولی سیستم نیز میتواند اسکریپت را بدون sudo همانطور که در زیر مشاهده میکنید اجرا کند. و علت آن به دلیل این است که مقدار USER_ID برابر با 100 است که با ROOT_ID که برابر با "0" است مساوی نیست :
این پست پایان سری پست های Debug شل اسکریپت بود. اگر درباره این موضوع سوال و یا پیشنهاد و یا هر گونه ترفند دیگری میشناسید باعث خوشحالیست که با ما در میان بگذارید.
بخش قبل از این سری مقالات درباره دو مد دیباگ اسکریپت : verbose mode و sysntax checking mode بحث کردیم و همچنین مثال های بسیار ساده و قابل درک درباره نحوه فعال سازی این دو مد نیز ارائه دادیم :
آموزش فعال کردن Debugging Mode در شل اسکریپت لینوکس (بخش اول)
آموزش فعال کردن مد دیباگ برای بررسی Syntax در شل اسکریپت
trace شل در حقیقت به معنای ساده یعنی trace کردن اجرای دستورات در یک shell script و برای سوئیج کردن به مد shell tracing باید از آپشن دیباگ -x استفاده کنید.
این گزینه در حقیقت شل را به سمت نمایش تمامی دستورات و argument های آنها روی ترمینال و در زمانیکه در حال اجرا شدن هستند، هدایت میکند.
ما از شل اسکریپت "sys_info.sh" که در زیر آمده استفاده خواهیم کرد که به طور مختصر date و time سیستم تعداد کاربران login و همچنین uptime سیستم را نمایش میدهد. به هر حال این اسکریپت دارای خطای syntax ی میباشد که ما نیاز داریم آنرا پیدا و رفع کنیم.
کد PHP:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
کد PHP:
$ chmod +x sys_info.sh
$ sudo bash -x sys_info.sh
از خروجی بالا ما میتوانیم مشاهده کنیم که یک دستور ابتدا اجرا شده و سپس در خط بعد خروجی آن دستور به عنوان مقدار یک متغییر جایگزین میشود.
برای مثال date ابتدا اجرا شده و خروجی آن به عنوان مقدار متغییر DATE جایگزین میشود.
ما میتوانیم بررسی های syntax را به نحوی انجام دهیم که فقط error های syntax را همانند زیر نمایش دهد.
کد PHP:
$ sudo bash -n sys_info.sh
اگر شما به شل اسکریپت با دقت توجه کنید متوجه خواهید شد که "if statement" (که برای بستن کلمه "fi" استفاده میشود) در فایل کم است بنابراین آنرا به فایل اضافه میکنیم و اسکریپت جدید باید شبیه به نمونه زیر باشد.
کد PHP:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME
}
check_root
print_sys_info
exit 0
کد PHP:
$ sudo bash -n sys_info.sh
نتیجه عملیات بررسی ساختار همچنان نمایش میدهد که یک باگ دیگر در اسکریپت ما و در خط 21 موجود است. در نتیجه ما همچنان نیاز به تصحیح ساختار داریم.
اگر بار دیگر اسکریپت را مورد آنالیز قرار دهیم متوجه خواهیم شد که خط 21 به دلیل کمبود یک دابل کوتیشن (") در آخرین دستور echo درون فانکشن "print_sys_info" میباشد.
در نتیجه ما دابل کوتیشن را در پایان دستور echo اضافه خواهیم کرد و فایل را ذخیره میکنیم. اسکریپت تغییر یافته باید شبیه به زیر باشد.
کد PHP:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
check_root
print_sys_info
exit 0
کد PHP:
$ sudo bash -n sys_info.sh
کد PHP:
$ sudo bash -x sys_info.sh
اکنون اسکریپت را اجرا میکنیم :
کد PHP:
$ sudo ./sys_info.sh
اهمیت اجرای tracing شل اسکریپت
trace کردن shell script به ما در تشخیص خطاهای syntax و مهم تر از آن error های logical (منطقی) کمک میکند. برای مثال از function (فانکشن) "check_root" در اسکریپت "sys_info.sh" استفاده میکنیم که برای تشخیص اینکه کاربری root هست یا نیست استفاده میشود و اجرای اسکریپت تنها برای سوپر یوزر مجاز است.
کد PHP:
check_root(){
if [ "$UID" -ne "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
فرض میکنیم که از آپشن -eq (به معنای مساوی با) استفاده کردیم که این آپشن به هر کاربر سیستمی و همچنین کاربر root اجازه اجرا کردن اسکریپت (حتی با وجود یک logical error) را میدهد.
کد PHP:
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
بنابراین خط زیر به ما در یافتن این logical error در function و با استفاده از trace کردن اجرای اسکریپت کمک میکند.
اسکریپت به همراه یک logical error
کد PHP:
#!/bin/bash
#script to print brief system info
ROOT_ID="0"
DATE=`date`
NO_USERS=`who | wc -l`
UPTIME=`uptime`
check_root(){
if [ "$UID" -eq "$ROOT_ID" ]; then
echo "You are not allowed to execute this program!"
exit 1;
fi
}
print_sys_info(){
echo "System Time : $DATE"
echo "Number of users: $NO_USERS"
echo "System Uptime : $UPTIME"
}
#turning on and off debugging of check_root function
set -x ; check_root; set +x ;
print_sys_info
exit 0
کد PHP:
$ ./sys_info.sh
این پست پایان سری پست های Debug شل اسکریپت بود. اگر درباره این موضوع سوال و یا پیشنهاد و یا هر گونه ترفند دیگری میشناسید باعث خوشحالیست که با ما در میان بگذارید.