انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


 خبرها، اتفاقات و تصاویر مربوط به مربوط به جشن انتشار را با هشتگ ufest1804 در شبکه‌های اجتماعی دنبال کنید

نویسنده موضوع: شروع برنامه نویسی در لینوکس  (دفعات بازدید: 88105 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین mimook

  • Full Member
  • *
  • ارسال: 102
  • جنسیت : پسر
    • mimook
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #30 : 10 شهریور 1388، 11:58 ب‌ظ »
لطفا یه نگاهی بکنید ببینید من درست میگم یانه!
چند مورد از کدها درست نیستن به این صورت که
while [ “$foo” -le 20 ]ایا درستش این نیست؟
while [ $foo -le 20 ]و این
case “$timeofday” inدرستش این نیست؟
case $timeofday inو این یکی هم
   [yY] | [Yy] [Ee] [Ss] )درستش اینه
   [yY] | [Yy][Ee][Ss] )بعد از امتحان کردن کدها دیدم درستشون ایناست که گفتم.

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #31 : 11 شهریور 1388، 11:09 ق‌ظ »
سلام میموک جان
در باره اشتباه آخری که ازم گرفتی باید بگم شما درست میگی و درستش به شکل زیره
   [yY]|[Yy][Ee][Ss] )
یعنی هیچ فاصله ای حتی بین | هم نداره

در باره بقیه اوامر شما باید عرض کنم که مشکل از اینه که شما کد ها رو کپی پیست کردید و به یه دلیلی که نمیدونم چیه فروم ما کاراکتر دابل کوتیشن رو به یه کاراکتر مشابه گویا تغییر میده!!!!!
اونی که شما در کد من میبینید دابل کتیشن نیست
اگه دستی با دبل کتیشن جایگزینشون کنید درست میشه و نیازی به پاک کردن اونها نیست!

لذا کد هایی که شما نوشتید همه (قبل و بعد از اصلاح) صحیحند و لی کدی که دابل کتیشن  داره بهتره و دلیلش هم اونه که در کد مشابه دو پست قبل مورد بررسی قرار داده بودیم و بدون دابل کتیشن ارور میداد.
خاطرتون هست؟
البته وجود دابل کتیشن در همه کد هایی که نوشتید از این اررور جلوگیری نمیکنه و شاید در بعضی موارد وجودش زاید باشه که از روی عادت برای همش میذارم تا یک وقت مشکلی از دستم در نره (که البته حجم رو الگی زیاد میکنه و خوب نیست)
اما غلط هم نیست. توجه به این موضوع که غلط نیست خیلی مهمه چون  در بعضی جاها وجود اون دابا کتیشن حتمی هستش و نمیشه حذفش کرد

به هر حال از توجه و مخصوصا اینکه غلط بنده رو گرفتید ممنون (در پست اصلی تصحیحش کردم)
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین mimook

  • Full Member
  • *
  • ارسال: 102
  • جنسیت : پسر
    • mimook
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #32 : 11 شهریور 1388، 01:44 ب‌ظ »
 :)خیلی خوشحالم و ممنونم از پیگیری.
بله مشکل من بخاطر کپی و پیست کردن کدها بود :P و بعد از نوشتن دستی دابل کوتیشن کد بدون ایراد اجرا شد.
به هر حال خیلی کارت درسته! (چون هم اسم خودمی سید محمود)
موفق باشی

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #33 : 11 شهریور 1388، 05:31 ب‌ظ »
سلام مجدد و تشکر فراوان از میموک جان عزیز برای پستشون
(میموک جان ما کوچیکتیم. وظیفه بود عزیز)

قبل از اینکه در باره برنامه نویسی با هم صحبت کنیم یک سوا از شما میپرسم (سوال منطقی) که البته جوابش رو در پست قبل دادم
فرض کنید که با یک عبارت منطقی روبرو هستید. در این صورت اگر این عبارت از چندین عبارت ساده تشکیل شده باشه که بین جملات اون حرف (و) قرار داشته باشه و اولین عبارت اشتباه باشه شما چیکار میکنید
به عنوان مثال فذص کنید الان هوا آفتابیه. آیا برای تشخیص صحت جمله زیر مطالعه کل اون لازمه؟
<< اگر هوا بارانی باشه و ..... من به خانه می روم >>
جمله فوق بدون درنظر گرفتن بقیه اون یعنی (...) غلط هستش و ارزش منطقی برابر False داره چون طبق فرض ما هوا بارانی نیست پس نیازی به مطالعه و بررسی ادامه جمله نیست
در باره جمله زیر چطور در صورتی که هوا آفتابی باشه
<<اگر هوا آفتابی باشه یا ..... من به دیدار شما خواهم آمد>>
این جمله به هرحال درسته چون با عبارت منطقی (یا) جملات از هم جدا شدند و جمله اول درسته و نیازی به چک کردن بقیه جمله نیست
به صورت خلاصه اگر T برابر ارزش منطقی جملات یا عبارات صحیح و F برابر ارزش منطقی جملات یا عبارات منطقی غلط باشه چنین نتیجه میگیریم
T && .... = ?
F && ...= F
T || ... = T
F || ... = ?
در جاهایی که از ؟ استفاده شده منظور اینه که نتیجه معلوم نیست و به قسمت نامعلوم جمله یعنی (....) بستگی داره و باید بقیه جمله رو مطالعه کرد و همچنین || معادل با OR و عبارت && برابر با AND منطقی است

دلیل اینکه این بحث رو مطرح کردم
۱)برای اینکه کدهاتون رو راحت تر بهینه کنید و شیوه کار شیشتم رو در برخورد با عبارات تودرتو و پشت سر هم بدونید (لذا دز استفاده از AND یا شرط های اجماعی (همه باید صادق باشند مثل IF های تو در تو)باید عبارتی رو اول قرار بدید که احتمال اینکه غلط در بیاد بیشتره و در این صورت به علت اینکه عبارات کمتری چک میشه سرعت اجرا بالا میره و به طور مشابه در جایی که از OR استفاده می کنید یا شرط های موازی دارید مثل IF و ELIF ها که فقط یکیشون اجرا میشن بهتره که عبارتی اول بیاد که معمولا صحیح هستش. در عباراتی که از ترکیب OR و AND ساخته میشه هم باید به ترتیب اولویت ها دقت کرد تا کدی بهینه و سریع داشته باشیم

۲)اینکه کد زیر مربوط به && و || یعنی AND و OR میشه که همونجوری که گفتم در && ممکنه فقط اولین statement اجرا بشه و به بیان بهتر فقط تا statement ای اجرا میشه که ارزش منطقی صحیح داشته باشه و در باره OR هم فقط تاجایی اجرا میشه که ارزش منطقی غلط داشته باشه


The AND List
شکل کلی
statement1 && statement2 && statement3 && ...همونجوری که گفته شد عبارات به ترتیب از سمت چپ اجرا میشن.در صورتی که ارزش True داشته باشن بعدی هم اجرا میشه و لی اگر غلط باشه ارزش کل برابر False قرار میگیره و دیگه عبارتی اجرا نمیشه.
#!/bin/sh
touch file_one
rm -f file_two
if [ -f file_one ] && echo “hello” && [ -f file_two ] && echo “ there”
then
    echo “in if”
