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

برچسب: Linux

virtualenv چرا و چگونه ؟

برای ساخت یک محیط ایزوله و جدا برای پروژه ی در دست ساخت در زبان پایتون از virtualenv استفاده میکنیم. دلیل این امر عدم تاثیر پذیری پایتون و ماژولها و کتابخانه های نصب شده از تغییرات در سیستم و انتخاب نسخه مورد نظر ما برای پایتون و پکیج های آن است. بعنوان مثال مسیر نصب در pip یک مسیر مشخص است که هر کتابخانه و ماژول جدید در این مسیر نصب میشود و به مرور زمان با نصب کتابخانه‌های جدیدتر ممکن است بعضی پکیج ها دچار تغییراتی شوند که در کار توسعه پروژه فعلی ما ایجاد اختلال کنند. به همین منظور استفاده از محیط ایزوله برای جداسازی پایتون و ماژولهای مورد نیاز از مسیر سیستم کاملا معقول و لازم است . با استفاده از پکیج virtualenv میتوان یک محیط ایزوله برای این منظور ساخت :

sudo apt-get update
sudo apt-get install build-essential libssl-dev libffi-dev python-dev
sudo apt install python3-pip
sudo pip3 instal virtualenv

بعد از نصب virtualenv در مسیر پروژه یک محیط ایزوله بصورت زیر میسازیم:

$cd new-project
virtualenv -p python3 env

در صورتیکه برروی سیستم خود نسخه های متفاوتی از پایتون نصب شده باشد، با استفاده از سوئیچ زیر میتوان نسخه متفاوتی از پایتون سیستم مادر را در virtualenv نصب کرد:

virtualenv -p python3 env --python="pythonx.y"

که pythonx.y پایتون نسخه x.y میباشد، مثلا پایتون نسخه ۳.۶ یا ۲.۷ یا …

در مسیر new-project در فولدر env یک پایتون جدید برپا میکند.برای فعال سازی پایتون جدید باید به مسیر زیر رفته و آن را فعال کنیم:

$cd env/bin
$source activate

بعد از این عمل اعلان ترمینال تغییر کرده و نام محیط ایزوله قبل از مسیر جاری قرار میگیرد:

ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$ source activate
(env) ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$

برای اطمینان از نصب صحیح میتوانیم نسخه پایتون مورد استفاده را بدست بیاوریم :

$python --version
Python 3.7.5

$which python
/home/ali/Documents/ML/virtualEnv/env/bin/python3

بعد از نوشتن کد مورد نظر و اتمام کار با استفاده از دستور deactivate از محیط virtual environment خارج میشویم .اعلان (env) نیز پاک خواهد شد:

ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$ source activate
(env) ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$ which python3
/home/ali/Documents/ML/virtualEnv/env/bin/python3
(env) ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$ deactivate 
ali@ali-pc:~/Documents/ML/virtualEnv/env/bin$ which python3
/usr/bin/python3

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

دوره Raspberry pi

ویرایش بهار ۹۹:

قبلا چند مطلب درباره Raspberry PI در سایت نوشته بودم،بعد از راه اندازی مجدد سایت و آپلود مطالب قبلی تصمیم گرفتم مطالب قبلی در قالب یک پست انتشار داده شود . با توجه به تصمیمم برای ضبط دوره آموزشی RPI مطالب جدید و ویدیو های جدید نیز به تدریج اضافه خواهند شد.

فعال سازی SSH بصورت پیش فرض در رزبری‌پای:

در حالت عادی SSH در سیستم عامل رزبیان فعال نیست و باید ابتدا برد رزبری‌پای را به یک مانیتور وصل کنید و با استفاده از کیبور و موس USB سیستم را بوت کرده و با دستور raspi-config اقدام به فعال کردن SSH کنید. برای دور زدن این مراحل میتوانید بعد از عملیان رایت ایمیج بر روی SD-card به پارتیشن /etc/ بروید و فایل rc.local را به صورت زیر ویرایش کنید:
در بالای خط انتهایی (یعنی exit 0) دستور زیر را وارد کنید تا در هر بار روشن شدن برد رزبری‌پای ، SSH هم روشن شود:

systemctl start ssh #run SSH on each startup

wifi در RaspberryPi3:

نسخه سوم برد RPi علاوه برا ارتقاء سخت افزاری قابل توجه, به امکانات ارتباطی وای فای و بلوتوث هم مجهز شده که در نظر دارم وای فای رو راه اندازی کنم و به صورت بی سیم با برد ارتباط SSH برقرار کنم .
مراحل کار ساده و سر راست هستند, پیدا کردن شبکه, ویرایش یک فایل حاوی اسم شبکه و رمز عبور و در انتها هم راه اندازی مجدد برد RPi .
در ابتدا برای پیدا کردن شبکه های بی سیم از دستور زیر استفاده میکنیم:

sudo iwlist wlan0 scan

اطلاعات مختلفی از شبکه های وای فای اطراف با ریز جزئیات برای شما به نمایش گذاشته خواهد شد, در میان شبکه های مختلف به دنبال کلمه ESSID باشید . نام شبکه جلوی این کلمه درج خواهد شد , مثلا:

pi@raspberrypi:~ $ sudo iwlist wlan0 scan
wlan0     Scan completed :
          Cell 01 - Address: 10:10:10:10:10:10
                    Channel:1
                    Frequency:2.412 GHz (Channel 1)
                    Quality=26/70  Signal level=-84 dBm
                    Encryption key:on
                    ESSID:"mohamad"
                    Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 18 Mb/s
                              ۲۴ Mb/s; 36 Mb/s; 54 Mb/s
                    Bit Rates:6 Mb/s; 9 Mb/s; 12 Mb/s; 48 Mb/s
                    Mode:Master
                    Extra:tsf=0000000000000000

