لينوكس براي همه - كوتاه از لينوكس
لينوكس براي همه
پايپها و انتقال
پيش از آنكه در اين شماره بهطور جدي وارد مبحث برنامهنويسي در پوسته( shell ) شويم، بهتر است ابتدا با شيوههاي انتقال ورودي و خروجي آشنا شويم.
انتقال خروجي
ممكن است تا كنون به چنين دستوري برخورده باشيد:
ls -l > lsoutput.txt$
اين دستور، خروجي دستور ls را داخل فايلي بهنام lsoutput.txt ميريزد. با عملگر> تقريبا همه خروجيها را ميتوان منتقل كرد. و اگر فايل مقصد از قبل وجود داشته باشد، در اين صورت فايل جديد جايگزين آن خواهد شد. براي اينكه خروجي را به انتهاي فايل اضافه كنيم، اما فايل قبلي پاك نشود، از عملگر> استفاده كنيد:
$ls << lsoutput.txt
اين دستور، نتيجه را به انتهاي فايل قبلي اضافه خواهد كرد.
انتقال ورودي
درست مانند انتقال خروجي دستورات، ميتوان وروديها را هم منتقل كرد و از ورودي استاندارد استفاده نكرد. براي نمونه:
more > lsoutput.txt$
البته اين مثال، بسيار جزيي و اندك بود و انتقال جريان ورودي و خروجي نسبت به ويندوز، ابعاد بسيار گستردهتري دارد.
پايپها
ميتوانيد پروسسها را با عملگر پايپ (1) بههمديگر وصل كنيد. برخلاف سيستم عامل داس، در لينوكس ميتوان بهكمك پايپها، پروسسها را همزمان با هم اجرا كرد و بهطور خودكار با انتقال جريان داده در ميان آنها، زمانبندي كرد. يك مثال ساده: ميتوانيد بهسادگي خروجي حاصل از دستور ps را بهدستور sort بدهيد. اگر از پايپها استفاده نكنيد، دستور چند گام به درازا خواهد كشيد:
ps < psout.txt$
<$sort psout.txt pssort.out
حالا راه بهتر و تر و تميزتر اين است كه اين دو پروسس را با يك پايپ به هم وصل كنيم:
ps1 sort < pssort.out$
لابد ميخواهيد خروجي كار هم، صفحهبندي شده باشد، پس حتما از دستور سومي استفاده خواهيد كرد بهنام more و آن را با پايپ به دو دستور قبلي وصل ميكنيد:
$ps1 sort 1 more
در عمل هيچ محدوديتي براي تعداد پروسسهايي كه بههم وصل ميشوند، وجود ندارد. فرض بگيريم كه ميخواهيد نام تمام پروسسهايي كه در حال اجرا هستند بهجز پوسته را ببينيد. اين خط دستور را نگاه كنيد:
$ps-xo comm1 sort 1 uniq
grep -v sh1 more
اين دستور چه كار ميكند؟
خروجيps را ميگيرد، به ترتيب الفبا مرتب ميكند، پروسسها را با استفاده ازuniq استخراج ميكند، با استفاده از grep -v sh پروسسي كه اسمش sh است را حذف ميكند و دست آخر بهصورت صفحهبندي شده به خروجي (نمايشگر) ميفرستد. اين روش، همانطور كه شما هم ميبينيد، عجب روشتر و تميزي است براي پيوندانيدن چند دستور بههمديگر! تازه بدون اينكه به دردسر بيافتيم و فايلهاي موقت ايجاد بكنيم! هرچند، حسابي مراقب يك چيز باشيد: اگر رشتهاي از دستورها داشتيد و قرار بود خروجي را به يك فايل بفرستيد، هيچ وقت از يك نام فايل دوبار در رشته دستوري استفاده نكنيد. براي مثال اگر چنين دستوري بنويسيد:
cat mydata.txt 1 sort 1 uniq < mydata.txt$
در اينصورت با يك فايل خالي مواجه خواهيد شد، چون پيش از اينكه بخواهيد فايلmydata.txt را بخوانيد، آن را بازنويسي كردهايد.
پوسته يا يك زبان برنامهنويسي
حالا كه ديگر برخي از عمليات پايه پوسته را ياد گرفتيم، وقت آن رسيده است كه سراغ برنامههاي واقعي پوسته برويم. دو راه براي نوشتن برنامههاي پوسته وجود دارد. ميتوانيد رشتهاي از دستورات را بنويسيد و به پوسته اجازه بدهيد كه آنها را تكتك اجرا كند، يا دستورات را داخل فايل بريزيد و بعد بهعنوان برنامه از آن استفاده كنيد.
برنامههاي تعاملي
(Interactive Programs)
نوشتن و اجرا كردن دستورها، يكي از راههاي سريع و آسان آزمايش تكههاي كوچك كد است، براي يادگرفتن مناسب. فرض بگيريد تعداد زيادي فايلC داريد و ميخواهيد فايلهايي كه شامل رشتهPOSIX هستند را شناسايي كنيد، بهجاي اينكه تكتك و از طريق دستور grep بخواهيم اين كار را انجام دهيم، ميتوانيم همه اينكارها را داخل اسكريپتي تعاملي بنويسيم، اين پايين را نگاه كنيد:
for file in *$
do <
if grep -l POSIX $file<
then<
more $file<
fi<
done<
نگاه كنيد كه چقدر طبيعي $ برنامه پوسته به < تبديل ميشود و پوسته منتظر اطلاعات بعدي است. ميتوانيد تايپ كردن را بس كنيد و به پوسته اجازه بدهيد خودش تصميم بگيرد كه شما كارتان تمام شده است و بعد اسكريپت فورا اجرا ميشود. پوسته همچنين ازWildcard expansionها نيز پشتيباني ميكند. ديگر قريب بهيقين شما ميدانيد كه * يعنيWildcard براي همه كاراكترها. ممكن است اين را ندانيد كه براي يك حرف نيزWildcard بهنام داريم، همچنين]set[ مجموعهاي از كاراكترها را در خود ميگيرد كه قرار است چك شوند. برعكس آن اگر 8 بيايد، مثل]set[ در اين صورت، هر چيزي را شامل ميشود جز آنهايي كه داخل براكتاند. نشان آكولاد ت ت هم به شما اجازه ميدهد تا چند رشته را در مجموعهاي كنار هم قرار دهيد تا كار خاصي انجام بدهيد:
ls my- تfinger, toeتs$
اين دستور فايلهاي myfingers و mytoes را ليست ميكند. اين دستور از پوسته استفاده ميكند تا هر فايلي كه داخل دايركتوري فعلي است را بررسي كند.
ساختن يك اسكريپت
با هر ويرايشگر متني كه ميلتان ميكشد، ميتوانيد فايلي شامل دستورات بسازيد، فايلي بسازيد بهنام first كه شبيه مثال زير باشد:
/bin/shَ#
firstَ#
This file looks throughَ#
all the files in the current
directory for the string POSIX,َ#
and then prints the names of
those files to the standard output.َ#
for file in *
do
file$if grep -q POSIX
then
file$echo
fi
done
0exit
توضيحات(comment) ها با نماد آغاز ميشوند و تا پايان خط بهعنوان توضيح بهحساب ميآيند؛ هر چند عرف است كه در ستون اول هميشه بگذارند. حال در خط بعدي به دستور َbin/sh/! بر ميخوريم كه فرم خاصي از توضيح است. كاراكترهاي َ به سيستم ميگويند كه آرگومانهايي كه در ادامه ميآيند، برنامهاي است كه براي اجراي اين فايل بايد دنبال شودbin/sh/ . برنامه پوسته پيشفرض است.
نكته: مسير پس از َ مسير قطعي(Absolute) است. با هم توافق كردهاند كه اين رشته را از 32 كاراكتر كمتر نگهدارند تا با سيستمهاي قديميتر همخوان باشد، چون برخي از يونيكسهاي قديمي از تعداد محدودي از كاراكترهايي كه بعد از ! ميآيند، بهره ميبردند. واضح است كه لينوكسهاي امروزي ديگر اين محدوديت را ندارند. از آنجايي كه اسكريپت وارده، بهعنوان ورودي استانداردي در پوسته مطرح است. در اين صورت ميتواند شامل هر دستوري باشد كه متغير محيطي PATH شما مسير آن را در خود دارد.
دستورexit در انتهاي اسكريپت اطمينان ميدهد كه اسكريپت با كد خروجي مطمئن كنترل اجراي دستورات را به سيستم عامل بر ميگرداند. هرچند كه بهندرت چنين چيزي چك ميشود، اما ميشود فهميد كه آيا اسكريپت با موفقيت اجرا شده است يا خير. در اين صورت ميتوان با اطمينان از اين اسكريپت در اسكريپت يا دستوري ديگر استفاده كرد و از صحت اجراي آن اطمينان حاصل كرد. حتا اگر نخواهيد اسكريپتتان را بقيه اجرا كنند، باز هم در انتهاي اسكريپت اين كد را بگذاريد كه كاري منطقي است. به كاربردي بودن اسكريپت خود اعتقاد داشته باشيد. فرض بگيريد كه شايد، يك در يك ميليون قرار باشد بهعنوان بخشي از اسكريپتي ديگر بهكار گرفته شود.
نكته: عدد صفر نشانگر خروج موفقيتآميز است.
اجرايي كردن يك اسكريپت
حالا فايل اسكريپتمان را ساختيم، ميتوانيم به دو صورت آن را اجرا كنيم. راه سادهتر اين است كه اسم فايل را به پوسته بدهيم.
/bin/sh first $
اين دستور بايد عمل كند، اما چقدر خوب ميشود كه اسكريپت را فقط با صدا كردن نامش استفاده كنيم و از اينbin/sh/ خلاص شويم. اين كار را با تغيير حالت فايل (chmod) بهسادگي ميتوان انجام داد:
$chmod+xfirst
اين دستور، فايل first را با +x اجرايي ميكند. و پس از اين، تنها كافي است با دستور زير اسكريپت را اجرا كنيد:
$first
اگر پيغامي گرفتيد كه "چنين دستوري يافت نشد!" متغير محيطي PATH احتمالا به مسير فايلهاي اسكريپت شما اشاره نميكند. براي رفع اين مشكل، يا تايپ كنيدPATH=$PATH: يا فايل bash-profile را ويرايش كنيد و اين دستور را به انتهاي آن بيفزاييد. سپس يك بارlog out كنيد و دوباره به سيستم برگرديد. اين هم نشد،first/. را در دايركتورياي كه اسكريپت داخلش است، بنويسيد تا مسير كامل نسبي به اسكريپت را به فايل بدهيد.
استفاده از ./ يك سود ديگر هم دارد، آن اين است كه شما تصادفا دستور ديگري با اين نام را اجرا نخواهيد كرد. اگر ديديد كه اسكريپت شما با موفقيت اجرا شد، ميتوانيد به جاي مطمئني منتقلش كنيد، اگر از اين دستور فقط خودتان استفاده ميكنيد، ميتوانيد يك دايركتوري bin در فولدر home خود بسازيد و مسيرش را بهPATH اضافه كنيد. اگر ميخواهيد بقيه كاربران هم از آن استفاده كنند، آن را داخل فولدرusr/local/bin/ قرار دهيد. اگر دسترسيRoot نداريد، بايد از سرپرست سيستم درخواست كنيد اين كار را براي شما انجام دهد. اگر هم مايل نيستيد كه كسي آن را تغيير دهد، ميتوانيد دسترسي نوشتن در آن فايل را برداريد. دستوراتي كه سرپرست سيستم طي آن مالكيت و دسترسيهاي نرمافزار را مشخص ميكند، چيزي شبيه اين خواهد بود:
cp first /usr/local/binَ#
chown root /usr/local/bin/firstَ#
chgrp root /usr/local/bin/firstَ#
َchmod557 /usr/local/bin/first #
توجه داشته باشيد كه از شكل كلي دستور chmod استفاده كرديم، چون دقيقا ميدانستيم كه چه سطح دسترسياي ميخواهيم بدهيم. اما شما ميتوانيد از شكل طولانيتر، اما شايد واضحتر دستور chmod استفاده كنيد:
َchmod u=rwx,go=rx /usr/local/bin/first #
براي اطلاعات بيشتر از راهنماي دستور chmod استفاده كنيدman chmod :
محمدرضا قرباني
كليك جام جم