else
    echo “in else”
fi
exit 0

خوب این کد چیکار میکنه؟
دستور touch که حتما باهاش آشنایید.چک میکنه که فایل file_one وجود داره یا نه و اگر وجود نداشت اون رو ایجاد میکنه. به عبارت دیگه این اطمینان رو به ما میده که این فایل در ادامه اجرای اسکریپت حتما وجود داشته باشه
در طرف مقابل دستور rm این اطمینان رو ایجاد میکنه که file_two حتما وجود نداره و اگرم وجود داشته الان دیگه پاک شده

بنابر این قسمت اول عبارت که به برسی file_one میپردازه حتما true هستش چون با دستور touch این اطمینان رو بدست اوردیم
لذا دستور بعدی یعنی echo اجرا میشه که این هم موفقیت آمیزه و خروجی True داره چون دستور echo همیشه خروجی True داره پس عبارت hello بر روی مونیتور چاپ میشه
حالا قسمت سوم یعنی چک کردن فایل file_two اجرا میشه که موفقیت آمیز نیست!!!! چون خودمون با دیستور rm از عدم وجود اون اطمینان پیدا کرده بودیم پس مقدار این عبارات حتما false هستش
در همینجا اجرا و بررسی این list متوقف میشه چون مقدار کل برابر false میشه , و لذا عبارت there هیچوقت بر روی مونیتور چاپ نخواهد شد!!! از طرف دیگه گفتیم ارزش کل نیز برابر false میشه به علت وجود یک flase (عدم وجود فایل file_two) پس وارد قسمت else میشیم و عیارت in else نیز بر روی مونیتور چاپ خواهد شد


The OR List

statement1 || statement2 || statement3 || ...
خب حالا کد فوق رو تغییر بدید به شکلی که از عدم وجود فایل file_one اطمینان داشته باشید و نیازی به file_two نداریم
خط شرط رو نیز به شکل زیر تغییر بدید
if [ -f file_one ] || echo “hello” || echo “ there”
پس کل کد به شکل زیر در میاد
    #!/bin/sh
    rm -f file_one
    if [ -f file_one ] || echo “hello” || echo “ there”
    then
         echo “in if”
    else
         echo “in else”
    fi
    exit 0

خروجی رو به راحتی میشه بررسی کرد
file_one حتما وجود نداره و خروجی اون برابر false هستش اما دستور بعدی یعنی echo "Hello" مقداری برابر با true داره پس بررسی متوقف میشه چون با یک true برخورد کرده و لذا ارزش کل برابر با true قرار میگیره و ادامه اجرا به داخل بدنه اصلی if منتقل میشه و عبارت in if بر روی مونیتور چاپ میشه

بحث شیرین بعدی بانام بلوک ها یا statement blocks
بعضی وقتها شما نیاز دارید تا یک مجموعه دستور رو بجای یک تک دستور (جایی که فقط یک statement میشه گذاشت)قرار بدید
به عنوان مثال چند دستور در بین دو عبارت && یا || قرار بگیره.
شما میتونید این کا رو با چسبوندن این مجموعه دستور با علامت {} انجام بدید. علامت های {} یک بلوک رو به وجود میاره و سیستم با این بلوک به شکل یک تک دستور برخورد میکنه و به عبارت دیگه این بلوک یکپارچه است و برابر یا یک single statement هستش
به عنوان مثال به کد زیر دقت کنید
get_confirm && {
   grep -v “$cdcatnum” $tracks_file > $temp_file
   cat $temp_file > $tracks_file
   echo
   add_record_tracks
}

خوب فکر میکنم برای این بحث کافیه و لذا بحث جدید دیگه ای رو شروع میکنم FUNCTIONS یا توابع
شما میتونید در اجرا و نوشتن کدهاتون از توابع استفاده کنید و توابعی رو برای خودتون بنویسید تا کدتون منظم تر و خوانا تر بشه!
در بعضی موارد (بسته به کد) نوشتن تابع اثر مثبت زیادی بر روی سرعت و نحوه اجرای برنامه میذاره
به عنوان یک جایگزین و تقریب ذهن شما میتونید یک اسکریپت یا کد بزرگ رو به چندید اسکریپت کوچیک بشکونید که هرکدوم از اونها یک عمل کوچیکی رو انجام میدند

اگر شما از اینکه برنامه های بزرگ رو در شل بنویسید میترسید یا فکر میکنید کارامد نیست باید بهتون یادآور بشم که خیلی از برنامه های بزرگی رو که استفاده میکنید در شل نوشته شدندو باید یاداوری کنم که FSF autoconf و خیلی برنامه های نصب پکیج در لینوکس اسکریپت های شل هستند!
نکته مهم در این مورد اینه که این اطمینان رو دارید که برنامه شما همیشه در لینوکس قابل اجراست چون هیچ لینوکسی بدون شل نمیشه و لذا در گستره وسیعی از unix و لینوکس سیستم ها برنامه شما حتما اجرا میشه

برای اینکه یک تابع رو تعریف بکنیم از شکل زیر استفاده میکنیم
function_name () {
  statements
}

و حالا یک کد زیبا و بسیار ساده
#!/bin/sh
foo() {
    echo “Function foo is executing”
}
echo “script starting”
foo
echo “script ended”
exit 0

چند نکته مهم:
۱- همیشه باید قبل از صدا کردن یا به عبارتی invoke کردن تابع اون رو تعریف کرده باشید
پس باید  حتما متن توابع قبل از اولین صدا زدن تابع قرار گرفته باشه.
۲-وقتی یک تابع صدا زده میشه و شروع به اجرا میکنه تمام متغیر های پارامتری از قبیل $*, $@, $#, $1, $2, چیز های مشابه با پارامتر هایی که به تابع پاس داده شدند جایگزین میشن و در واقع به همین صورت شما به پارامتر هایی که به تابع پاس داده شده دسترسی پیدا میکنید و دقیقا پس از پایان تابع و بازگشت به متن اصلی برنامه تمام متغیر های پارامتری به مقدار اصلی و اولیه خودشون بر میگردند تا در ادامه برنامه بشه از اونها استفاده کرد

در ادامه این پست به بررسی چگونگی قراردادن یک خروجی در تابع میپردازیم اما توجه داشته باشید چون برخی از شل های قدیمی بعد از اجرای تابع مقدار خروجی اون رو بر نمیگردونند اگر پرتابل بودن و قابلیت جابجایی کد برای شما خیلی مهمه(به عنوان مثال اگر یک هکر هستید) روی این قابلیت زیاد حساب نکنید.

با استفاده از دستور return میشه یک تابع رو مجبور کرد تا مقدار عددی رو به عنوان خروجی برگردونه. راه معمول برای پس فرستادن مقادیر استرینگ به عنوان خروجی استفاده از متغیر هایی هستش که بعد از اجرای تابع نیز قابل استفاده باشند و یا اینکه به عنوان جایگزین با دستور echo این متن را چاپ کنیم و به شکل زیر این مقدار رو در یک متغیر ذخیره کنیم
foo () { echo JAY;}
...
result=”$(foo)”