که مشخصا اسم شبکه در اینجا mohamad است.
در مرحله بعد برای ویرایش فایل متنی و اضافه کردن نام شبکه و رمز عبور از دستورات زیر استفاده میکنیم:

	
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

در فایل باز شده قسمت های زیر در صورت وجود ویرایش میشوند و اگر موجود نباشند اضافه میشوند:

network={
ssid="SSID"
psk="WIFI PASSWORD"
}

منظور از SSID نام شبکه . مثلا در اینجا mohamad و منظور از WIFI PASSWORD همان رمز عبور وای فای است.
با زدن کلید های ترکیبی CTRL+X از برنامه nano خارج میشویم.

برای درست کار کردن وای فای دستورات زیر را یک به یک وارد میکنیم تا یکبار وای فای راه اندازی مجدد شود و سپس رزبری را راه اندازی مجدد میکنیم . برد رزبری به صورت اتوماتیک به وای فای متصل خواهد شد.

https://www.youtube.com/watch?v=E1VFhmwNjiUsudo ifdown wlan0
sudo ifup wlan0
خارج شدن از نظر

text base user interface در لینوکس

مدتها این موضوع معلق بود تا اینکه فرصت کنم و تکمیلش کنم . تصمیم گرفتم کمی درباره ساخت یک UI بر مبنای text صحبت کنم . چیزی که همه ما از ابتدای برخوردمون با کامپیوتر باهاش درگیر هستیم، اما کاملا بی توجه از کنارش عبور می‌کنیم . در دسترس ترین مثال برای این موضوع، UI مربوط به Bios کامپیوتر ماست .یک UI گرافیکی مبتنی بر متن شامل انواع منوها و متون و صفحات مختلف.
کتابخانه مورد استفاده برای نوشتن یک UI مبتنی بر متن NCurses نام دارد. قصدم معرفی مقدماتی این کتابخانه است، شاید خیلی از دوستان بپرسند چرا Qt نه؟! Qt هم جذابیت بصری بیشتری داشته و هم احتمالا سرعت بیشتری در پیاده سازی ها برای برنامه نویس به ارمغان می‌آورد، من هم منکر این مزیتهای Qt نیستم، اما حجم کتابخانه NCurses نسبت به Qt قابل مقایسه نیست و اینکه من قصدم تکرار مکررات نیست، بلکه پرداختن و معرفی قسمتهایی که در جامعه آی‌تی کمتر بهشون پرداخته شده و معمولا ناشناخته هستند، جزء اهداف من بوده و هست . درباره Qt مطالب خیلی زیادی وجود دارد اما درباره NCurses مطلب زیادی به فارسی نداریم.
نصب کتابخانه NCurses
برای نصب Ncurses در توزیع اوبونتو از دستور

sudo apt-get update
sudo apt-get install ncurses-dev

همچنین فایل سورس در آدرس GNU Operating System موجود است ، میتوان بعد از دانلود مثل تمامی برنامه‌های لینوکسی اقدام به نصب نمود.

tar zxvf ncurses<version>.tar.gz  # unzip and untar the archive
cd ncurses<version>               # cd to the directory
./configure                             # configure the build according to your 
                                        # environment
make                                    # make it
su root                                 # become root
make install                            # install it

کامپایل کردن برنامه‌های شامل کتابخانه ncurses توسط gcc
برای کامپایل یک برنامه نوشته شده در لینوکس از gcc بصورت زیر استفاده می‌کنیم:

gcc -o exe_name program_name.c

که exe_name نام دلخواه ما برای فایل اجرایی و program_name.c نام فایل سورس ما به زبان c است.
در صورتیکه بجز کتابخانه‌های استاندارد موجود به همراه gcc از کتابخانه‌ای که به صورت دستی نصب کرده‌ایم استفاده کنیم، در انتهای دستور فوق باید نام کتابخانه مورد استفاده با پیشوند l- هم نوشته شود، در مثال ما دستور فوق بصورت زیر اصلاح میشود:

gcc -o exe_name program_name.c -lncurses

برای آموزش از Trace کردن برنامه‌های ساده شروع میکنیم:

#include <ncurses.h>
 
int main()
{   
    initscr();          /* Start curses mode          */
    printw("Hello World !!!");    /* Print Hello World          */
    refresh();          /* Print it on to the real screen */
    getch();            /* Wait for user input */
    endwin();           /* End curses mode        */
 
    return 0;
}

برنامه فوق عبارت !!!Hello World را در یک صفحه جدید نمایش میدهد.
تابع ()initscr ترمینال را جهت استفاده ncurses آماده سازی می‌کند. در بعضی پیاده سازی‌ها این آماده سازی شامل ایجاد یک صفحه خالی ترمینال وتخصیص فضای مورد نیاز در حافظه سیستم برای این پنجره می‌شود. برای هرگونه تغییر، ابتدا باید تابع ()initscr فراخوانی شود تا بتوانیم تغییرات مدنظر خود را در صفحه ( این صفحه stdscr نامیده می‌شود) اعمال کنیم.
تابع ()printw همانند تابع معروف ()print عمل میکند بجز اینکه خروجی آن در صفحه stdscr ، در مختصات دلخواه (x,y) چاپ می‌شود.
تابع ()refresh ،عملکرد جالبی را ارائه می‌دهد. تابع printw تعداد زیادی flag را تنظیم کرده و محتویات مورد نظر ما را در بافر خود می‌نویسد. اما بدون استفاده از تابع ()refresh این نوشته ها در صفحه stdscr چاپ نمی‌شوند . برای چاپ باید حتما یکبار تابع ()refresh فراخوانی شود.
این کار باعث بهبود عملکرد و انعطاف پذیری بیشتر برنامه خواهد شد، به این صورت که هر برنامه ممکن است تعداد زیادی آپدیت برای نمایش در صفحه نمایش داشته باشد که همگی در بافر تجمیع شده و با هر بار اجرای تابع ()refresh صفحه نمایش به روزرسانی خواهد شد.
در انتها با فراخوانی تابع ()endwin به کار در مد curses پایان می‌دهیم. به این صورت که ترمینال به صورت عادی برخواهد گشت و فضاهای حافظه گرفته شده آزاد می‌شود.این تابع بعد از اتمام کار در مد curses فراخوانی می‌شود.
ادامه دارد … .
این مطلب ترجمه آزادی از این نوشته در سایت tldp.org بود .

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

