رفتن به نوشته‌ها

ماه: سپتامبر 2015

کمی shell Script

یکی از راه‌های خوب برای یاد گرفتن یک چیز جدید ( صرف نظر از ماهیت اون چیز ) استفاده از تجربه بقیه و نگاه کردن به کاری هست که قبلا انجام شده، در برنامه نویسی این روش به شکل شدیدتری قابلیت‌های خودش را نشان میدهد، گفته میشود یکی از بهترین روش‌های یاد گرفتن تفکر سیستماتیک و متدهای برنامه نویسی دیدن کدهای خوب و تکرار کدها است . یعنی برنامه را تحلیل کنیم و دوباره بنویسیم. و چیزی که این روز‌ها خیلی پیدا میشود، کدهایی هستند که با زبانهای مختلف نوشته شده‌اند.
من بدلایلی در نظر دارم درباره برنامه‌نویسی در Bash لینوکس کمی صحبت کنم، نه با این عنوان که در برنامه نویسی Shell Script استاد هستم، به هیچ وجه! تنها بدلیل اشتراک گذاری مطالبی که در ادامه می‌آید با دوستانم .
من فرض می‌کنم که خواننده با دستورات ترمینال آشنایی داشته و می‌تواند دستورات را بصورت تکی یا ترکیبی استفاده کند، این مقاله درباره روش نوشتن یک Shell Script و تشریح دستورات کنترلی در Shell Script می‌باشد.
برای اجرای کارها در ترمینال لینوکس از دستورات Shell استفاده می‌شود، در صورتیکه نیاز به اجرای یک عمل روتین یا یک کار تکراری یا یک مجموعه کار پشت سرهم داشته باشیم، یکی از راه حل‌ها برنامه نویسی و یک از ساده‌ترین، قدرتمندترین و در دسترس‌ترین محیط‌ها برای نوشتن یک برنامه در لینوکس استفاده از Shell لینوکس و نوشتن یک Shell Script است. یک Shell Script از مجموعه دستورات Bash (یا هر Shell دیگه ) به همراه توضیحات (Comments) و دستورات کنترلی استفاده می‌کند. یک Shell Script با فرمت sh. ذخیره می‌شود، و با نوشتن دستور

sh foo.sh

اجرا می‌شود. در صورتیکه به Shell Script مجوز اجرایی بدهیم:

chmod +x foo.sh

به راحتی بصورت زیر قابلیت اجرا پیدا میکند:

./foo.sh

در صورتیکه در خط اول از Shebang استفاده کنیم و آدرس مفسر فایل اسکریپت را اعلام کنیم ( همانند روشی که در فایل‌های py. استفاده میشود)،Shell Script ما قابلیت اجرایی خواهد یافت، ابتدا با دستور زیر محل قرارگیری مفسر (Bash) را پیدا میکنیم:

which bash

که احتمالا چیزی شبیه به این خواهد بود:

/usr/bin/bash

سپس این خط را به ابتدای اسکریپت خود اضافه می‌کنیم:

#!/usr/bin/bash

و ادامه برنامه را می‌نویسیم.
مرسوم شده که هر زبان برنامه نویسی جدید با برنامه !Hello World شروع بشود، اما من با این برنامه شروع نمیکنم و فقط تعدادی از دستورات کنترلی را در قالب برنامه‌های ساده مرور می‌کنم.
for LOOP
حلقه کنترلی for برای انجام یک ( مجموعه ) عمل به تعداد مشخص بکار می‌رود، مثلا ما نیاز داریم یک کار را ۱۰ بار تکرار کنیم، یا یک تعداد از دستورات را به تعدادی که کاربر مشخص کرده است انجام دهیم. یا تعداد فایل‌های یک دایرکتوری را شمارش کرده و به تعداد آنها یک عمل را تکرار کنیم . در این‌صورت استفاده از حلقه for ناگزیر خواهد بود :
for … in
برنامه زیر ۴ بار کد بین do و done را اجرا میکند .

for i in 1 2 3 4
    do
        echo "Number $i"
    done