حالا باید یک بحث دیگه رو بررسی کنیم به نام scope یا حوضه دید
این بحث خیلی طولانی ومهمه و برای همین بحث کامل تر و گسترده تری رو بعدا به این موضوع اختصاص میدم اما فعلا توجه کنید که اگر یک متغیر را مستقیما محلی تعریف کنید فقط در محل و حوضه خودش قابل ذسترسی و مشاهده هست
متغیر های محلی با عبارت local مشخص میشن
هر تابع برای خودش یک حوضه داره و لذا به متن زیر دقت کنید
   #!/bin/sh
   sample_text=”global variable”
   foo() {
       local sample_text=”local variable”
       echo “Function foo is executing”
    echo $sample_text
}
echo “script starting”
echo $sample_text
foo
echo “script ended”
echo $sample_text
exit 0

خوب این بحث رو در پست بعدی ادامه میدم
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #34 : 12 شهریور 1388، 06:18 ب‌ظ »
 سلام
هر حوضه مثل یک برنامه جدید میمونه پس اگر متغیری به صورت local درونش تعریف بشه فقط در اون دیده میشه ولی در صورتی که در اسکپی نتغیری با نام تکراری به صورت local تعریف نشه شما میتونید در شرایطی به متغیر های سطوح بالا تر دسترسی داشته باشید

در اسکریپت زیر روش پاس دادن متغیر ها رو بین توابع و متن اصلی اسکریپت مشاهده می کنید
#!/bin/sh
yes_or_no() {
  echo “Is your name $* ?”
  while true
  do
     echo -n “Enter yes or no: “
     read x
     case “$x” in
       y | yes ) return 0;;
       n | no ) return 1;;
       * )        echo “Answer yes or no”
     esac
  done
}

echo “Original parameters are $*”
if yes_or_no “$1”
then
   echo “Hi $1, nice name”
else
   echo “Never mind”
fi
exit 0

خوب فکر نمیکنم نیازی به تفسیر باشه

break
از این دستور برای خروج نا به هنگام یا به عبارت دیگه فرار از حلقه استفاده میکنیم
این دستور با توجه به اینکه خیلی میتونه کارامد باشه اما در مقابل اون باید توجه داشته باشید که هنگامی که در حلقه قرار بگیره دیگه نمیشه مطمین بود که چه میزان حلقه اجرا میشه و همچنین باعث میشه که از خوانایی کد کم بشه.لذا پیشنهادی مبنی بر استفاده از این دستور وجود نداره و فقط خودتون باید بر اساس کد تصمیم بگیرید که چیکار کنید.
به صورت دیفالت این دستور فقط یک لول را متوقف میکنه

اسکریپت :
#!/bin/sh
rm -rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
    if [ -d “$file” ]; then
        break;
    fi
done
echo first directory starting fred was $file
rm -rf fred*
exit 0

دستور جدید یعنی ( : )
این دستور معادل با true هستش و البته نکته مهم اینه که اگرچه خیلی خیلی سریعتر از true اجرا میشه اما معمولا کد نهایی از خوانایی کمی برخورداره
به عنوان مثال به عبارت زیر دقت کنید
while :این عبارت معادل با عبارت زیره
while trueکه هر دو یک حلقه بی پایان رو به وجود میارن

یک کار برد دیگه این دستور برای مقدار دهی به یک متغیر در شل هستش
به عنوان مثال :
: ${var:=value}بدون : شل عبارت $var رو به صورت یک دستور تفسیر میکنه و قصد اجرای اون رو خواهد داشت

نکته : در کدها و اسکریپت های قدیمی ممکنه که علامت : رو در اول برخی خط ها ببینید تا اون خط ها کامنت باشند اما در شل های جدید تر (مثل اینی که شما باهاش کار میکنید) حتما باید کامنت ها با علامت # شروع بشن چون خیلی کارامد تر هستند و خیلی بهتر اجرا میشن

#!/bin/sh
rm -f fred
if [ -f fred ]; then
    :
else
    echo file fred did not exist
fi
exit 0


دستور جدیدی دیگر Continue
دستور قبل رو باهاش در C آشنا شده بودید.این دستور هم همون کاری رو میکنه که در C انجام میده
یعنی حلقه رو کوتاه میکنه و هرگاه برنامه با این دستور در حلقه مواجه بشه از بقیه حلقه تا انتهای اون صرف نظر میکنه و شروع به اجرای حلقه از ابتدای اون میکنه(از حلقه خارج نمیشه)
#!/bin/sh
rm -rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
    if [ -d “$file” ]; then
          echo “skipping directory $file”
        continue
    fi
    echo file is $file
done
rm -rf fred*
exit 0

این دستور میتونه یک عدد به عنوان پارتمتر غیر اجباری داشته باشه تا به عنوان شماره استفاده بشه و مقداری از ابهام حلقه های تو در تو کم کنه ولی این پارامتر به ندرت استفاده میشه زیرا در مواقعی خودش باعث ناخوانی کد میشه. به مثال زیر دقت کنید
ٰٰٰٰٰٰٰٰfor x in 1 2 3
do
   echo before $x
   continue 1
   echo after $x
done

خروجی :
before 1
before 2
before 3

دستور دات (.)

دستور دات باعث میشه تا دستورات در شل فعلی اجرا بشن
. ./shell_scriptبه صورت دیفالت وقتی یک اسکریپت اجرا میشه و یا یک دستور خارجی رو اجرا میکنید یک محیط جدید (subshell) ساخته میشه و دستورات در این محیط جدید اجرا میشه اما دستور دات و منابع خارجی (دو هم معنی) باعث میشن تا در همون جایی که اسکریپت صدا زده شده یا دستور اجرا شده اجرا بشن
معنی این جملات اینه که به صورت دیفالت هر تغییری که اسکریپت یا دستوری بر روی متغیر های محلی بده از بین میره و دستور دات از طرف دیگه این امکان رو میده که بر روی محیط فعلی تغییر رو ایجاد کنید
موقعی کاربرد این موضوع رو متوجه میشید که یک اسکریپت نوشته باشید تا محیط رو تنظیم و آماده کنه تا بعدا یک اسکریپت دیگه اجرا بشه!
به عنوان مثال اگر بر روی چند پروژه به صورت همزمان کار کنید به این نکته برخورد کردید که برای هر برنامه باید پارامتر ها به شکل های مختلفی ست بشه به عنوان مثال شاید لازم باشه که برای اجرای یک برنامه قدیمی یک نسخه قدیمی تری از کامپایلر رو invoke کنید

دستور دات در شل کمی شبیه به دستور #include در زبان برنامه نویسی C هستش. اگر چه این دستور چیزی رو به اسکریپت شما نمی چسبونه اما چون محل اجرای دستور رو تغییر میده به شما این امکان رو میده که دستوراتی رو و توابعی رو اجراکنید که در اسکریپت شما تعریف نشدند

در مثال زیر اگرچه دستور . درون شل تایپ شده اما میشه این دستور رو درون اسکریپت هم استفاده کرد
در این مثال ما دو اسکریپت برای دو تنظیم مختلف برای اجرا دستورات مختلف برای دو پروژه خواهیم ساخت

نام : classic_set
#!/bin/sh
version=classic
PATH=/usr/local/old_bin:/usr/bin:/bin:.
PS1=”classic> “