کمی 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 قرار دارد مراجعه کنید .

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

ایجاد یک فرایند با استفاده از تابع fork

قبلا با نوشتن یک فرآیند -Process- ابتدایی در لینوکس به وسیله تابع system کمی آشنا شدیم . اما همانطور که گفتم روش اصولی استفاده از تابع fork و ساخت یک فرآیند فرزند -child Process- و تغییر این فرآیند جدید طبق نیازمون هست .
در برنامه نویسی سیستمی ویندوز (win32) از توابع از پیش نوشته شده ای مثل CreateProcess برای ساخت یک process جدید استفاده میشود . در لینوکس این تابع در دسترس نیست ولی توابع fork و exec کار مشابهی را برای ما انجام میدهند .
تابع fork
با استفاده از فراخوانی تابع fork لینوکس یک فرآیند فرزند کاملا مشابه فرآیند والد -parent Process- ایجاد میکند . فرآیند فرزند با اینکه کاملا مشابه والد خود است اما در فضای حافظه متفاوتی اجرا می‌شود و بعد از فراخوانی تابع fork مسیر متفاوتی نسبت به والد خود طی می‌کند . با توجه به این موضوع که فرآیند فرزند یک فرآیند جدید است ، شناسه متفاوتی با فرآیند والد خود دارد و با توجه به همین موضوع می‌توان تشخیص داد فرآیندی که در حال اجراست فرآیند فرزند است یا فرآیند والد . مقدار بازگشتی تابع fork در فرآیند والد برابر با شناسه فرآیند فرزند است ولی این مقدار در فرآیند فرزند برابر با عدد ۰ است . با چک کردن این عدد ( مقدار بازگشتی تابع fork ) به راحتی میتوان تشخیص داد فرآیند در حال اجرا فرآیند والد است یا فرزند .

در برنامه زیر در صورتیکه فرآیند فرزند در حال اجرا باشد شرط if صحیح است و دستورات بلاک بالا اجرا می‌شوند و در‌صورتیکه فرآیند والد در حال اجرا باشد شرط if صحیح نیست و بلاک مربوط به else اجرا می‌شود . فرآیند فرزند ۱۰ مرتیه و فرآیند والد ۲۰ مرتبه اجرا می‌شوند و هر کدام بعد از هربار اجرا به مدت ۱ ثانیه تاخیر ایجاد می‌کنند :

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
 
int main ()
{
pid_t child_pid;
int count1 , count2;
 
printf ("the main process id before fork ,  is %d\n" , (int) getpid());
child_pid = fork ();
 
    if (child_pid == 0 )
    {
        printf ("this is the child Process with id %d\n" , (int) getpid());
        while(count1 < 10)
        {
            printf("child Process : %d\n" , count1 );
            sleep (1);
            count1++;
        }
    }
    else
    {
        printf ("this is parent Process with id %d\n" , (int) getpid());
        while (count2 < 20)
        {
            printf ("Parent Process : %d\n" , count2 );
            sleep (1);
            count2++;
        }
    }
return 0 ;
}

در سایت دانشگاه واترلو یک مثال ابتدایی ( شبیه به همین چیزی که من نوشتم ) از توابع fork وexec وجود داره .

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

نوشتن یک پروسس در لینوکس

در یک ماشین لینوکسی Process به چه چیزی گفته میشود ؟ چگونه یک فرآیند – Process – ایجاد کنیم ، مدیریت کنیم و در انتها Process را خاتمه دهیم ؟

به هر نمونه از برنامه درحال اجرا در یک سیستم یونیکسی ( شبه یونیکسی ) یک Process گفته میشود . برای دیدن لیست Process ها در خط فرمان از دستور ps -e میتوانیم استفاده کنیم . هر Process یک Process والد دارد بجز init که با ID شماره ۱ در لیست Process ها قرار گرفته و وظیفه راه اندازی سیستم را برعهده دارد . فرآیند‌ها همواره در حال اجرا هستند ، حتی در هنگامی که ما هیچ کار خاصی با سیستم خود انجام نمیدهیم .

در لینوکس هر Process با یک ID اختصاصی شناسایی می‌شود ، که به این شماره اختصاصی معمولا pid (مخفف Process ID ) گفته می‌شود . این شناسه اختصاصی یک عدد ۱۶ بیتی است و در زمان ایجاد Process به آن اختصاص داده می‌شود . به Process والد ( Process ای که باعث به وجود آمدن Process فعلی می‌شود والد Process فعلی محسوب می‌گردد.) نیز ppid (مخفف Parend Process ID ) گفته می‌شود . در یک سیستم لینوکسی فرآیند ها – Processes – بصورت یک درخت در نظر گرفته می‌شوند که init در ریشه قرار گرفته است و هر Process بالاتر به عنوان والد Process پایین‌تر محسوب می‌شود .برای مشاهده فرآیندها به همراه فرآیند والد آنها از دستور

$  ps -e -o pid,ppid,command