((for ((exp1, exp2, exp3
همان کد بالا با قالب ((for ((exp1, exp2, exp3

for (( i=1; i<=4; i++))
    do
        echo "Number $i"
    done

خروجی کدهای بالا بعد از اجرای اسکریپت:

Number 1
Number 2
Number 3
Number 4

برنامه نمایش اعداد بر روی کنسول

#!/bin/bash
for i in {1..25}
do
    echo $i
done

یا :

#!/bin/bash
for ((i=1;i<=25;i+=1)
do
    echo $i
done

برنامه شمارش اعداد با step برابر با ۵ :

#!/bin/bash
for i in {0..25..5}
do
    echo $i
done

برنامه شمارش معکوس از عدد ۲۵ تا ۱ با step برابر با ۵- :

#!/bin/bash
for i {25..0..-5}
do
    echo $i
done

یک کاربرد جالب و خوب دستور for، قابلیت کارکردن با فایل‌های خاص است، به عنوان مثال کد زیر تمام فایل‌هایی که فرمت sh. دارند را نمایش میدهد:

for file in ~/*.sh
do
    echo $file
done

برای استفاده از شرط باید ابزار لازم برای چک کردن شرط را داشته باشیم، مثلا عملگرهای مقایسه‌ای،(==،<،>،=! و …) برای مقایسه ۲ پارامتر با هم مناسب هستند. برای آشنایی با عملگر ها اینجا و اینجا مطالب خوبی را ارائه کرده است.

برای دریافت داده توسط کاربر از دستور read استفاده میشود، مثلا

read  word

یک ورودی از کاربر دریافت کرده و در متغیر word قرار می‌دهد. برای دسترسی به محتویات word میتوان از دستور

echo $word

استفاده کرد، در نوع داده محدودیتی وجود ندارد، داده میتواند یک عدد، یک رشته یا یک آرایه باشد. در صورتیکه نیاز به کار با آرایه دارید، میتوانید از سوئیچ a- به‌همراه دستور read برای گرفتن مقادیر آرایه از کاربر استفاده کنید. همچنین دستور declare میتواند برای تعریف یک متغیر بکار رود . در صورتیکه این دستور به همراه سوئیچ a- بکار برده شود برای تعریف یک آرایه استفاده می‌شود.
برای دسترسی به المانهای مختلف یک آرایه بصورت زیر عمل میکنیم:

read -a colors
echo "colors : ${colors[0]} , ${colors[1]} , ${colors[2]}"

برای ساخت یک حلقه از دستورات until و while نیز میتوان استفاده کرد .

#!/bin/bash
COUNT=0
# bash until loop
until [ $COUNT -gt 5 ]; do
        echo Value of count is: $COUNT
        let COUNT=COUNT+1
done
!/bin/bash
COUNT=6
bash while loop
while [ $COUNT -gt 0 ]; do
     echo Value of count is: $COUNT
     let COUNT=COUNT-1
 done

برای استفاده از کاراکترهای خاص مثل $ باید این کاراکترها را بین ‘ ‘ قرار داد، برای استفاده از کاراکتر ‘ از ‘\ استفاده میشود.
همچنین کارایی کاراکتر ” نیز مانند ‘ است .

خب ! این پست خیلی کوتاه ( نسبت به مطالب گفته نشده ) تمام شد، بهترین کار آزمایش کدهای ساده بالا و ترکیب این برنامه‌ها با دستورات جدید و ساخت برنامه‌های جدید است.
از ترمینال نترسید. توانایی و قدرتی که ترمینال به کاربر لینوکس میده بی نظیر و شگفت آوره . نوشتن این آموزش توی برنامه ام نبود، چون میدونستم مطالب نگفته‌ی زیادی باقی میمونه . اما به دلایلی برای آشنایی دوستان این رو نوشتم . امیدوارم کمی در پیدا کردن یک دیدگاه مثبت و یک درک صحیح به Shell Script کمک کنه .
برای خوندن مطالب همین مطالب البته کاملتر به linuxconfig یک سر بزنید .( بعضی کد ها از این سایت برداشت شده بودند)،
سایت TutorialsPoint مطالب خوبی در همه زمینه ها و از جمله Shell Scripting داره.
در این سایت هم درس‌های ابتدایی برای شروع هست .

خارج شدن از نظر

گذری بر ساخت یک سیستم لینوکس از ابتدا

به در خواست بعضی از دوستانم مرور کلی در روش ساخت یک سیستم عامل گنو لینوکس از پایه به وسیله کامپایل برنامه ها و تنظیم کرنل خواهم داشت . در این نوشته قرار نیست وارد ریز جزئیات و مرور دستورات با تمام پسوندها و سوئیچ ها بشوم . تنها کلیتی از روند انجام کار و ساخت یک گنو/لینوکس از پایه شرح داده میشود . برای اطلاع دقیق از ریزه کاری ها و دستورات لطفا به کتاب LFS در انتهای این پست مراجعه کنید .
شاید وسوسه کامپایل بسته ها و کرنل و ساخت یک لینوکس از پایه همواره همراه یک کاربر لینوکس باشد و اگر کاربر کمی روحیات «گیک» ی هم داشته باشد وضع به مراتب بدتر خواهد بود .یکی از این گیک ها فردی به نام Gerard Beekmans بوده که در سال ۱۹۹۸ تصمیم به ساخت یک توزیع با جمع آوری بسته های اساسی برای ساخت سیستم عامل و کرنل لینوکس میکند . حاصل تجربیات کار «جرارد » در کتابی تحت عنوان Linux From Scratch جمع آوری شده و به LFS مشهور می‌شود .
من فرض میکنم که مایل به ساخت سیستم عامل با آخرین نسخه از برنامه‌ها و کرنل هستیم . و از نسخه جاری دستورالعمل ساخت به همراه آخرین نسخه ازبرنامه‌ها استفاده می‌کنم . درصورتیکه به داشتن یک نسخه پایدار علاقمندید میتوانید از نسخه پایدار هربرنامه به همراه کرنل پایدار استفاده کنید . در کلیت کار تفاوت عمده‌ای ایجاد نخواد شد .
ابتدا بسته‌های برنامه های مورد نیاز را از آدرس‌های آن‌ها دریافت می‌کنیم. در این آدرس اسم برنامه‌ها به همراه لینک دریافت آخرین نسخه قرار داده شده است .همچنین بعضی ازبرنامه‌ها دارای مشکلاتی هستند که باید فایل‌های Patch این برنامه‌ها را نیز از اینجا دریافت کنیم .
برای ساخت یک لینوکس جدید قائدتا احتیاج به یک فضای کافی بر روی دیسک سخت سیستم داریم ، در کتاب LFS حداقل فضایی به اندازه ۴ گیگابایت برای بسته‌های سورس و فایل‌های کامپایل شده درنظر گرفته شده است . اما فضای ۱۰ گیگابایتی در آینده منجر به کمبود فضا در پارتیشن tmp/ نخواهد شد . من برای این منظور از یک پارتیشن۲۰ گیگابایتی استفاده کردم .همچنین همانند باقی توزیع‌ها فضایی برای home/ و باقی پارتیشن ها مورد نیاز است ( من پارتیشن مجزایی در نظر نگرفتم . این یک مسئله سلیقه ای است و میتوان home/ را بدون درنظر گرفتن پارتیشن مجزا رها کرد تا در / فضایی به آن تعلق بگیرد .) اگر این توزیع در آینده به منظور سیستم عامل اصلی شما خواهد بود یک فضای ۳۰-۵۰ گیگابایتی نیز برای پارتیشن src/ در‌نظر بگیرید .در پارتیشن src/ برنامه‌های شما نصب خواهند شد .
بعد از در نظر گرفتن فضا با هر یک از فرمت‌های رایج ext2 ,ext3,ext4 میتوان این فضا را فرمت کرد ، و در انتها پارتیشن جدید را به mnt/ سوار -mount- کرد . در این مرحله پکیج‌هایی که گرفته ایم در پارتیشن جدید قرار داده و آماده کامپایل بسته‌ها می‌شویم . برای اینکه محل بسته‌ها و سیستم جدیدی که میسازیم از هم تشخیص داده شوند ، تمام بسته‌ها به همراه فایل ها پچ در پارتیشن مجزای source/ قرار گرفته و تمام برنامه‌های کامپایل شده در tools/ قرارمیگیرند .( توسط سوئیچ‌های gcc می‌توان محل نصب بسته‌ها را تعیین کرد که در مستندات کتاب به تفصیل توضیح داده شده است ) .
برای کامپایل بسته‌ها ، ابتدا اقدام به کامپایل برنامه‌های کامپایلر gcc و لینکر (Binutils) و همچنین Linux API Headers و کتابخانه‌های Glibc و ++Libstdc می‌نمائیم . بسته‌های فوق را ابتدا توسط کامپایلر سیستم میزبان کامپایل می‌کنیم .سپس با استفاده از این برنامه‌هادوباره همین بسته‌ها را برای بار دوم کامپایل کرده (با پارامترهای متفاوت در قسمت Config ) و در ادامه باقی بسته‌ها را کامپایل می‌نمائیم . برای کامپایل هر بسته ابتدا بسته را از حالت فشرده خارج می‌کنیم . سپس در آدرس فولدر ساخته شده دستورات را وارد کرده و بعد از نصب بسته‌ها فولدر ساخته شده را پاک حذف می‌کنیم . سورس پکیج‌ها در پوشه sources/ باقی می‌ماند .
بعد از کامپایل سورس‌ها و نصب تمام بسته‌های سیستم پایه ، شروع به ساخت سیستم عامل جدید می‌کنیم . ابتدا پارتیشن‌های ضروری سیستم‌عامل ( مثل dev,proc,sys,run ) را می‌سازیم سپس Node هایی برای اتصال Devise های مختلف سیستم ایجاد می‌کنیم .و پارتیشن‌های مرتبط با فایل سیستم لینوکس را Mount می‌کنیم . در نهایت با استفاده از دستور chroot وارد سیستم جدید که بنا کردیم می‌شویم و در لینوکس جدید کار را ادامه می‌دهیم .
در ابتدا دایرکتوری‌ها و زیر دایرکتوری‌ها و فولدرهای اساسی موردنیاز سیستم را می‌سازیم .فایل‌ها و لینک‌ها را می‌سازیم و همچنین گروه‌ها را تعریف می‌کنیم.سپس نصب برنامه‌ها و پکیج‌ها در لینوکس جدید را با نصب Linux API Headers شروع می‌کنیم . یک به یک پکیج‌ها را ابتدا از حالت فشرده خارج کرده و سپس وارد فولدر ایجاد شده می‌شویم و برنامه را کامپایل و نصب کرده و در انتها فولدر را پاک می‌کنیم .
پس از کامپایل آخرین بسته ( یعنی برنامه vim ) در صورتیکه به فایل‌های Symbol برنامه‌های نصب شده نیازی نداریم میتوانیم آنها را پاک کنیم . در این صورت حجم برنامه‌های نصب شده به ۹۰ مگابایت کاهش پیدا می‌کند . در صورتیکه علاقمند به دیباگ و توسعه سیستم هستید بهتر است این فایل‌ها را نگهداری کنید .
همچنین فایل‌های اضافه ای که حین کامپایل ساخته می‌شوند نیز میتوان حذف کرد (بخش ۶٫۷۲ کتاب LFS )

خب ! ساخت سیستم به اتمام رسید . حالا باید سیستم ساخته شده را تنظیم کنید . تنظیماتی مثل نحوه اتصال به شبکه ، زبان و کیبورد و تنظیم ساعت سیستم ، Shell پیش‌فرض سیستم و تنظیمات مربوط به systemd در این مرحله صورت می‌پذیرد . پس از تنظیم سیستم جدید ، ابتدا فایل fstab را ایجاد و تنظیم می‌کنیم ، سپس کرنل (لینوکس) را کامپایل می‌کنیم . برای کامپایل لینوکس میتوان از make oldconfig استفاده کرد و تنظیمات و ماژول‌های مورد نیاز سیستم خود را بصورت سوال و جواب در یک فایل تنظیم کرد . در انتها این فایل قابلیت ویرایش داشته و در صورتیکه در محلی اشتباهی رخ داده باشد می‌توان به راحتی آن را اصلاح کرد .
پس از نصب کرنل در صورت تمایل می‌توانید گراب را نصب کنید و در غیر این صورت گراب سیستم میزبان را آپدیت کرده تا سیستم LFS جدید را شناسایی کند . در انتها از سیستم جدید خارج شده و پارتیشن‌ها را یک به یک Unmount میکنیم و سیستم را ریبوت می‌کنیم . در صورتیکه کرنل بدرستی تنظیم شده باشد میتوانید به سیستم LFS خود وارد شوید .

برای خواندن جزئیات و نحوه کار به کتاب LFS که در سایت Linux from Scratch قرار دارد مراجعه کنید .

خارج شدن از نظر