نام : latest_set
#!/bin/sh
version=latest
PATH=/usr/local/new_bin:/usr/bin:/bin:.
PS1=” latest version> “

 حالا به استفاده از دستورات و خروجی دستورات دقت کنید
$ . ./classic_set
classic> echo $version
classic
classic> . latest_set
latest version> echo $version
latest
latest version>

آخرین دستور این پست که باهم بررسی میکنیم echo

این دستور معادل با printf در شل های جدید تر است.از این دستور زیاد استفاده کردیم پس چیزی دیگه نمیگم غیر از چند نکته کوتاه
بزرگ ترین مشکل در استفاده از این دستور چگونگی ایجاد خط جدید یا new line هستش و دلیل ایم مشکل هم اینه که ورژن های مختلف UNIX راه حل های متفاوتی رو پیشنهاد دادن و البته معمول ترین روش در لینوکس به شکل زیر هستش
echo -n “string to output”گاهی هم به شکل زیر
echo -e “string to output\c”
مدل دوم یعنی echo -e این اطمینان رو ایجاد میکنه که مفسر شما برای تفسیر کاراکتر های بعد از \ مانند \n برای اینتر و \t برای tab فعال هستش.اگرچه معمولا به صورت دیفالت فعال هست

اگر اسکریپت شما قراره در مجموعه وسیعی از unix و linux اجرا بشه میتونید از دستور خارجی tr استفاده کنید برای ایجاد خط جدید که البته خیلی خیلی کند تره
اما اگه قراره فقط برروی سیستم های linux اجرا بشه به احتمال زیاد با دستور echo -n مشکل سما حل خواهد شد

در پست بعد به بررسی eval , exec , exit n و چند دستور دیگر خواهیم پرداخت
و حالا به استفاده از دو اسکریپت
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین firethumbs

  • Full Member
  • *
  • ارسال: 151
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #35 : 14 شهریور 1388، 07:33 ب‌ظ »
چاکریییییییییییییییییییییییییییییییییییییییییییییییییییم خیلی باحالی \\:D/ \\:D/ \\:D/ \\:D/ :guitar: :lolflag: O0 :-({|= :popcorn: =D> ):P

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #36 : 15 شهریور 1388، 12:32 ق‌ظ »
.... O0 .....

آقا چقدر مو داری شما!!! خدا ازت نگیره  ;)

شوخی کردم  ;D به دل نگیری یک وقتا


بحث رو ادامه میدم با مبحث زیبای eval

ای دستور از evaluate میاد و برای بررسی و ارزیابی آرگومان ها استفاده میشه
این دستور در داخل خود شل ساخته و برنامه نویسی شده و در جای دیگه ای به عنوان یک دستور خارجی وجود نداره
شاید توضیح این دستور یکم سخت باشه واسه همین اون رو بایک مثال شرح میدم

foo=10
x=foo
y='$'$x
echo $y

خروجی این دستورات چیه؟
دقیقا خود عبارت foo$ خروجی این دستور هست و نه چیز دیگه ای (نه مقدار اون)

حالا به دستورات زیر دقت کنید

foo=10
x=foo
eval y='$'$x
echo $y

خروجی این دستور عدد ۱۰ هست!!!
دستور eval تا مقداری میشه گفت شبیه به یک دالرساین ($) اضافه عمل میکنه.این دستور به شما مقدار متغیر رو میدهد
شاید لازم باشه که تذکر بدم در دستورات بالا در خطی که نوشته شده x=foo , عبارت foo یک استرینگ ساده هست و نه یک متغیر ولذا مقداری غیر از عبارت foo نداره
میشه این گفته رو با دستور echo $x تست کرد. دلیل این امر هم عدم وجود $ در این خطه
اگه قرار بود مقدار متغیری به نام foo درون متغیری به نام x ریخته شه باید یک $ قبل از نام متغیری کهخونده میشه (یعنی foo$) گذاشته بشه که چون در اینجا این علامت وجود نداره پس یک استرینگ سادست و بس
لذادرعبارتی که دردستورات اول در مقدار دهی y استفاده شده تنها دو استرینگ درکنارهم قرار دارند و خروجی آن رو هم که مشاهده میکنید
در مجموعه دستورات دوم - دستور eval این امکان رو به ما میده تا استرینگ داخل y تفسیر بشه و مقدار متغیری که با این استرینگ همنام هستش در اون جایگزین بشه
لذا میشه گفت که در مجموعه دستور اول عبارت foo=10 زیادی هست و هیچ کاری انجام نمیده!

دستور eval خیلی پرکاربرد و کارامد هستش
این دستور این امکان رو میده که کد در حال اجرا ساخته بشه و اجرا بشه.به قول خارجکی ها کدها generate and run on the fly میشن  :P
درسته که این کدها معمولا پیچده و سخت تفسیر خواهند شد اما عدم وجود این دستور باعث میشه تا نوشن برخی کدها بسار دشوار ودر بعضی شرایط غیر ممکن بشه

exec
این دستور دو استفاده متفاوت داره!!!!
معمولا برای این استفاده میشه که شل فعلی رو با یک برنامه دیگر جایگزین کنه
exec wall "Thanks for all the fish"در این اسکریپت - شل با دستور wall جایگزین خواهد شد

هیچ خطی بعد ار دستور exec در اسکریپت اجرا و تفسیر نخواهد شد چون شلی که این اسکریپت رو اجرا کرده دیگر وجود نداره!

استفاده دیگر این دستور برای تغییر دادن مفسر فعلی فایل هست
exec 3<afile
این دستور باعث میشه که مفسر فایل شماره ۳ برای خواندن فایل afile باز بشه(منظور از مفسر descriptor هست)
واقعا از این منظور زیاد استفاده میشه

exit n و بقیه دستورا باشه طلبتون
امشب خیلی خستم اما چون دوستمون firethumbs جان پست داده بودند دلم نیومد که هیچی پست ندم ولذا همینقدر رو از من قبول کنید
یک گله هم کنم از اساتید محترم
آقا چرا در این تاپیک پست نمیدید؟؟؟؟ دست مارم بگیرید. چرا تحویل نمیگیرید دوستان؟ یه لطفی مرحمتی!!!
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین firethumbs

  • Full Member
  • *
  • ارسال: 151
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #37 : 15 شهریور 1388، 01:13 ب‌ظ »
.... O0 .....

آقا چقدر مو داری شما!!! خدا ازت نگیره  ;)

شوخی کردم  ;D به دل نگیری یک وقتا


امشب خیلی خستم اما چون دوستمون firethumbs جان پست داده بودند دلم نیومد که هیچی پست ندم ولذا همینقدر رو از من قبول کنید
یک گله هم کنم از اساتید محترم
آقا چرا در این تاپیک پست نمیدید؟؟؟؟ دست مارم بگیرید. چرا تحویل نمیگیرید دوستان؟ یه لطفی مرحمتی!!!

خیلی مخلصیم