استفاده می‌کنیم . سوئیچ e- باعث نمایش همه Process ها میشود و با استفاده از سوئیچ o- میتوان موارد مورد نیاز برای نمایش را ( مانند ppid و توضیحات درباره Process در حال اجرا )به مفسر shell اعلام کرد . اگر در ترمینال فعلی دستور بالا را دوباره اجرا کنیم یک شماره PID جدید به Process ما ( یعنی ps -e -o pid,ppid,command ) اختصاص می‌یابد ، اما شماره ppid همچنان بدون تغییر باقی می‌ماند . زیرا والد Process ما همین پنجره ترمینال است و باعث به وجود آمدن Process ما این پنجره ترمینال می‌باشد . پس تا وقتی از این پنجره ترمینال هر دستوری اجرا شود ppid همیشه ثابت خواهد بود .

ایجاد یک فرآیند در لینوکس
برای ایجاد یک Process در لینوکس از ۲ روش میتوانیم استفاده کنیم . در این پست روش اول توضیح داده می‌شود و ان‌شاءالله در پست بعدی روش دوم معرفی می‌گردد :

درکتابخانه استاندارد C یک تابع به اسم system وجود دارد که میتواند برنامه های موردنظر ما را در داخل برنامه در حال اجرا call کرده و خروجی را به برنامه اصلی برگرداند . روش کار بسیار ساده است ، برنامه فعلی (Process والد ) در حال اجرا یک فرآیند فرزند ایجاد میکند . فرآیند فرزند بعد از اتمام کار نتیجه را به فرایند والد برگردانده و خودش به اتمام میرسد . برای روشن شدن ماجرا برنامه ساده زیر را در نظر بگیرید :

#include<stdlib.h>
 
int main (){
 
    int return_value;
    return_value = system("ls -l ");
return return_value;
}

در این برنامه تابع system برنامه ls با سوئیچ -l را در مسیر جاری فراخوانی کرده نتیجه را در کنسول چاپ می‌کند . تابع system وضعیت اجرای فرمان در پوسته سیستم عامل را بازمیگرداند . درصورتیکه پوسته نتواند اجرا شود مقدار ۱۲۷ و اگر خطای دیگری رخ دهد مقدار ۱- بازگردانده خواهد شد .

نقص های این روش بیشتر مربوط به یکسان نبودن نوع پوسته ها و ورژن پوسته ها در سیستم های مختلف شبه یونیکسی می‌باشد. به عنوان مثال خروجی پوسته های مختلف کاملا مشابه نبوده و ممکن است در برنامه‌های پیچیده‌تر باعث اشکال در تفسیر child-process یا فرآیند فرزند شود . همچنین نقایص امنیتی نیز ایراد دیگری است که به این روش وارد است .

برای آشنایی با system میتونید از این منبع استفاده کنید .

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

کامپایل کردن Kernel Module در لینوکس ۱

کامپایل کردن Kernel Modules ، چرا ؟ و چگونه ؟

یکی از گیکی ترین کارهای ممکن در لینوکس کامپایل کردن کرنل و به تبع این کار نوشتن ماژول هایی برای کاربردی خاص در کرنل لینوکس است . مثلا فرض کنید بعد از آپدیت کرنل لینوکس ، یکی از درایور ها از کار افتاده و بعد از درخواست از سازنده ، کد C درایور را دریافت میکنید . در این حالت کامپایل کد C و الحاق ماژول ایجاد شده بر عهده خود شما خواهد بود . این کار نه تنها برای اضافه کردن درایور های سخت افزاری بلکه برای انجام کاری خاص در فضای کرنل که شما تعریف میکنید کاربرد دارد .

من فرض میکنم شما قبلا برنامه هایی معمولی با زبان C نوشته اید و با قابلیت های اساسی این زبان آشنا هستید و قصد دارید قدرت این زبان برنامه نویسی را در کرنل لینوکس ،جایی که با یک اشتباه مهلک میتوانید فایل های سیستمی لینوکس خود را از دست بدید به کار بگیرید .

اما واقعا Kernel Module چیست ؟ ماژول های کرنل یک قطعه کد هستند که با درخواست سرویس های دیگر میتوانند در کرنل بارگزاری (Load) شوند یا از کرنل پایین آورده شوند (UnLoad) . این ماژولها به توسعه قابلیت های کرنل کمک میکنند . بارگزاری این ماژول‌ها در کرنل معمولا احتیاجی به ریبوت سیستم ندارد . یکی از مثالهای خوب در این مورد اضافه کردن سخت افزارها به کرنل لینوکس است ، با اضافه شدن هر سخت افزار ماژول درایور آن در فضای کرنل راه اندازی میشود . در صورت وجود نداشتن این قابلیت در لینوکس ما با یک کرنل یکپارچه روبرو میشدیم که درایور هر قطعه باید مستقیما در ایمیج کرنل قرار میگرفت . در این صورت برای توسعه هر قابلیت در کرنل یا اضافه کردن هر سخت افزار به سیستم باید این کرنل بزرگ دوباره ساخته شده و سیستم از نو راه اندازی می‌شد .

پیش نیازهای کامپایل Kernel Module

برای کامپایل Kernel Module در لینوکس باید kernel headers packages در سیستم نصب باشد ، در حالت عادی این پکیج ها در سیستم نصب نیست ،برای نصب در خانواده دبیان بصورت زیر عمل می‌کنیم :

$ sudo apt-get update
$ apt-cache search linux-headers-$(uname -r)
$ sudo apt-get install linux-headers-$(uname -r)

در آرچ لینوکس از دستور زیر استفاده میکنیم :

sudo pacman -Sy
sudo pacman -S linux-headers

