[code]سلام
خب لازم شد که فنی تر ! کد رو بررسی کنیم
قسمت اول
[code]echo پسورد کاربری خود را وارد کنید |fribidi
read -s pass
echo اجرا شدم |fribidi
این قسمت که خب کار خاصی انجام نمی ده فقط یک متن فارسی رو چاپ می کنه (چون خط فرمان قابلیت نمایش صحیح حروف فارسی رو نداره این خروجی رو با fribidi انجام می دهند) بعد پسورد رو از کاربر می گیره ودر متغیر pass ذخیره می کنه (-s باعثت می شه که چیزی رو که کاربر تایپ می کنه روی صفحه نمایش نشان داده نشه-بنا به دلایل امنیتی)
قسمت دوم
ps -u `whoami` |grep -i $1 >/dev/null
if [ $? != '0' ]
then
echo no programme running!...
exit
fi
خب این قسمت برای اینکه از خاموش شدن بی مورد جلوگیری کنه
ببینید به نظرتون این قسمت :
ps -u `whoami` |grep -i $1 >/dev/null
مشکل نداره. من این خط رو اجرا میکنم error میده. ببینید شما چیزی رو به فرمان grep ندادید و بعد خواستید که standard output رو بریزید تو null.
کلا شما این طور عمل کردید که ببینید آیا برنامه ای واسه این کاربر باز هست یا نه ، اگر باز بود دوباره بررسی میکنه و زمانی که همه پروسس ها بسته شدن، سیستم رو خاموش میکن
اینکه شما خطا در یافت می کنید به احتمال زیاد مربوط به این می شه که این کد رو خارج از اسکریپت اجرا کردید چیزی رو که ما به grep می دیم همون چیزیه که کاربر به ما می ده ! به متغیر $1 در فرمان توجه کنید
اما توضیحش :
ps یک نرم افزاری که پروسس ها رو نشون می ده
whoamiنرم افزاریه که می گه شما (اجرا کننده )نام کاربریش چیه
``
زوج علامت بالا به این معنیه که هر چیزی که بینشان باشه اجرا می شه و خروجیشون بجای این زوج علامت و عبارت درونشون قرار می گیره
ps -u `whoami`
خب این می یاد تمام برنامه هایی رو که کاربری رو که اجراش کرده رو لیست می کنه
ps -u `whoami |grep -i $1 >/dev/null
این خط می یاد تمام برنامه رو می فرسته (با | ) به grep -i grep هم دنبال می گرده ببینه که همچین عبارتی توی لیست برنامه ها هست یا نه که خب اگر باشه به طور پیش فرض چاپش می کنه ولی چون صفحه شلوغ می شد فرستادمش به نا کجا آباد !(/dev/null ) اگر که همچین چیزی وجود داشت متغیر ? (این متغیر خروجی رو که برنامه به صدا زنندش می فرسته توی c همون return ; هست )برابر صفر می شه و اگر که این عبارت نبود یا مشکلی پیش اومد (خیلی کم پیش می یاد که مشکلی رخ بدهد -یعنی من که تا حالا زیاد ندیدم) مخالف صفر میشه که بستگی به این چه حالتی باشه فرق می کنه
اما اون ساختار شرطی بررسی می کنه که ببینه آیا متغیر ? صفر هست یا نه ؟ (چون بلافاصله بعد از خط بالا قرار داره می شه مطمئن شد که وضعیت grep رو مشخص می کنه - چون بعد از اجرای هر دستور مقدارش تغییر می کنه) اگر که مخالف صفر بود یعنی این برنامه وجود نداره یا اینکه اشکالی وجود داره!که در این صورت از اسکریپت خارج می شه
قسمت سوم:
exe=0
while [ $exe != '1' ]
do
ps -u `whoami` |grep $1 >/dev/null
exe=$?
sleep 2
done
خط اول می یاد متغیر exeرو برابر صفر قرار می ده بعد میره توی حلقه ی while توی این حلقه ابتدا دستور قسمت دوم اجرا می شه بعد چون یک برنامه ی دیگه هم هست و مقدار $? تغییر می کنه اومدم مقدار exe رو برابر ? قرار دادم و مبنای مقایسه رو هم برپایه ی exe گذاشتم بعد از خط بالا ۲ثانیه صبر می کنه چون هم از میزان پردازش حلقه کم بشه و هم اینکه اگر داشت اسکریپتی رو مانیتور می کرد فرصت کافی برای رفتن به خط بعد باشه وهم اینکه سریع خاموش نشه ! و فرصت کنسل هم داشته باشه بعد از این دوثانیه دو باره حلقه از اول چک می شه
قسمت آخر t
[/code]echo $pass |sudo -S halt[/code]
حال اگر که grep چیزی پیدا نکرد یا مشکلی پیش اومد از حلقه خارج می شه و کامپیوتر رو خاموش می کنه
منظورتون این بوده که تا زمانی که فرمان ps ... درست اجرا شده، و پروسه ای درحال اجرا هست، این حلقه ادامه پیدا کنه. درسته.
حالا بعضی وقت ها که یه دستور ناموفق میشه همیشه خروجیش ۱ نمیشه و ممکنه ۲ هم بشه. به نظر من بهتره که بنویسید:
بله با صفر بهتره ولی نمی دونم چرا این مدلی نوشتم (این کد مال چند ماه پیشه)یعنی تغیییرش دادم به مخالف با یک ولی الان که فکر می کنم می بینم خیلی بهتره که با صفر مقایسه بشه ممنون
ر ضمن به نظر من واسه این کاری که شما گفتید، این طور مناسب نیستش که ببینیم همه پروسه های کاربر جاری تموم شده و بعد سیستم رو خاموش کنیم. شاید یه پروسس ای رو یه کاربر اجرا کرده که تا ابد تموم نمیشه. به نظر من این طور بهتر بود که نام برنامه از کاربر گرفته بشه، بعد ما بریم pid رو پیدا کنیم و بعد رو این pid مانور بدیم.
احتمالا یک جاییش رو متوجه نشدید قرار نیست که این صبر کنه تا همه ی برنامه تموم بشن (خیلی از برنامه ها هستند که تا زمانی که سیستم خاموش نشده در حال اجرا هستند )بلکه برای اپن برنامه ای رو که ما می دیم صبر می کنه اما ایده ی pid ایده ی خوبیه چون با استفاده از نام برنامه ها ممکنه که تداخل بوجود بیاد مثلا dd با thdd (هر چند که توی برنامه های با اسم بزرگتر کمتر پیش می یاد )ولی pid این مشکل رو نداره در عوض pid این مشکل رو داره (به همبن خاطر من اسم رو به pid ترجیح دادم-هر کسی با کامپیوترش یک جوری کار می کنه) که توی اسکریپتهایی که توی خط فرمان نوشته میشه ویک برنامه چندین بار اجرا می شه و به اتمام می رسه pid فرق می کنه و با عث که یا یک بار اجرا خاموش بشه و به دفعات بعدی نرسه برای pid هم این خط رو به اول اضافه کنید
pid=`pidof $1`
وخطوط شامل
ps -u `whoami`|grep -i $1 >/dev/null
به ابن خط تبدیل کنید
ps -u `whoami` |awk '{print $1}' |grep $pid >/dev/null