اقا موهام داره مثل برگ پاییزی می ریزه. داغم را تازه کردی. دعا کن که بمونه رو کله ام
خیلی لطف کردید اقا . دستتون درد نکنه.همین قدر هم از سرمون زیاده.! ما که بی سوادیم اگه چیزی بلد بودیم حتما باهات همکاری می کردیم.
اگه کاری ازم بر میاد بگو دریغ نمی کنم. ما هم مبتدی هستیم. بلکه چیزی یاد بگیریم.
از پست اولت شروع کردم به خوندن.
یه اشکال کوچیک هم دارم. من در همون مثال اول که گفته بودی فایل first بسازیم. اینکار را کردم ولی برنامه ای که نوشتم اجرا نمی شه.
این پیغام را می ده
The program 'first' is currently not installed.  You can install it by typing:
sudo apt-get install yagiuda
bash: first: command not found
اشکال چیه ؟
البته در یک فلدر دیگه ای(جدید) این کار را کردم. می تونه اشکال این باشه؟
یه سوال دیگه شما در همون پستهای اولیه ات گفته بودی :

نکته : تغییر دادن PATH به شکل فوق برای سوپر یوزر ویا همون root کار خیلی خطرناکته چون یک شکاف امنیتی محسوب میشه چون با اجرای یک دستور توسط root ممکنه که یک برنامه اشتباه و دروغین اجرا بشه!!!(حالا پس با کپی کردن یک اسکریپت با نام یکی از دستورات مشهور و پر استفاده شما میتونید هر کار ی رو در سیستم قربانی انجام بدین Silenced چون با دسترسی root قراره اجرا بشه)

حالا سوال من :چرا؟مگه مسیر جاری را در path قرار دادن اشکال داره و چطور می شه که این خطر پیش میاد
« آخرین ویرایش: 15 شهریور 1388، 01:17 ب‌ظ توسط firethumbs »

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #38 : 15 شهریور 1388، 02:44 ب‌ظ »
اگه کاری ازم بر میاد بگو دریغ نمی کنم. ما هم مبتدی هستیم. بلکه چیزی یاد بگیریم.
از پست اولت شروع کردم به خوندن.
یه اشکال کوچیک هم دارم. من در همون مثال اول که گفته بودی فایل first بسازیم. اینکار را کردم ولی برنامه ای که نوشتم اجرا نمی شه.
این پیغام را می ده
The program 'first' is currently not installed.  You can install it by typing:
sudo apt-get install yagiuda
bash: first: command not found
اشکال چیه ؟
البته در یک فلدر دیگه ای(جدید) این کار را کردم. می تونه اشکال این باشه؟
یه سوال دیگه شما در همون پستهای اولیه ات گفته بودی :

نکته : تغییر دادن PATH به شکل فوق برای سوپر یوزر ویا همون root کار خیلی خطرناکته چون یک شکاف امنیتی محسوب میشه چون با اجرای یک دستور توسط root ممکنه که یک برنامه اشتباه و دروغین اجرا بشه!!!(حالا پس با کپی کردن یک اسکریپت با نام یکی از دستورات مشهور و پر استفاده شما میتونید هر کار ی رو در سیستم قربانی انجام بدین Silenced چون با دسترسی root قراره اجرا بشه)

حالا سوال من :چرا؟مگه مسیر جاری را در path قرار دادن اشکال داره و چطور می شه که این خطر پیش میاد

سلام دوست گلم
چرا کاری از دستت بر نمیاد
موقع خوندن ممکنه احساس کنی یه جایی از مطلب گنگه و یا اینکه جای دیگه ای چیری خوندی یا تجربه ای داری که فکر میکنی من جایی غلط نوشتم
اگه پست بزنی و این مطلب رو با من در میون بذاری باعث میشه که هم من چیزای جدید یاد بگیرم و هم این مجموعه به امید خدا کامل تر و بهتر بشه و بعدا بقیه دوستان راحتتر استفاده کنند(اگر بعدا بخام اینو pdf کنم چون تو pdf نمیشه مثل فروم سوال پرسید پس در اینجا باد همه سوال های ممکن پرسیده بشه و جوابش معلوم بشه)
همین سر زدن شما به این تاپیک و مطالعه اون و پرسیدن سوال و نظر دادن و اشکال وارد کردن به مثال ها و غیره بزرگترین لطفی هستش که میتونید به من بکنید

اما در باره ۲ سوال شما

در باره اجرا کردن فایل ها باید اینو بگم:
شما وقتی در ترمینال یک عبارتی رو تایپ می کنید-این عبارت یا دستوری که تایپ کردید یا دستوری هست که در زمانی که شل رو میساختند داخل اون وجود داشته ویا اینکه یک اسکریپت یا برنامه خارجی هست که شما دارید اجراش میکنید
به عنوان مثال برنامه nautilus رو در نظر بگیر.این برنامه یک برنامه جدای از shell هست.در بعضی از کامپیوتر ها ممکنه نصب نباشه و جود نداشته باشه و در بعضی مثل ubuntu وجود داشته باشه(nautilus اسم فایل منیجر شما هست)
وقتی از ترمینال تایپ میکنید nautilus . ترمینال این برنامه رو اجرا میکنه اما به نظر تو آدرس این برنامه رو ازکجا پیدا میکنه که اجراش کنه؟ ازکجا میدونه که کجا نصب شده؟
ویا حتی فکرکن این برنامه وجود نداشته باشه و نصب نباشه (مثل برنامه ای به نام first که شما نوشتید) از کجا میفهمه که نیست که پیغام میده (درست یا غلط ولی پیغام میده)
دلیلش همونیه که در پست اول گفتم.
وقتی nautilus رو تایپ میکنی شل در سیستم شما در آدرس های موجود در PATH (به بزرگی و کوچکی حروف دقت کنید)به دنبال اسکریپت یا برنامه ای به نام nautilus میگرده که حالا یا پیدا میکنه و یا پیدا نمیکنه.اگه پیدا کنه که اجراش میکنه ولی اگه پیدا نکنه پیغام میده که وجود نداره ۰بهتره اینجوری بخونیم که در آدرس های PATH وجود نداره)
به همین سادگی
لذا شل تمام سیستم رو به دنبال nautilus نمیگرده و فقط فولدر های خاصی رو میگرده
در سیستم شما فایل file در آدرس های موجود در PATH قرار نداشته (در زمان اجرای دستور) لذا با اون پیغام روبرو شدید
عبارت دات (.) در آدرس دهی در لینوکس به معنی آدرس دهی نسبی هست و عدم وجود دات (.) به معنی آدرس دهی مطلق
فرض کن که در PATH فقط مقدار /usr/bin/ وجود داشته باشه در این صورت با زدن دستور nautilus - این برنامه با آدرس مطلق زیر اجرا میشه
/usr/bin/nautilus
اما حالا فرض کن با ترمینال و با استفاده از دستور cd به فولدر خانگی خودت رفته باشی
(فولدر خانگی یعنی اگر اسم یوزر شما abcd باشه آدرس /home/abcd/)
در این حالت قصد داری وارد فولدر دسکتاپ خپدت بشی. هرکدوم از دو دستور زیر قابل قبوله فقط روش اول مطلق و روش دوم نسبی هستش
cd /home/abcd/Desktop
cd ./Desktop
خوب واضحه که در جاهایی که بشه از آدرس دهس نسبی استفاده کرد این کار بهتره و راحت تره
حالا به مثال های زیر دقت کن
وقتی که در متغیر PATH مقدار دات (.) وجود داشته باشه به این معنی  هست که (آدرس دهی نسبی و اشاره یه فولدر فعلی) برنامه های موجود در آدرس فعلی رو برای یافتن دستور مورد نظر جستجو و در صورت وجود اجرا کن.
ویا اگر این عبارت وجود نداره در PATH خوب شما برنامه رو با آدرس مطلق اجرا میکنی تا دیگه نیازی به چک شدن PATH توسط شل وجود نداشته باشه
یعنی اگر برنامه در آدرس جاری و فعلی قرار داره تایپ کن first/. که یعنی برنامه فرست رو از آدرس فعلی اجرا کن
حالا اگه آدرس مطلق برنامه first رو که به عنوان مثال در فولدری بهنام xyz در فولدر خانگیت وجود داره بخای وارد کنی و یا آدرس نسبی اون رو در حالی که خودت در فولدر خانگیت قرار داشته باشی باید یکی از دو عبارت زیر رو تایپ کنی
/home/abcd/xyz/first
./xyz/first
اگر هنوز جایی از این بحث گنگه لطفا بفرمایید تا بیشتر توضیح بدم
فقط یک نکته رو اضافه میکنم و اون اینکه عبارت ~ به معنی فولدر خانگی هست.یعنی برای شما ~ معادل است با /home/abcd/
پس در آخرین مثالمون میشه آدرس دهی مطلق رو به شکل زیر هم انجام داد
~/xyz/firstویا برای جابجا شدن به فولدر خانگی در ترمینال از دستور زیر استفاده کرد
cd ~