برای تست به نوشتن یک برنامه ساده اکتفا میکنیم:

/*
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
 
int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");
 
    /*
     * A non 0 return means init_module failed; module can't be loaded.
     */
    return 0;
}
 
void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}

برنامه بالا را بنام hello-1.c سیو میکنیم و یک فایل تکست بنام Makefile بصورت زیر در محل سورس برنامه فوق ایجاد میکنیم:

obj-m += hello-1.o
 
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
 
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

از نظر تکنیکی تنها وجود خط اول Makefile کاملا ضروری است . بعد از نوشتن Makefile با استفاده از ترمینال Kernel Module ای که نوشتیم را با نوشتن دستور make در ترمینال کامپایل میکنیم ، دقت کنید که با نوشتن دستور کامپایل از کد توسط gcc نمیتوانیم مستقیما kernel Module را کامپایل کنیم .

اضافه کردن Kernel Module به هسته لینوکس
برای اضافه کردن ماژولی که نوشتیم از دستور insmod استفاده میکنیم :

$ su -
# insmod hello.ko

تحلیل کارکرد Module نوشته شده
در Kernel Modules ما حداقل ۲ تابع داریم . تابع init_module برای مقدار دهی اولیه -initialization- برنامه ما در آغاز برنامه و در هنگام استارت Module استفاده میشود . و تابع cleanup_module در انتهای برنامه و هنگامی که برنامه از کرنل پایین آورده میشود -UnLoad- اجرا میشود .

معمولا تابع init_module یک کارکرد جدید برای کرنل ایجاد میکند و یا یکی از قابلیت فعلی کرنل را تغییر داده و تعریف جدیدی از آن ارائه میدهد . و تابع cleanup_module قابلیتهایی که تابع init_module تغییر داده بود به حالت پیش فرض خود باز میگرداند .

هر Kernel Module حتما باید شامل هدر فایل linux/module.h باشد . در اینجا ما برای استفاده از تابع printk از هدر فایل linux/kernel.h استفاده کردیم .

تابع ()printk یک تابع برای نوشتن اطلاعاتی در log سیستم میباشد . سیستم لینوکس دارای ۸ اولویت میباشد که با نوشتن ماکرو در تابع printk میتوان اولویت نوشتن در log سیستم را تغییر داد . اولویت ها به همراه ماکروها بصورت زیر است :

Name		String	Meaning											alias function
KERN_EMERG	"0"	Emergency messages, system is about to crash or is unstable				pr_emerg
KERN_ALERT	"1"	Something bad happened and action must be taken immediately				pr_alert
KERN_CRIT	"2"	A critical condition occurred like a serious hardware/software failure			pr_crit
KERN_ERR	"3"	An error condition, often used by drivers to indicate difficulties with the hardware	pr_err
KERN_WARNING	"4"	A warning, meaning nothing serious by itself but might indicate problems		pr_warning
KERN_NOTICE	"5"	Nothing serious, but notably nevertheless. Often used to report security events.	pr_notice
KERN_INFO	"6"	Informational message e.g. startup information at driver initialization			pr_info
KERN_DEBUG	"7"	Debug messages	pr_debug, pr_devel if DEBUG is defined
KERN_DEFAULT	"d"	The default kernel loglevel	

برای دیدن پیغامی که تابع printk در log سیستم چاپ میکند باید برنامه syslogd در حال سرویس باشد :

sudo pacman -S syslog-ng
systemctl enable syslog-ng
systemctl start syslog-ng
cat /var/log/messages.log

با توجه به اینکه هر لحظه message های زیادی وارد فایل messages.log میشود میتوانیم از دستور grep برای پیدا کردن message مورد نظر خودمان استفاده کنیم :

sudo cat /var/log/messages.log | grep Hello

پایین آوردن -UnLoad- کرنل ماژول
برای unload کردن یک Kernel Module از دستور rmmod استفاده می‌کنیم :

rmmod hello-1

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

نصب Arch Linux

ویرایش پنجم زمستان ۹۸ :
بعد از ویرایش این آموزش باتوجه به اینکه دیگه آرچ نصب نکردم کاستی های این آموزش برام مشخص نشد. تا اینکه به دلایلی سیستم عامل Arch Linux ام رو پاک کردم و تصمیم گرفتم یک سیستم جدید که فقط برنامه های مورد نیازم روش نصب باشه و زیاد شلوغ نباشه تهیه کنم . به همین دلیل از اول اقدام به نصب آرچ کردم که با توجه به بعضی از مشکلات ویرایش قبلی این آموزش پاسخگوی اونها نبود. من تصمیم گرفتم ویرایش جدیدی به همراه تغییرات جدید آرچ لینوکس تهیه کنم. امیدوارم مفید واقع بشه.

این یک راهنمای مینیمال برای نصب «Arch Linux» هستش . توی اینترنت راهنماهای زیادی هست ، هر کسی با توجه به نیازی که داشته برای خودش یا برای بقیه یک راهنما نوشته . من هم با توجه به چیزهایی که میخوام نصب کنم این راهنما رو مینویسم . و صد البته که قسمت عمده ای ازش با بقیه مشترک خواهد بود .

تهییه فایل iso.
من فرض کردم شما یک ایزوی سالم  و جدید از سایت ArchLinux در اختیار دارید.برای رایت ایزو بر روی دی وی دی یا بوتیبل سازی فلش طبق مسیر زیر اقدام کنید.

در لینوکس:
باز هم من فرض کرده ام شما آشنایی مقدماتی با دستورات خط فرمان و شناسایی دیوایس ها در لینوکس و … دارید . معمولا فرد ناآشنا با لینوکس برای اولین بار سراغ آرچ لینوکس نمیاد و این آموزش برای افراد آشنا با ساختار لینوکس و خط فرمان مفید خواهد بود.

به راحتی با استفاده از خط فرمان و دستور قدرتمند dd میتوان نسبت به تهییه یک سی‌دی یا فلش بوتیبل اقدام کرد :

با دستور زیر میتونیم اون رو روی دی وی دی موجود بر روی اپتیک درایو رایت کنیم :

sudo dd if=/path_to_arch_.iso of=/device-name

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

در ویندوز :

با استفاده از نرم افزار unetbootin میتوان اقدام به رایت ایزو نمود .

بعد از رایت شدن میتونیم سیستم رو راه اندازی مجدد کنیم .

اتصال به اینترنت

بعد از بوت شدن سیستم . در ابتدای فرآیند نصب اتصال به اینترنت را چک میکنیم:

ping -c3 www.google.com

دستور بالا سایت گوگل را ۳ بار پینگ میکند که در صورت عدم اتصال متوجه خواهیم شد .

البته اولویت با اتصال به اینترنت توسط کابل لن میباشد.

در صورت استفاده از مودم وایرلس یا استفاده از Wifi میتوان بصورت زیر به اینترنت متصل شد :

wifi-menu

دستور فوق اتصال وای‌فای را چک کرده و اقدام به اتصال مینماید .

نوع پارتیشن بندی

دو نوع جدول پارتیشن برای نصب در اختیار ماست . استفاده از سیستم مدرن GPT یا استفاده از سیستم قدیمی تر MBR . در صورتیکه سیستم شما از UEFI پشتیبانی میکند تنها انتخاب شما استفاده از سیستم بوت UEFI به همراه پارتیشن بندی GPT میباشد. در غیر اینصورت از هر دو سیستم پارتیشن بندی MBR یا GPT میتوان استفاده کرد . در اینجا ما نصب آرچ لینوکس بر روی هر دو نوع سیستم را آموزش میدهیم.

برای پارتیشن بندی ، در صورت استفاده از GPT از برنامه cgdisk و در صورت استفاده از MBR از برنامه cfdisk استفاده میشود .

ابتدا با برنامه lsblk اسم پارتیشن مورد نظر برای نصب را پیدا میکنیم .

sda      8:0    0 119.2G  0 disk
├─sda1   8:1    0  119.2G  0 part
sde      8:64   0 931.5G  0 disk
└─sde1   8:65   0 931.5G  0 part

پارتیشن بندی MBR:

فرض میکنیم تنها سیستم عامل کامپیوتر ما فقط ArchLinux خواهد بود. در این حالت بصورت زیر عمل میکنیم:

فرض کنیم قصد نصب Arch در درایو sda را داریم :

cfdisk /dev/sda

ابتدا پارتیشن روت .سپس swap و در انتها پارتیشن home را میسازیم .
بعضی از علما استفاده از یک پارتیشن مجزا برای var/ را پیشنهاد میدهند که در صورت تمایل میتوانیم این پارتیشن را هم بسازیم .

New > Enter
Partition Size > 40G
Primary or Extended > Select Primary
Bootable > Enter
Write > Enter > Yes

بعد از ساخت روت swap را میسازیم :

New > Enter
Partition Size > 4G
Primary or Extended > Select Primary (or extended, if you are going to create more than 3 partitions on this hard drive)
Write > Enter > Yes

سپس در صورت علاقه میتوانیم پارتیشن home/ را بسازیم . در غیر اینصورت پارتیشن home/ از فضایی که برای root/ در نظر گرفته ایم استفاده میکند.

بعد از ساخت پارتیشن ها ،آنها را فرمت میکنیم، فرض میکنیم پارتیشن root/ در آدرس dev/sda8/ قرار دارد .

# mkfs.ext4 /dev/sda8

از سیستم فایل ext4 برای پارتیشن روت استفاده کردیم .

فرض میکنیم swap در dev/sda5/ قرار دارد. با استفاده از دستور زیر این پارتیشن را به swap تخصیص داده و فعال میکنیم . در صورتیکه یک پارتیشن swap در سیستم شما از قبل موجود است، نیازی به تخصیص پارتیشن به سیستم فایل swap نمیباشد و تنها باید نسبت به فعال سازی swap اقدام کنید.

# mkswap /dev/sda5
# swapon /dev/sda5

در صورت علاقه میتوان یک پارتیشن مجزا برای boot/ با حداقل حجم ۲۵۶ مگابایت ساخت .

در صورتیکه بخواهید از بوت دوگانه به همراه ویندوز یا چندگانه استفاده کنید بصورت زیر عمل کنید:
ابتدا به مقدار موردنیاز خود فضای خالی درنظر بگیرید،حداقل ۲۰ گیگابایت برای پارتیشن root و حداقل به اندازه رم سیستم برای swap و مقدار دلخواه برای پارتیشن home. درصورتیکه بجای HDD از SSD استفاده میکنید یا حافظه سیستم شما بیشتر از ۸ گیگابایت میباشد،احتیاجی به پارتیشن Swap ندارید.
من از ۱۷۰ گیگابایت فضای پارتیشن بندی نشده برروی سیستمم استفاده کردم . ابتدا یک پارتیشن ۱۷۰ گیگابایتی از نوع extended میسازیم . سپس از فضای خالی پارتیشن extended پارتیشن های root ,swap و home را میسازیم.در انتها پارتیشن root ( در صورتیکه اقدام به ساخت پارتیشن boot مجزا کرده اید پارتیشن boot) را بوتیبل میکنیم و برای اعمال تغییرات write را میزنیم.

نصب در حالت UEFI و پارتیشن بندی GPT