حالا سوال دوم
با توجه به اونچه که گفتم (PATH درسته و نه path) شما فرض کنید که چندین آدرس در این متغیر وجود داشته باشه
دستوری مثل دستور copy رو در نظر بگیرید
اگر این دستور با همین نام در بیش از یکی از این آدرس ها و مثلا در ۲ تا از این آدرس ها وجود داشته باشه.با زدن دستور copy شل یکی از اینها رو اجرا میکنه اما کدوم رو؟
در اینجا فرض کنید که یکی از این copy ها رو من وشته باشم و قصد خراب کردن سیستم شما رو داشته باشم
اسکریپت من علاوه بر اینکه عمل کپی رو انجام میده کارهای دیگری مثل نصب چند برنامه مخرب و backdoor ویا ارسال برنامه ها وفایل های شخصی شما رو برای من انجام بده
در این صورت وقتی که شما دستور cp رو اجرا میکنید با اینکه در ظاهر عمل کپی با موفقیت انجام میشه - سیستم شما مورد حمله قرار میگیره
پس تغییر دادن و یا اضافه کردم آدرس ها به PATH کار مهم و حساسیه
اگر شما به متغیر PATH مقدار دات (.) رو اضافه کرده باشید به این معنی هست که شل در هنگام اجرای یک دستور باید فولدر جاری رو نیز به دنبال اون دستور جستجوکنه
حالا احتمال خطر بیشتره!
چون من ممکنه به همه فولدر ها دسترسی نداشته باشم که اسکریپت های مخربم رو برروی اونها کپی کنم اما به بعضی ها دسترسی خواهم داشت و این احتمال وجود داره که شما به صورت ناخواسته این اسکریپت رو اجراکنید

تغییر دادن متغیر های محلی و مجوز ها و سطوح دسترسی به صورت کلی کار حساسی هست و بر روی امنیت سیستم اثر مستقیم میذاره. یک مدیر امنیت باید فردی باهوش باشه و در مقابل اون هکر ها آدم هایی زیرک تر وباهوش ترند (البته من کلاه سفید ها رو بیشتر از کلاه سیاه ها دوست دارم)
من یک یوزر سادم و کلاه سفید نیستم اما کلاه سفید هارو دوست دارم  ;)

اگه سوالی هست بازم در خدمتم

یا علی
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1529
  • جنسیت : پسر
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #39 : 15 شهریور 1388، 07:16 ب‌ظ »
هر وقت تکنوتاکس درست شد، یه سری به این لینک بزنید:
http://www.technotux.org/html/PNphpBB2-viewtopic-t-13341.html
در رابطه با همین PATH و دایرکتوری جاری(.) و مسائل امنیتی هست.

آفلاین firethumbs

  • Full Member
  • *
  • ارسال: 151
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #40 : 15 شهریور 1388، 07:31 ب‌ظ »
خیلی چاکریییییییییییییییییییییییییم
این حاصل فرمان ال اس من است
drwxr-xr-x  2 sniper sniper 4096 2009-09-06 19:17 .
drwxr-xr-x 77 sniper sniper 4096 2009-09-06 19:14 ..
-rwxrwxrwx  1 sniper sniper  149 2009-09-05 19:22 first
-rw-r--r--  1 sniper sniper    0 2009-09-06 13:03 kill micro$oft's office
-rw-r--r--  1 sniper sniper    0 2009-09-05 19:17 mydata
-rw-r--r--  1 sniper sniper    0 2009-09-05 18:57 one
-rw-r--r--  1 sniper sniper  113 2009-09-05 19:16 psout
-rw-r--r--  1 sniper sniper   84 2009-09-05 19:15 psout1
-rw-r--r--  1 sniper sniper    0 2009-09-05 18:57 three
-rw-r--r--  1 sniper sniper    0 2009-09-05 18:57 two

اقا من فایل را به این صورت اجرا می کنم
./ttt/first
ttt فلدری است که در پوشه خانگی من قرار داره. بعد این خروجی را می گیریم
grep: Unsaved: No such file or directory
grep: Document: No such file or directory
grep: 1: No such file or directory
first
first~
داخل فلدر ttt هم که می روم و فایل را به این صورت اجرا می کنم
 ./first
این خروجی را دارم:
first
grep: kill: No such file or directory
grep: micro$oft's: No such file or directory
grep: office: No such file or directory


سوال دوم
چرا ادرس دهی نسبی بهتر از مطلق است.؟
backdoor چیه؟
سوال بعدی
من در یک مقاله خوندم که وقتی فرمانی را اجرا می کنی اول فلدری برای آن فرمان جستجو می شود که در PATH اول باشد. پس جای نگرانی نیست چون وقتی شما (.) را به مسیر اضافه می کنی نقطه در آخر مسیر قرار می گیرد و اگه به قول شما کسی فرمان کپی را اجرا کند مسیرهای قبلی اجازه اجرای آن را ندارند و فرمان کپی که در مسیر قبل از (.) قرار دارد اجرا میشود

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #41 : 15 شهریور 1388، 11:24 ب‌ظ »
سلام
آدرسی که ilius جان دادند هم خیلی جالبه و سالم هم هست (مگه تکنوتاکس برای شما قطعه ilius جان؟)

به هرحال جواب سوال های شما دوست محترم (در حد سواد من)

من متن شما رو کامل خوندم اما همچین چیزی به نظرم امکان نداره! نمیدونم چی شده چون مجوز های شما کاملا درسته پس فکرکنم شاید مشکل تایپی ای چیزی باشه
دستور زیر رو لطفا یک بار دیگه تایپ کنید و دقتکنید که هیچ فاصله ای وجود نداره - برای اطمینان نصف کلمه first رو که نوشتید با زدن کلید tab اون رو کامل کنید. اگر اشتباه دستوری یا املایی یا تایپی باشه دیگه دکمه tab متن رو کامل نمیکنه
~/ttt/first
اگه بازم کار نکرد دیگه سواد من قد نمیده!