برای نصب سیستم UEFI لازم است در مرحله بوت ، بوت حتما در حالت UEFI انتخاب شود در غیر این صورت پس از اتمام عملیات نصب سیستم شما قابل دسترسی نیست.

پس از تست اتصال به اینترنت با دستور ping ، با استفاده از دستور lsblk میتوان پارتیشن های موجود را دید. با استفاده از دستور زیر میتوانیم پارتیشن های لازم برای نصب آرچ لینوکس را بسازیم.

cfdisk /dev/sda

در صورتیکه از ویندوز ۱۰ در کنار آرچ لینوکس استفاده میکنید، نقشه حافظه اختصاص داده شده به ویندوز و بوت آن بصورت زیرمیباشد(پارتیشن ویندوز سیستم من ۲۴۳ گیگابایت ظرفیت دارد.):

Recovery	sda1	500 MB	ntfs
EFI System	sda2	100 MB	vfat
Reserved	sda3	16 MB	
Windows 10	sda4	243 GB	ntfs

با استفاده از دستور cfdisk پارتیشن های زیر را میسازیم:

۵۰۰ مگابایت با فایل سیستم EFI system

مابقی حافظه به پارتیشن root اختصاص میابد . و از نوع Linux filesystem انتخاب میشود. در صورتیکه شما تمایل داشته باشید میتوانید از پارتیشن home/ جداگانه استفاده نمایید.

در صورتیکه از بوت دوگانه به همراه ویندوز استفاده میکنید، حتما یک حافظه به حجم ۱ مگابایت از نوع Bios boot اختصاص دهید . در غیر اینصورت بعد از اتمام عملیات نصب سیستم شما بوت نخواهد شد. در صورتیکه قصد استفاده همزمان از ویندوز در کنار لینوکس خود ندارید از این مرحله صرف نظر کنید.

پارتیشن بندی سیستم من بعد از اتمام کار بصورت زیر میباشد:

مابقی مراحل نصب بین سیستم قدیمی و سیستم UEFI مشترک میباشد:

ماونت کردن پارتیشن ها

بعد از ساخت و فرمت کردن پارتیشن ها نوبت به ماونت کردن پارتیشن ها میرسد . برای ماونت کردن از دستورات زیر استفاده میکنیم :

ماونت کردن root/ ( پارتیشن روت سیستم من در sda8 قرار دارد .):

# mount /dev/sda8 /mnt

در صورتیکه از پارتیشن home/ مجزا استفاده میکنید میتوانید آن را بصورت زیر ماونت کنید ( پارتیشن home/ سیستم من در sda9 قرار دارد.) :

mkdir /mnt/home
mount /dev/sda9 /mnt/home

در صورتیکه پارتیشن مجزا برای var/ ساختید ، به صورت بالا ابتدا یک Mount Point در mnt/ در نظر گرفته و سپس اقدام به مونت کردن پارتیشن var/ بنمایید .

همچنین میتوان یک پارتیشن مجزا برای boot/ نیز در نظر گرفت و به صورت فوق بعد از مونت پارتیشن / اقدام به ساخت mount point در mnt/ نموده و این پارتیشن ها را مونت نمود .

انتخاب سایت های Mirror

قبل از نصب بسته های اولیه باید سایت های میرور را برای نصب انتخاب و فایل زیر را ویرایش کنیم ، از دو روش میتوان دست به Rank کردن سایت های میرور کرد ، روش اول استفاده از برنامه reflector برای Rank کردن سایتهاست و روش دوم روش دستی میباشد . از یکی از این روش ها برای رنک کردن سایتهای میرور استفاده کنید تا سرعت دانلود بسته ها برای شما افزایش یابد .

روش اول استفاده از reflector

ابتدا برنامه را توسط دستور pacman -S نصب میکنیم :

pacman -Syy
pacman -S reflector

سپس از mirror list بکاپ میگیریم:

cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak

در انتها توسط برنامه reflector سایتها را رنک میکنیم :

reflector -c "IR" -f 12 -l 10 -n 12 --save /etc/pacman.d/mirrorlist

روش دوم Rank کردن دستی سایتهای Mirror list :

# nano /etc/pacman.d/mirrorlist

ابتدا خط مورد نظر را انتخاب کرده و در بالای لیست قرار میدهیم .برای این منظور با استفاده از Ctrl+w کلمه iran را جستجو میکنیم و با کلید های alt+6 خط مورد نظر کپی شده و با زدنctrl+u در ابتدای فایل mirrorlist پیست میشود .برای پیدا کردن بقیه میرورهای کشور ایران از Alt+w استفاده میکنیم و سایتهای میرور را در ابتدای فایل لیست میکنیم.

نصب بسته های اولیه

در این مرحله بسته های base که بسته های ضروری برای ایجاد سیستم جدید هستند و بسته های base-devel که بسته های لازم برای برنامه نویسی و توسعه سیستم هستند ، همچنین کرنل لینوکس نصب میشوند:

# pacstrap -i /mnt base base-devel linux linux-firmware

بسته های پیشنهادی به صورت پیش فرض نصب خواهند شد . در صورتیکه علاقه ای به نصب بعضی از بسته ها ندارید ، مثلا هم ویرایشگر nano و هم vi در این مرحله نصب میشوند، و ما به دلایلی علاقه ای به نصب vi نداریم میتوانیم بااضافه کردن یک – جلوی عدد پکیج مورد نظر از نصب آن در این مرحله جلوگیری کنیم . (البته ویرایشگر nano جدیدا در نصب بسته های base نصب نمیشود و باید بصورت دستی توسط pacman نصب شود. یا کد بالا بصورت زیر اصلاح شود)

pacstrap /mnt base base-devel linux linux-firmware nano

در صورتیکه در حین فرایند نصب دچار وقفه و اختلالی شده اید، بدون نگرانی دستور بالا را دوباره تکرار کنید تا ادامه دانلود صورت بگیرد.

بعد از نصب باید فایل fstab را بسازیم :

ساختfstab

فایل fstab برای معرفی اینکه کدام پارتیشن‌ها باید به فایل‌سیستم مونت شوند بکار می‌رود .

genfstab -U -p /mnt >> /mnt/etc/fstab

برپا ساختن سیستم جدید توسط chroot

# arch-chroot /mnt

تنظیم زبان و مکان محلی

# nano /etc/locale.gen

عبارت en_US.UTF-8 UTF-8 مربوط به زبان انگلیسی ، همچنین عبارت مربوط به زبان فارسی رو از کامنت خارج میکنیم و دستورات زیر را میزنیم

# locale-gen
# echo LANG=en_US.UTF-8 > /etc/locale.conf
# export LANG=en_US.UTF-8

تنظیم زمان محلی

# ln -sf /usr/share/zoneinfo/Asia/Tehran /etc/localtime

تنظیم ساعت سیستم

# hwclock --systohc --utc

تعیین host name

برای داشتن نام دلخواه سیستم خودتان میتوان دستور زیر را استفاده کرد ( این دستور نام کامپیوتر را به sys_name تغییر میدهد ):

# echo sys_name > /etc/hostname

پیکربندی مخازن

در صورت نصب سیستم عامل ۶۴ بیتی نیاز به مخازن multi Lib خواهیم داشت . برای این منظور فایل pacman.conf را با نرم افزار nano باز میکنیم :

# nano /etc/pacman.conf

سپس به پایین اسکرول کرده و خطوط زیر را uncomment میکنیم :

[multilib]
Include = /etc/pacman.d/mirrorlist

با قرار دادن خطوط زیر در انتهای فایل pacman.conf میتوان مخازن فرانسه را اضافه کرد :

[archlinuxfr]
SigLevel = Never
Server = http://repo.archlinux.fr/$arch

در نهایت فایل را ذخیره کرده و خارج میشویم . با دستور زیر مخازن را آپیدت میکنیم :

#sudo pacman -Sy

پیکربندی حساب کاربری

ابتدا برای کاربر root یک پسورد در نظر میگیریم :

# passwd

سپس یک کاربر جدید بنام ali تعریف میکنیم :

# useradd -m -g users -G wheel,storage,power -s /bin/bash ali

در انتها برای کاربر ali پسورد تعیین میکنیم:

#passwd ali

برای اینکه بتوان کارهای مربوط به کاربر root را بدون وارد شدن به حساب root انجام داد ، برنامه sudo را ویرایش میکنیم :

# EDITOR=nano visudo

خط زیر را uncomment میکنیم :

%wheel ALL=(ALL) ALL

نصب بسته auto-complete برروی bash

# pacman -S bash-completion

نصب بوت لودر گراب برای سیستم MBR

اگر بجز آرچ از سیستم عامل دیگری نیز استفاده میشود . ابتدا بسته زیر را نصب میکنیم :

#pacman -S os-prober

سپس گراب را نصب میکنیم :

# pacman -S grub
# grub-install --recheck /dev/sda
# grub-mkconfig -o /boot/grub/grub.cfg

نصب بوت لودر گراب برای سیستم GPT

ابتدا بسته های زیر را نصب میکنیم :

pacman -S grub efibootmgr

یک دایرکتوری برای ماونت کردن پارتیشن EFI میسازیم :

mkdir /boot/efi

حال پارتیشن ۵۰۰ مگابایتی EFI system را ماونت میکنیم ، ( در سیستم من dev/sda7/ قرار دارد) :

mount /dev/sda7 /boot/efi

گراب بصورت زیر نصب میشود :

grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi
grub-mkconfig -o /boot/grub/grub.cfg

در انتها برای اطمینان از اتصال به اینترنت بعد از ریبوت سیستم جدید بسته زیر را نصب میکنیم :

pacman -S networkmanager
systemctl enable NetworkManager.service

بعد از نصب سیستم عامل برای نصب گرافیک از بسته ای زیر استفاده میکنیم :

pacman -S xorg xorg-server

نصب Gnome

برای نصب Gnome از دستورات زیر استفاده میکنیم . میتوان هر مدیر پنجره را بکار برد اما مدیر پنجره gdm پیشنهاد میشود:

pacman -S gnome
systemctl start gdm.service
systemctl enable gdm.service

نصب XFCE

sudo pacman -S lxdm
sudo pacman -S xfce4 xfce4-goodies
systemctl enable lxdm.service

نصب KDE

sudo pacman -S kde
systemctl enable kdm.service
pacman -S kdeplasma-applets-plasma-nm
pacman -S alsa-utils pulseaudio kdemultimedia-kmix

در انتها از مد ch-root خارج میشویم ، پارتیشن ها را Unmount میکنیم و سیستم را ریست میکنیم:

# exit
# umount -R /mnt
# reboot

پس از نصب

برای اینکه بتوانیم به پارتیشن های ویندوزی دسترسی داشته باشیم باید بسته زیر را نصب کنیم:

sudo pacman -S ntfs-3g

در صورتیکه از بوت دوگانه یا چندگانه به همراه سیستم عامل ویندوز استفاده میکنید، در این مرحله دوباره گراب را آپدیت میکنیم تا سیستم عامل مقیم در حافظه ntfs هم شناسایی شود و به گراب اضافه شود:

در سیستم Legacy:

# grub-install --recheck /dev/sda
# grub-mkconfig -o /boot/grub/grub.cfg

در سیستم UEFI:

grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi
grub-mkconfig -o /boot/grub/grub.cfg

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