آدرس دهی نسبی بهتر یا بدتر نیست و فقط دو روش آدرس دهی هستند. آدرس دهی نسبی به نظر من دو نکته داره
۱ - راحت تره
۲ - در اسکریپت نویسی بیشتر کاربرد داره چون معمولا شما قصد دارید اسکریپتتون در محل و ادرس فعلی (یعنی دات (.)) اجرا بشه

وقتی یک هکر قصد نفوذ رو داشته باشه گاهی اوقات از یک سری برنامه هایی که بروی سیستم شما هستند استفاده میکنه تا کارش راحت بشه و یا گاهی بعد از طی کردن مراحل و روش های دیگه هک و هک کردن سیستم شما برای اینکه از این به بعد راحت تر به سیستم شما دسترسی پیدا کنه و دیگه این دشواری ها رو تحمل نکنه یک سری برنامه روی سیستم شما نصب میکنه که در واقع این برنامه (که هکر نصب کرده ویا اینکه برنامه ای غیر مطمئن که خودتدن نصب کردید) به سیستم شما و مراحل امنیتی موجود روی اون خیانت میکنه و هکر میتونه تمام سیستم های امنیتی موجود روی سیستم شما رو دور بزنه.
مثل در پشتی خونه که یک دزد خودش برای خونه شما ساخته باشه ولذا کلیدش رو هم داره
هرچقدر شما امنیت برای درب جلو خونه بذارید فایده نداره چون اون به راحتی و از در پشتی وارد خواهد شد!


بله دقیقا فرمایش شما و اونی که مطاله کردید صحیح و درسته. ترتیب آدرس ها در PATH اهمیت داره اما اونی که من گفتم یک مثال بود برای اینکه اهمیت تغییر دادن متغیر های محلی و مجوزهای دسترسی معلوم بشه.با تغییر متغیر های موجود و یا مجوز ها ممکنه که کار رو برای یک کلاه سیاه سخت تر و یا ساده تر کنید. به هر حال هر قدمی در زمینه امنیت باید قدمی آگاهانه و از روی تفکر باشه و تست شرایط بر روی یک سیستم واقعی که اطلاعات مهمی هم بر روی خود داره کار درستی نیست و خطر ناکه
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #42 : 17 شهریور 1388، 07:36 ب‌ظ »
منتظر جواب دوست عزیز و جدیدمون (firethumbs )‌شدیم اماایشون نیومدند!
امید وارم که مشکلشون حل شده باشه

اما با انگیزا ای مضاعف قصد دارم آموزش رو ادامه بدم

دلیل این انگیزه اینه که هر بار پروژه موفقی مثل star calender رو میبینم - به خودم میگم چرا من نباید یکی از این برنامه نویس ها باشم و در این پروژه ها یا پروژه های دیگه به دوستای عزیزم کمک کنم

چرا شما نباید یکی از این برنامه نویسا باشید!به امید روزی که تعداد برنامه نویس های ایرانی و کیفیت کارشون در لینوکس آنقدر عالی و زیاد بشه که کمبودی در این زمینه احساس نشه و نام لینوکس در سرتاسر کشور عزیزمون بپیچه (دیگه کسی نپرسه که این لینوکسی که میگین چیه؟ مثل ورد میمونه یا اینکه شبیه winrare!!!)


اگه خدا بخاد قصد دارم از این به بعد حداقل روزی یک پست (شاید ۲ تا) حتما بفرستم تا ایشالا تا یک ماه دیگه (آخر فروردین) هرکس بتونه کارای روزمره خودش رو در زمینه اسکریپت نویسی انجام بده و این اسکریپت ها یک مجموعه کامل بشه (در هر زمینه ای) ;)

exit n

این دستور باعث پایان یافتن اسکریپت با کد n میشه!
به صورت عادی اگر از این دستور استفاده نکنید پس از اجرای آخرین خط دستورات در اسکریپت - اسکریپت بسته میشه! و البته این خطو بهتر بگم مقدار این خط به عنوان خروجی استفاده میشه (return) منظور من در خطوط زیر بهتر درک خواهد شد!

اگر از دستور exit در کامند پرامپت در شل استفاده کنید باعث logout شدن شما میشه
اسکریپت هایی که موفق اجرابشن کد خروج اونها ۰ هستش (معمولا) و کد های ۱ تا ۱۲۵ برای خطا ها استفاده میشه که اسکریپت ها قادر هستند از این مقادیر برای خودشون استفاده کنند

خروج ۱۲۶ به این معنی هستش که فایل قابلیت اجرا رو نداره یا به عبارتی executeable نیست

۱۲۷ یعنی دستور پیدا نشد یا command is not found

۱۲۸ به بالا به معنی رخ دادن یک سیگنال یا event هستش

Exit Code | Description
____________________________________________________
126 | The file was not executable.
127 | A command was not found.
128 and above | A signal occurred.

استفاده از ۰ به عنوان خروج موفقیت آمیز ممکنه در مقایسه با بسیاری برنامه های C و C++ کمی غیر معمول باشه.نکته مهم اینه که در اسکریپت نویسی کد های خطای ۱ تا ۱۲۵ در اختیار ما قرار داره بدون اینکه نیازی به استفاده یا ایجاد متغیر های ارور جهانی (global error code variable) داشته باشیم

در زیر یک نمونه کد رو میبینید که خروجی موفقیت آمیز رو میفرسته در صورتی که فایلی به نام .ptofile وجود داشته باشه
#!/bin/sh
if [ -f .profile ]; then
    exit 0
fi
exit 1

خوب حالا وقت اونه که با یک مثال شاه بیت مطالب فعلی این تاپیک رو بگم
به نظرم این کد جای فکر ک دن زیادی داره
اگه کد زیر رو درک کنید و از این الگوی فشرده در کدهاتون استفاده کنید کد هایی بسیار سریع خوانا و زیبا خواهید داشت

کل کد فوق در خط زیر خلاصه شده
[ -f .profile ] && exit 0 || exit 1
چرا ؟

جواب :
دستور اول که برای چک کردن وجود یا عدم وجود فایل هست دو حالت داره
۱- موفق باشه با مقدار true
۲- ناموفق باشه با خروجی false

در حالت دوم نیازی به چک کردن دستور && نیست (به دلایلی که در پست های قبلی گفتم) ولذا مسقیم به سر دستور بعد از || میره پس خروج با کد ۱ (خطا) صورت میگیره اما در حالت اول حتما باید دستور بعد از && چک بشه و چون این دستور exit هست لذا بعد از خروج با کد ۰ (موفقیت آمیز) مجالی برای چک کردن یا نکردن ادامه اسکریپت پ درواقع کد بعد از || باقی نمیمونه

جالب بود؟ خیلی از مواقع با کمی فکر کردن میشه ده ها خط رو گاهی به چند کلمه تبدیل کرد که سرعت اجرای بسیار بالاتری هم داشته باشه

export
به صورت عادی متغیر هایی که داریم در جاهای دیگه قابل رویت و دسترسی نیستند
این دستور محیطی را با متغیر های ما ایجاد میکند که متغیر ها در اسکریپت های دیگر قابل دسترسی باشند
در واقع این دستور متغیر ها رو مجبور میکنه که مثل پارامتر های اسکریپت در ساب شل ها (subshells) در دسترس باشند

این بحث رو با دو اسکریپت export1 و export2 شرح میدم

export2
#!/bin/sh
echo “$foo”
echo “$bar”

export1
#!/bin/sh
foo=”The first meta-syntactic variable”
export bar=”The second meta-syntactic variable”
export2

همونجوری که مشاهده میکنید در خط آخر export1 اسکریپت export2 اجرا و فراخوانی شده
حالا export1 رو اجرا میکنیم
$ export1
The second meta-syntactic variable
$

جالب بود نه؟  ;D

خوب به میانه راه اسکریپت نویسی رسیدیم
به خودم و به شما تبریک میگم
فردا صبح بقیشو دنبال خواهیم کرد (expr , printf , retuen , set , shift , trap , ....)
« آخرین ویرایش: 17 شهریور 1388، 08:58 ب‌ظ توسط سید محمود رضا سجادی »
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین سید محمود رضا سجادی

  • Hero Member
  • *
  • ارسال: 704
  • جنسیت : پسر
    • مرکز برنامه نویسی ایران
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #43 : 18 شهریور 1388، 09:19 ب‌ظ »
سلام
وقتی یک متغیر رو export کنم از اون به بعد تمام اسکریپت هایی که از شل اجرا بشن و فراخوانی بشن در دسترس هستند.یعنی اگر در داخل export2 اسکریپت دیگه ای هم فراخوانی و اجرا میشد - اون اسکریپت هم به متغیر bar دسترسی داشت درست مثل export2
اگر قصد داشتید که تمام متغیر ها رو اکسپرت کنید میتونید از یکی از دو دستور زیر استفاده کنید
set -a
set -allexport

expr
این دستور با آرگومانش به صورت یک عبارت (expression) برخورد میکنه
معمولا این دستور در فرم ها و کاربرد هایی مانند زیر استفاده میشه (البته این یک مثال ساده هست)
x=`expr $x+1`دقت داشته باشید که کاراکتر استفاده شده در دو سمت عبارت بعد از مساوی back-tick هست!
این علامت باعث میشه تا x مقدار و نیجه کل عبارت داخل این علامت رو به خودش اختصاص بده
البته میشه بجای استفاده از back-tick از شکل $() استفاده کرد (که مشابه اون رو در مثال های قبلی دیدید) و با این جایگزینی به شکل زیر در میاد
x=$(expr $x+1)
این دستور خیلی قدرتمنده و بسیاری از عبارات را ارزیابی و تفسیر میکنه
قواعد اصلی و کی رو در جدول زیر آوردم
Expression Evaluation | Description
___________________________________________________________________________________
expr1 | expr2 | expr1 if expr1 is nonzero, otherwise expr2
expr1 & expr2 | Zero if either expression is zero, otherwise expr1
expr1 = expr2 | Equal
expr1 > expr2 | Greater than
expr1 >= expr2 | Greater than or equal to
expr1 < expr2 | Less than
expr1 <= expr2 | Less than or equal to
expr1 != expr2 | Not equal
expr1 + expr2 | Addition
expr1 - expr2 | Subtraction
expr1 * expr2 | Multiplication
expr1 / expr2 | Integer division
expr1 % expr2 | Integer modulo

در اسکریپت های جدید تر معمولا دستور expr با علامت $((...)) جایگزین میشه  ;)
این علامت رو قبلا در مثال ها دیده بودید. اینم معنیش  ;D
البته بحث کاملتر در باره این علامت رو به آینده نه چندان دور میسپارم

printf
این دستور تنها در شل های نسبتا جدید وجود داره
متن زیر رو تنها یک نقل قوله :
نقل‌قول
                                                   X/Open suggests that we should use it in
preference to echo for generating formatted output.

فرمت این دستور :
printf “format string” parameter1 parameter2 ...
format string خیلی برای برنامه نویسان C و C++ آشناست البته با چند محدودیت و تغییر کوچک
floting point پشتیبانی نمیشه!
دلیل ایم امر هم واضحه چون تمام مقادیر عددی داخل شل به عنوان اینتیجر (اعداد حسابی) عمل میکنن
Escape Sequence | Description
__________________________________________________________________
\\ | Backslash character
\a | Alert (ring the bell or beep)
\b | Backspace character
\f | Form feed character
\n | Newline character
\r | Carriage return
\t | Tab character
\v | Vertical tab character
\ooo | The single character with octal value ooo

مبدل های تسریح (conversion specifier) کمی پیچیده هستند و لذا در جدول زیر تنها انواع معمول و پر کاربرد اونها رو خواهم آورد
موبدل های تسریح همگی شامل کاراکتر % میشن. برای اطلاعات بیشتر به منوال آنلاین بش bash online manual مراجعه کنید
Conversion Specifier | Description
________________________________________________________
d | Output a decimal number.
c | Output a character.
s | Output a string.
% | Output the % character.

format string برای تفسیر پارامتر های باقی مانده و فرمت کردن خروجی استفاده میشه بهمثال زیر توجه کنید
printf "%s\n" hello
hello
printf "%s %d\t%s" "Hi There" 15 People
Hi There 15 people

 در آخر لازم به استفاده از " در مثال آخر توجهتون رو جلب کنم که وجود اون لازمه تا عبارت Hi There به عنوان یک آرگومان عمل کنه و تفسیر بشه

return
با این دستور قبلا آشنا شدیم و بعدا هم بیشتر در باره اون صحبت خواهیم کرد
دستور آسونیه و توضیح زیادی نداره
این دستور خروجی یک تابع یا اسکریپت رو مشخص میکنه که این دستور به عنوان آرگومان تنها میتونه یک مقدار عددی داشته باشه و مقدار خروجی تابع با این دستور تنها در جایی که این تابع رو صدا زدیم قابل دسترسی هست.
اگه از این دستور استفاده نکنیم خروجی اسکریپت مقدار خروجی آخرین دستور اجرا شده در اسکریپت خواهد بود!
« آخرین ویرایش: 18 شهریور 1388، 09:30 ب‌ظ توسط سید محمود رضا سجادی »
مرکز برنامه نویسی ایران
محلی برای تمامی علاقه مندان به برنامه نویسی http://www.SourceCenter.IR

آفلاین HamidTB

  • Hero Member
  • *
  • ارسال: 897
  • جنسیت : پسر
    • دست نوشته هاي يه لينوكسي
پاسخ به: شروع برنامه نویسی در لینوکس
« پاسخ #44 : 19 شهریور 1388، 12:32 ب‌ظ »
سلام
من دستور if شما رو عینا کپی کردم ولی چرا

#!/bin/sh

echo "Is it morning? Please answer yes or no"
read timeofday

if [$timeofday = "yes" ]; then
   echo "Good morning"
else
   echo "Good afternoon"
fi

exit 0

hamid@hamid-desktop:~/Desktop/Learn$ /bin/sh First
Is it morning? Please answer yes or no
yes
First: 10: [yes: not found
Good afternoon
زندگی : یه بازی بزرگ که توی این بازی فقط یه جون داری , هیچ جاشو نمیشه ذخیره کرد و جایی برای اشتباه نیست !!!