آموزش لینوکس | آموزش LPIC 1 | جزوه آموزشی لینوکس LPIC 1 | آموزش سیستم عامل لینوکس | آموزش Linux
با دوره آموزش LPIC 1 کد 101 از سری دوره های آموزشی لینوکس در خدمت شما هستم. هدف این دوره آموزش مطالب به صورت خلاصه و به زبان خودمونی هستش تا شما بتوانید مطالب را در سریع ترین زمان ممکن یاد بگیرید و از خوندنشون خسته نشید! در قسمت اول از این دوره یاد میگیریم که لینوکس چجوری با سخت افزار ارتباط برقرار میکنه و یک سری مفاهیم و دستورات مربوط با اون رو مورد بررسی قرار میدیم.
Hardware Abstraction Layer چیست؟ کارش اینه که سخت افزار رو به طور ساده به شما نشون بده! مثلا اولین کارت شبکه ای که وصل می کنید فارغ از نوع و سرعت و برند و ... به شما eth0 نشون میده و همین باعث راحتی در کانفیگ اجزای مختلف میشود. در این بین یک شبه-فایل سیستمی به نام sysfs وجود دارد که HAL دیتبایسش را در آن ذخیره میکند این فایل سیستم یک رابطه برای دسترسی به ساختار داده کرنل که اطلاعاتی از قبیل دستگاهای متصل ، ماژول های کرنل ، فایل سیستم ها و باقی اجزای کرنل در داخل اون موجوده. با دستور زیر میشه اطلاعات داخل این فایل سیستم را دید:
─$ ls /sys
block bus class dev devices firmware fs kernel module
sysfs محل ذخیره ی دیتابیس HAL است
خط اتوبوس لینوکس هستش! کارش اینه که بخش های مختلف سیستم عامل رو به هم وصل میکنه و اجازه میده تا با هم دیگه صحبت کنند مثلا وقتی یه فلش جدید وصل میکنید به کامپیوترتون dbus به سیستم عامل خبر میدهد (که بهش رویداد های سخت افزار میگویند) یا مثلا وقتی اجرای یک برنامه به پایان میرسه میتونه پیغامی رو روی مانیتور نمایش بده (که بهش میگن رویداد های نرم افزار).
کارت ملیِ قطعات! یعنی به شما امکان میدهد قطعات را از روی ویژگیشان تشخیص بدهید. مثل شرکت سازنده و UUID ؛ و این امکان پیاده سازی قوانینی روی سخت افزار را به ما میدهد ، مثلا هروقت که من هارد ADATA م رو وصل کردم که فلان uuid رو داره به عنوان "dev/adata/" روی سیستم وصلش کن. ( در انتهای مقاله توضیحات تکمیلی رو راجع به uuid میدم) نکته ای که هستش اینکه وقتی دستگاه جدیدی وصل میشود یک فایل در dev/ به اون اختصاص داده میشه ، دایرکتوری dev/ توسط udev کنترل میشود و دستگاه ها فارغ از مدل و تکنولوژی و برندشون در این قسمت قرار دارند، با دستور زیر میتوانید داخل این دایرکتوری را ببینید:
└─# ls /dev
autofs full loop5 nvram ram12 ram6 sg0 tty1 tty17 tty24 tty31 tty39 tty46 tty53 tty60 ttyS1 vcsu
block fuse loop6 ppp ram13 ram7 sg1 tty10 tty18 tty25 tty32 tty4 tty47 tty54 tty61 ttyS2 vcsu1
bsg kmsg loop7 ptmx ram14 ram8 shm tty11 tty19 tty26 tty33 tty40 tty48 tty55 tty62 ttyS3 vfio
btrfs-control loop0 loop-control pts ram15 ram9 stderr tty12 tty2 tty27 tty34 tty41 tty49 tty56 tty63 urandom vhost-net
console loop1 mapper ram0 ram2 random stdin tty13 tty20 tty28 tty35 tty42 tty5 tty57 tty7 vcs vsock
cpu_dma_latency loop2 mem ram1 ram3 rtc0 stdout tty14 tty21 tty29 tty36 tty43 tty50 tty58 tty8 vcs1 zero
cuse loop3 net ram10 ram4 sda tty tty15 tty22 tty3 tty37 tty44 tty51 tty59 tty9 vcsa
fd loop4 null ram11 ram5 sdb tty0 tty16 tty23 tty30 tty38 tty45 tty52 tty6 ttyS0 vcsa1
به عنوان یه تمثیل میشه گفت که sys/ به جعبه دسترسی میدهد و dev/ به محتویات داخل جعبه!
جایی که اطلاعات ، ویژگی ها و تنظیمات مربوط به سیستم و کرنل در آن قرار دارد. این دایرکتوری به صورت مجازی است و در رم ساخته میشود.
└─$ ls /proc
1 buddyinfo cpuinfo execdomains irq kpagecgroup misc partitions swaps uptime
34 bus crypto filesystems kallsyms kpagecount modules sched_debug sys version
7 cgroups devices fs kcore kpageflags mounts schedstat sysvipc vmallocinfo
8 cmdline diskstats interrupts keys loadavg mtrr self thread-self vmstat
9 config.gz dma iomem key-users locks net softirqs timer_list zoneinfo
acpi consoles driver ioports kmsg meminfo pagetypeinfo stat tty
اعداد ID پروسه ها هستند. همچنین اطلاعاتی مانند cpuinfo,mounts,meminfo و ... در این دایرکتوری وجود دارد. در این دایرکتوری علاوه بر این موارد امکان تغییر تنظیمات به صورت لایو نیز وجود دارد مثلا در مسیر proc/sys/net/ipv4/ با تغییر پارامتر ip_default_ttl به 1 :
└─# echo 1 > ip_default_ttl
دیگر تمامی بسته ها با ttl 1 ارسال میشوند:
└─# ping 4.2.2.4 -c 4
PING 4.2.2.4 (4.2.2.4) 56(84) bytes of data.
From 172.20.96.1 icmp_seq=1 Time to live exceeded
From 172.20.96.1 icmp_seq=2 Time to live exceeded
From 172.20.96.1 icmp_seq=3 Time to live exceeded
From 172.20.96.1 icmp_seq=4 Time to live exceeded
--- 4.2.2.4 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3157ms
(البته برای تغییر تنظیمات در شاخه proc نیاز به دسترسی روت دارید!)
ولی این تنظیمات موقتی هستند و فقط تا زمانی باقی میمانند که سیستم ریستارت نشه، برای دائمی کردن تغییرات باید از توی دایرکتوری etc/ آنها را تغییر بدهید
[root@dhcppc5 dev]# lsmod
Module Size Used by
e1000 151552 0
nls_utf8 16384 1
udf 102400 1
crc_itu_t 16384 1 udf
uinput 20480 1
rfcomm 86016 6
xt_CHECKSUM 16384 1
ipt_MASQUERADE 16384 3
xt_conntrack 16384 1
ipt_REJECT 16384 2
nft_counter 16384 16
nf_nat_tftp 16384 0
nft_objref 16384 1
nf_conntrack_tftp 16384 3 nf_nat_tftp
tun 53248 1
bridge 192512 0
stp 16384 1 bridge
llc 16384 2 bridge,stp
nft_fib_inet 16384 1
nft_fib_ipv4 16384 1 nft_fib_inet
nft_fib_ipv6 16384 1 nft_fib_inet
nft_fib 16384 3 nft_fib_ipv6,nft_fib_ipv4,nft_fib_inet
nft_reject_inet 16384 5
nf_reject_ipv4 16384 2 nft_reject_inet,ipt_REJECT
nf_reject_ipv6 16384 1 nft_reject_inet
با استفاده از modprobe میتوان ماژول هایی را اضافه یا حذف کرد به طور مثال دستور زیر باعث حذف کارت شبکه ی دستگاه میشود:
[root@dhcppc5 dev]# modprobe -r e1000
و با دستور زیر دوباره کارت شبکه به ماژول های کرنل اضافه میشود
[root@dhcppc5 dev]# modprobe e1000
البته باید توجه داشته باشید که این دستورات هم موقت هستند و با ریستارت سیستم ، همه چی به حالت دیفالت بر میگرده!
هر دستگاه شناسه ی منحصر به فرد خودش را دارد ، تا بتواند فارغ از پورت وصل شده ، زمان وصل شده و ... شناسایی بشود. با دستور blkid میتوانید شناسه ی مربوط به دستگاه های بلاکی ( مثل هارد) را ببینید:
[root@dhcppc5 ~]# blkid
/dev/sda1: UUID="57479d0d-15e1-43c2-9e51-e775c42dcca0" TYPE="ext4" PARTUUID="4cbe73ef-01"
/dev/sda2: UUID="gykIgK-1OGj-n7r2-e0F1-Q13h-8twi-Y9wXPn" TYPE="LVM2_member" PARTUUID="4cbe73ef-02"
/dev/sr0: UUID="603ec3ef00068fb0" LABEL="VMware VCSA" TYPE="udf"
/dev/sdb: UUID="45c88ad6-6a3d-4cc6-8f68-ec0a03528393" TYPE="ext4"
/dev/mapper/cl-root: UUID="eb40c6ae-cfb6-460d-b1ed-a59ecca98ab0" TYPE="xfs"
/dev/mapper/cl-swap: UUID="c0e2bfca-c33d-4ffd-8dfe-561fa9e412b2" TYPE="swap"
در قسمت دوم از این دوره با مفاهیم بوت کردن سیستم ، BIOS ، لاگ های هنگام بوت ، کرنل و init آشنا میشیم.
BIOS مخفف Basic Input Output System میباشد و یک قطعه ی فیزیکی روی مادربورد هستش ، کارش اینه که وقتی سیستم روشن شد ، برای ما مراحل اولیه ی بوت رو انجام بده ، مثلا زمانی که شما کیس تون رو روشن میکنید اگر درست کار کنه یه تک بوق میزنه و این بهش POST گفته میشه که مخفف Power On Self Test یعنی سیستم موقع روشن شدن خودش رو تست میکنه و اگه ایرادی وجود داشته باشه اطلاع میده.
بایوس 4 کارکرد اصلی داره:
یه برنامه ی کوچیکه که سیستم عامل رو داخل مموری میشونه. وقتی یه کامپیوتر روشن میشه یا ریستارت میشه ، بایوس بعد از گذروندن تست اولیه اش (همون POST) کنترل رو به MBR میده ، MBR جایی هستش که بوت لودر درون اون قرار داره ولی برای سیستم های لینوکس یک بوت لودر اختصاصی باید نصب بشه.
لینوکس چندین بوت لودر مختلف داره یکی از اونها LILO هستش که معمولا فقط با MBR کار میکنه. ولی چیزی که الان در اکثر لینوکس ها مورد استفاده قرار میگیره GRUB هستش که داری دو ورژن 1 و 2 میباشد. مسیر های زیر برای تنظیمات این بوت لودرها هستش :
/etc/lilo.conf
/boot/grub/grub.cfg
/boot/grub/menu.lst
کرنل ، هسته ی سیستم عامل لینوکس هستش و واسط بین سخت افزار و نرم افزار محسوب میشه و کنترل همه چیز در سیستم را بر عهده دارد
کرنل پارمترهایی دارد ( که ممکنه با نام پارمترهای بوت نیز شناخته شوند) که این پارامتر ها باعث میشوند تا کارهای متفاوتی در زمان بوت اتفاق بیفتند مثلا با قرار دادن S باعث میشود تا کرنل به صورت تک کاربره ( Single user ) بوت بشود.
پارمتر های کرنل:
لیست پارامتر های کرنل را میتوانید از اینجا ببینید.
اضافه کردن پارمتر های بوت به کرنل لینوکس به صورت موقتی ( برای تست)
توجه داشته باشید که پارمتر هایی که به این صورت وارد میکنید موقتی هستند و بعد از اتمام این نوبت بود کاربرد نخواهند داشت!
اضافه کردن پارامتر های بوت به کرنل لینوکس به صورت دائمی
وقتی کرنل بالا اومد ، معمولا sbin/init/ رو اجرا میکنه. وظیفه ی این برنامه اجرای دیگر پروسه ها هستش و همیشه در حال اجرا باقی میماند تا وقتی که سیستم خاموش شود و همیشه آی دی این پروسه 1 هستش
برای دیدن درخت پروسه ها میتوانید از دستور زیر استفاده کنید:
pstree
در خیلی توزیع ها init در حال جایگزینی میباشد (مثلا در اوبنتو با upstart)
در لینوکس همه چی لاگ میشه! ولی در زمان بوت شدن سیستم ، فقط کرنل در حال اجرا هستش پس خودش باید لاگ های خودش رو ذخیره کنه!
دستور dmesg به ما تمام داده های مربوط به kernel ring buffer را تا این لحظه نمایش میده. علاوه بر این با دستور زیر میتوانید فقط لاگ های زمان بوت را ببینید:
cat /var/log/dmesg
وقتی init بالا اومد از این به بعد لاگ ها رو syslog ذخیره میکنه که دارای برچسب زمانی هستش و بعد از ریستارت هم باقی میمونه برای دسترسی به این لاگ ها از دستور زیر میتونید استفاده کنید:
cat /var/log/messages
چند نکته :
خلاصه : در این قسمت از این آموزش با هم بایوس رو بررسی کردیم ، کارکرد های اون رو دیدیم ، با بوت لودر ها آشنا شدیم با هم کرنل رو بررسی کردیم و فهمیدیم که چجوری میشه پارمترهای برای بوت شدن به کرنل هم به صورت موقت هم دائم اضافه کنیم ، کاربرد init رو فهمیدم و با انواع لاگ کردن در سیستم های لینوکسی آشنا شدیم.
در قسمت سوم از این دوره با مفهوم runlevel آشنا خواهیم شد و دستورات مربوط به اون رو توضیح خواهم داد ، دستورات خاموش کردن سیستم رو میبینیم ، بستن درست پروسه ها را یاد میگیریم و با مفاهیم مربوط به init بیشتر آشنا میشیم.
runlevel ها تعیین میکنند که چه کارهایی در حالت کنونی ماشین لینوکسی ما قابل انجام هستند. ران لول ها 7 حالت دارند :
ران لول دیفالت و تنظیمات مربوط به init از داخل فایل inittab قابل دسترسی و تغییر بود ( ولی هم اکنون این فایل منسوخ شده و فایل های دیگری جایگزین شده که جلوتر آنها رو بررسی میکنیم) ولی از آنجایی که هنوز در امتحانات LPIC از inittab سوال میشه ، پس اشاراتی به اون میکنم ، برای دیدن ران لول دیفالت از دستور زیر میشود استفاده کرد:
grep "^id:" /etc/inittab
برای تغییر ران لول از طریق تغییر پارمتر های کرنل ( که در درس پیش به طور کامل بهش پرداخته شد) نیز میشود اقدام کرد. یا از طریق دستور telinit :
# runlevel
N 3
# telinit 5
# runlevel
3 5
که در اینجا از ران لول N ( که یعنی ران لولی قبل از این وجود نداشته و دستگاه خاموش بوده) به ران لول 3 رفته و با دستور telinit از ران لول 3 به ران لول 5 رفته است.
همونطور که بالاتر گفتم این دایرکتوری تنظیمات مربوط به init رو داخل خودش داشته که الان کنار رفته و با systemd و upstart جایگزین شده است . در حال حاضر محتویات داخل inittab در سیستم هایی که هنوز این فایل را دارند به شکل زیر میباشد :
# inittab is no longer used.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
که در همان خط اول میگوید که inittab دیگر استفاده نمیشود. ولی قدیم تر که این فایل مورد استفاده قرار میگرفته به چه شکل بوده؟ نمونه ی یک فایل inittab را در زیر میبینید:
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
که از این فرمت استفاده میکند:
id:runlevels:action:process
که در آن:
اسکریپت های مربوطه در مسیر زیر قرار داشته اند:
ls /etc/init.d
و ران لول ها از طریق دایرکتوری های rc0.d تا rc6.d کنترل میشوند:
ls /etc/rc6.d/
بهترین راه برای خاموش کردن یک ماشین لینوکسی از طریق دستور shutdown میباشد، که اول برای تمامی کاربرهایی که در این ماشین لاگین کرده اند یک هشدار ارسال میکند و جلوی لاگین شدن جدید را هم میگیرد. بعد یک سیگنال به init میفرستد به عنوان تغییر runlevel ، سپس init به تمامی پروسه های در حال اجرا سیگنالی به نام SIGTERM میفرستد و اعلام میکند
ماشین تا 5 ثانیه ی دیگر ( یا زمان دیگری که تعیین شده) خاموش خواهد شد و فرصت میدهد تا پروسه ها در صورت نیاز دیتا های خودشون رو ذخیره کنند و در غیر این صورت به کار خود خاتمه دهند (terminate شوند) بعد از سپری شدن زمان داده شده init سیگنال SIGKILL را برای باقی پروسه هایی که هنوز در حال اجرا هستند میفرستد و آنها را به اصطلاح kill میکند.
shutdown -r 60 updating kernel
poweroff یه لینک سیمبولیک به halt هستش و باعث میشه سیستم اول halt بشه بعد مادربورد خاموش بشه و reboot هم همینطور یه لینک سیمبولیک به halt هستش که باعث ریبوت سیستم میشود.
همانطور که بالاتر اشاره کردم دو جایگزین برای inittab وجود دارد:
اولی upstart هستش که دیگه مثل init یک سری اسکریپت های استاتیک نیست و توانایی فهم event ها رو داره که به وسیله ی آنها میشه یک سری task ها یا سرویس هایی (jobs) رو به کار انداخت مثلا اجرای DNS server بعد از اینکه DHCP server اجرا شد
با دستور
initctl list
میتونید لیست سرویس ها رو ببینید. upstart برای سیستم های ubuntu ای هستش.
دومی هم systemd هستش که با سوکت ها کار میکنه و میتونه برای هر سرویسی یک سوکت باز بزاره و در صورتی که اون سرویس فراخوانی شد اجراش کنه سرعتش نسبت به init بیشتره ، وابستگی رو میفهمه و به صورت موازی هم میتونه کار کنه
دستورش هم
systemctl
هستش. systemd با واحد ها(units) کار میکنه ( service , socket ,device ,mount, automount, target(گروه دیگری از واحدها) ,snapshot (save/rollback)) و فایل کانفیگش هم به وسیله ی همین واحد ها پسوند گذاری میشه ( مثلا rpcbind.socket یا cups.service
و در مسیر etc/systemd/system/ قرار گرفته. systemd در سیستم های فدورا بیس و SUSE استفاده میشه.
خلاصه: در این قسمت با runlevel ها آشنا شدیم و لول های مختلف اون رو دیدیم و روش های تغییر بین runlevel های مختلف را یاد گرفتیم . با initttab آشنا شدیم و جایگزین های جدید اون که upstart و systemd هستند رو دیدیم و دستوراتشون رو یادگرفتیم و یادگرفتیم چجوری میتونیم یک ماشین لینوکسی را به نحو احسن خاموش و یا ریبوت کنیم.
در قسمت چهارم از این دوره قراره که مفاهیم مربوط به هارد دیسک ها و طراحی چیدمان (layout) اون رو ببینیم و با LVM هم یه آشنایی ای پیدا کنیم.
اول از همه باید به این نکته اشاره کرد که در لینوکس همه چی یه درخت بزرگ هستش که با / (که بهش ریشه یا root گفته میشه) شروع میشه و هر فایل و پارتیشن و دیسک و سی دی و USB ای یه جایی توی این درخت قرار میگیره
در لینوکس دیوایس در دایرکتوری /dev/ تعریف میشوند مثلا اولین دیسک SCSI با نام dev/sda/ شناخته میشود دومین با نام dev/sdb/ و الی آخر ... دیسک ها باید پارتیشن بندی شوند ، هنگام پارتیش بندی دیسک بزرگ به تیکه های کوچک تری تقسیم میشود مثلا dev/sda1/ که اولین پارتیشن از اولین دیسک هستش.
جدول پارتیشن در master boot record یا همان MBR ذخیره میشود که اولین سکتور از هارد هستش ، پس خیلی اندازه اش بزرگ نیست. در MBR (چون که یک استاندارد قدیمی هستش) محدودیت هایی وجود دارد مثلا هاردها نهایتا تا ظرفیت 2 ترابایت را ساپورت میکردند و بیشتر از 4 پارتیشن primary نمیشود ایجاد کرد.
نکته : پارتیشن primary پارتیشنی هستش که درون اون میشه سیستم عامل رو نصب کرد.
برای حل مشکل 4 پارتیشن راه حلی ارائه شد به نام پارتیشن های extended که اجازه میداد درون اون 4 پارتیشن logical ( منطقی) اضافه بشود.
در لینوکس نام گذاری پارتیشن های logical همیشه از عدد 5 شروع میشود مثلا اگر 2 پارتیشن primary و دو پارتیشن logical داشته باشید به ترتیب به این شکل نام گذاری میشود : sda1, sda2, sda5, sda6
نکته : پارتیشن extended فقط یک ظرف خالی هستش برای قرار دادن پارتیشن های logical داخل آن
برای حل این مشکلات GUID Partion Table یا همان GPT به وجود آمد که امکان ساختن تا 128 پارتیشن primary را به ما میدهد و هاردهایی با ظرفیت بیشتر از 2 ترابایت را هم پشتیبانی میکند.
لینوکس ابزار های مختلفی برای مدیریت دیسک دارد که به 3 تای اونها اشاره میکنم:
sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.32.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk /dev/sda: 420 GiB, 450971566080 bytes, 880803840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x4cbe73ef
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 20971519 18872320 9G 8e Linux LVM
sudo parted /dev/sda p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sda: 451GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1075MB 1074MB primary ext4 boot
2 1075MB 10.7GB 9663MB primary lvm
بعضی وقتا نیازه که سایز پارتیشن بندی هامون رو تغییر بدیم یا یه دیسک جدید اضافه میکنیم و میخوایم اون رو به نقطه ای که دیسک های دیگرمون رو مانت کردیم اضافه کنیم. به طور خلاصه LVM به ما کمک میکنه که یدونه پارتیشن از چندتا دیسک متفاوت ایجاد کنیم ، چجوری؟ اول چندتا مفهوم رو باید بفهمیم:
volume group ها مجموعه ای از physical volume ها و logical volume ها هستند و کار واسط بین این دو رو انجام میدهند. از اونجایی که هر physical volume فقط میتونه روی یک دیسک وجود داشته باشه ، داخل هر دیسک یک یا چندتا physical volume میسازیم و بعد همه رو داخل یک volume group قرار میدیم تا بتونیم باهاش logical volume های لازم خودمون رو بسازیم.
نکته: چون بوت لودر نمیتونه از توی logical volume پوشه ی boot/ رو بخونه ، اگر روت (/) در یک logical volume هستش، باید یک پارتیشن
جداگانه برای boot/ بسازید که عضو volume group نباشه!
volume group میتواند تقسیم به چند logical volume بشود؛ که میتواند محل های مانت شده مثل home/ و یا / باشد و فایل سیستم هایی مثل ext2 یا ext3 داشته باشند. وقتی پارتیشن ها (logical volumes) ظرفیتشون پر میشه ، ظرفیت خالی از volume group میتواند به اونها اضافه شود تا سایزشون افزایش پیدا کند همینطور وقتی هارد درایو جدیدی هم به سیستم اضافه میکنیم ، میتواند به volume group اضافه شود و پارتیشن ها (logical volumes) هم سایزشون افزایش پیدا کنه.
طراحی چیدمان هارد بستگی به کار شما با دستگاه لینوکسی داره و برای هر زمینه ای متفاوت هستش ولی قبل از اینکه شروع به توضیح راجع به این زمینه کنم باید با دو مورد swap و boot رو براتون توضیح بدم.
swap : به عنوان مموری اضافه برای سیستم لینوکس کار میکنه ، وقتی که مموری دستگاه کم میاد ، کرنل بخشی از مموری رو توی این پارتیشن/فایل به اصطلاح page میکنه. برای استفاده از این قابلیت کافیه که یک پارتیشن رو با swap file system فرمت کنید و توی بخش etc/fstab/ تعریفش کنید ( توی درس های آینده بهش میرسیم)
نکته : پیشنهاد شده که سایز swap دوبرابر رم تعریف بشه و نهایتا از 8 گیگابایت هم بیشتر نشه!
boot/ : لینوکس های قدیمی تر نمیتونستند که هارد های بزرگ ( ترابایتی) رو در زمان بوت به کار ببرند پس بخش boot/ رو جدا میکردند. و اینکار یه مزیتی هم که داره اینکه هنگام ریکاور کردن یه سیستم خراب به کمکمون میاد و حتی میشه read only هم کردتش. میتونید یا پارتیشن جدایی برای boot/ درست کنید یا یه دیسک کلا جدا که بیشتر اوقات 100 مگابایت براش کافیه. و همینطور که توی بخش LVM اشاره کردم باید جایی باشه که بایوس بتونه بهش دسترسی پیداش کنه ( مثلا روی شبکه نباشه)
روی کامپیوتر های خونگی نیاز به وسواس زیاد نیست ولی خوبه که هارد به سه پارتیشن تقسیم بشه :
همونطور که میدونید boot/ فقط باید روی خود هر ماشینی باشد و بیشتر اوقات هم برای / نیز همین حالت است ولی میشود home/ را به صورت مانت شده روی شبکه داشته باشیم تا هر کاربر پشت هر سیستمی که نشست به فایل های خودش دسترسی داشته باشد. swap هم میشود هم به صورت local باشد هم تحت شبکه.
در سرور هم boot/ باید به صورت local باشد. home/ میتواند local یا تحت شبکه باشد. و در خیلی از موارد ما var/ رو جدا میکنیم چون اگه هارد مشکل خورد log ها و ... آسیب نبینند. بعضی ها usr/ رو هم جدا میکنند و read only ش میکنند تا آسیبی نبینه( حتی میشه از روی شبکه مانت ش کرد تا اگر نیازی بود توی این دایرکتوری تغییراتی انجام بشه ، به راحتی تغییرات را در کل شبکه اعمال کنیم). روی سرور معمولا swap قرار نمیدهند چون سرور باید سرعت بالا داشته باشه و swap کندش میکنه.
خلاصه : با ساختار دایرکتوری های لینوکس آشنا شدیم و بخش های مختلف اون رو توضیح دادیم ، پارتیشن بندی های نوع دیسک ها ، MBR و GPT رو دیدیم و یادگرفتیم که چه ابزارهایی برای مدیریت دیسک در لینوکس وجود داره. با LVM آشنا شدیم و روش کارش رو دیدیم ، فهمیدیم که چیدمان هارد در لینوکس چجوریه و طراحی چیدمان برای کامیپوتر خانگی ، کامپیوتر تحت شبکه و سرور رو یاد گرفتیم.
در قسمت پنجم از این دوره با هم نگاهی کلی به بوت کردن سیستم میندازیم و بوت منیجرها مختلف از جمله GRUB v2 رو بررسی میکنیم. در آخر این درس شما میتونید یک بوت منیجر رو انتخاب ، کانفیگ و نصب کنید.
وقتی سیستم روشن میشود BIOS شروع به کار میکند و مراحل POST که یک تست از قطعات کامپیوتر هستش رو انجام میده بعدش ادامه مراحل بوت شدن رو به MBR میده که روی اول سکتور از هارد ذخیره شده. MBR فقط 512 بایت اندازه ش هستش و نیاز به یک بوت لودر داره که در لینوکس موارد زیادی هستش از جمله LILO و GRUB و GRUB2 که با هم بررسی شون میکنیم.
Chain Loading : وقتی که یک بوت لودر ، یک بوت لودر دیگر را لود میکند ، مثلا وقتی که بوت لودر لینوکس نیاز دارد که یک سیستم ویندوزی را بالا بیاورد ، مراحل بوت را به بوت لود ویندوز انتقال میدهد و خودش کنار میرود.
ممکنه این سوال براتون پیش بیاد که تفاوت boot loader و boot manager در چیه؟
چون در قسمت 2 از این سری آموزش هم راجع به بوت کردن صحبت کردیم و در اونجا نام boot loader رو هم بردیم ؛ در اصل ما دو نوع boot loader داریم : boot loader مرحله ی اول و boot loader مرحله ی دوم. boot loader مرحله اول همون BIOS هستش ( یا نمونه های مشابه ش مثل Libreboot) که بعد از انجام دادن کارهای مربوطه کنترل رو به MBR و در نتیجه بهboot loader مرحله ی دوم میده، boot loader مرحله ی دوم باید هوشمند باشه تا بتونه در صورت نیاز چندین سیستم عامل مختلف رو بوت کنه پس در نتیجه میشه بهش گفتش مدیر بوت یا boot manager.
اولین بوت لودری که بررسی میکنیم یکی از قدیم ترین بوت لودرهای لینوکس هستش و این روزها خیلی کم پیش میاد که ببینیمش ، منظورم LILO هست که مخفف LInux LOader میشه. فایل کانفیگش در مسیر etc/lilo.conf/ پیدا میشه و با دستور usr/sbin/liloconfig/ میشه فایل کانفیگ رو ساخت:
# Originally generated by liloconfig - modified by Ian Shields
# This allows booting from any partition on disks with more than 1024
# cylinders.
lba32
# Specifies the boot device (floppy)
boot=/dev/fd0
# Specifies the device that should be mounted as root.
# If the special name CURRENT is used, the root device is set to the
# device on which the root file system is currently mounted. If the root
# has been changed with -r , the respective device is used. If the
# variable ROOT is omitted, the root device setting contained in the
# kernel image is used. It can be changed with the rdev program.
root=/dev/sda7
# Bitmap configuration for /boot/coffee.bmp
bitmap=/boot/coffee.bmp
bmp-colors=12,,11,15,,8
bmp-table=385p,100p,1,10
bmp-timer=38,2,13,1
# Enables map compaction:
# Tries to merge read requests for adjacent sectors into a single
# read request. This drastically reduces load time and keeps the map
# smaller. Using COMPACT is especially recommended when booting from a
# floppy disk.
compact
# Install the specified file as the new boot sector.
# LILO supports built in boot sectors, you only need
# to specify the type, choose one from 'text', 'menu' or 'bitmap'.
# new: install=bmp old: install=/boot/boot-bmp.b
# new: install=text old: install=/boot/boot-text.b
# new: install=menu old: install=/boot/boot-menu.b or boot.b
# default: 'menu' is default, unless you have a bitmap= line
# Note: install=bmp must be used to see the bitmap menu.
# install=menu
install=bmp
# Specifies the number of _tenths_ of a second LILO should
# wait before booting the first image. LILO
# doesn't wait if DELAY is omitted or if DELAY is set to zero.
# delay=20
# Prompt to use certain image. If prompt is specified without timeout,
# boot will not take place unless you hit RETURN. Timeout is in tenths of
# a second.
prompt
timeout=200
# Enable large memory mode.
large-memory
# Specifies the location of the map file. If MAP is
# omitted, a file /boot/map is used.
map=/boot/map
# Specifies the VGA text mode that should be selected when
# booting. The following values are recognized (case is ignored):
# NORMAL select normal 80x25 text mode.
# EXTENDED select 80x50 text mode. The word EXTENDED can be
# abbreviated to EXT.
# ASK stop and ask for user input (at boot time).
# <number> use the corresponding text mode. A list of available modes
# can be obtained by booting with vga=ask and pressing [Enter].
vga=normal
# Defines non-standard parameters for the specified disk.
#disk=/dev/sda
# bios=0x80
# If you are using removable USB drivers (with mass-storage)
# you will need to tell LILO to not use these devices even
# if defined in /etc/fstab and referenced in /proc/partitions.
# Adjust these lines to your devices:
#
# disk=/dev/sda inaccessible
# disk=/dev/sdb inaccessible
# These images were automagically added. You may need to edit something.
image=/boot/vmlinuz-2.6.31-14-generic
label="Lin 2.6.31-14"
initrd=/boot/initrd.img-2.6.31-14-generic
read-only
image=/boot/vmlinuz-2.6.31-20-generic
label="Lin 2.6.31-20"
initrd=/boot/initrd.img-2.6.31-20-generic
read-only
image=/boot/memtest86+.bin
label="Memory Test+"
read-only
# If you have another OS on this machine (say DOS),
# you can boot if by uncommenting the following lines
# (Of course, change /dev/sda1 to wherever your DOS partition is.)
other=/dev/sda6
label="Fedora 8"
other=/dev/sda1
label="Windows XP"
و با دستور lilo میتونیم دیسک خودمون رو bootable کنیم:
# lilo -v -v
LILO version 22.8, Copyright (C) 1992-1998 Werner Almesberger
Development beyond version 21 Copyright (C) 1999-2006 John Coffman
Released 19-Feb-2007, and compiled at 10:52:38 on Aug 25 2009
Running Linux kernel 2.6.31-14-generic on i686
Ubuntu
raid_setup returns offset = 00000000 ndisk = 0
BIOS VolumeID Device
Reading boot sector from /dev/fd0
pf_hard_disk_scan: ndevs=1
0800 54085408 /dev/sda
device codes (user assigned pf) = 0
device codes (user assigned) = 0
device codes (BIOS assigned) = 1
device codes (canonical) = 1
mode = 0x03, columns = 80, rows = 25, page = 0
Using BITMAP secondary loader
Calling map_insert_data
Secondary loader: 19 sectors (0x3800 dataend).
Warning: The boot sector and map file are on different disks.
bios_boot = 0x00 bios_map = 0x80 map==boot = 0 map S/N: 54085408
Mapping bitmap file /boot/coffee.bmp
Calling map_insert_file
Compaction removed 592 BIOS calls.
Bitmap: 603 sectors.
BIOS data check was okay on the last boot
Boot image: /boot/vmlinuz-2.6.31-14-generic
Setup length is 26 sectors.
Compaction removed 7452 BIOS calls.
Mapped 7601 sectors.
Mapping RAM disk /boot/initrd.img-2.6.31-14-generic
Compaction removed 14696 BIOS calls.
RAM disk: 14930 sectors.
Added Lin_2.6.31-14 *
Boot image: /boot/vmlinuz-2.6.31-20-generic
Setup length is 26 sectors.
Compaction removed 7468 BIOS calls.
Mapped 7617 sectors.
Mapping RAM disk /boot/initrd.img-2.6.31-20-generic
Compaction removed 14704 BIOS calls.
RAM disk: 14938 sectors.
Added Lin_2.6.31-20
Boot image: /boot/memtest86+.bin
Setup length is 4 sectors.
Compaction removed 243 BIOS calls.
Mapped 254 sectors.
Added Memory_Test+
Boot other: /dev/sda6, loader CHAIN
Pseudo partition start: 43198848
Compaction removed 0 BIOS calls.
Mapped 6 (4+1+1) sectors.
Added Fedora_8
Boot other: /dev/sda1, on /dev/sda, loader CHAIN
Compaction removed 0 BIOS calls.
Mapped 6 (4+1+1) sectors.
Added Windows_XP
BIOS VolumeID Device
80 54085408 0800
Writing boot sector.
/boot/boot.0200 exists - no boot sector backup copy made.
Map file size: 336896 bytes.
RAID device mask 0x0000
One warning was issued.
که با سوئیچ های v- میتونیم میزان توضیحات داده شده توسط دستور رو زیاد کنیم و شما میتونید تا 5 تا v قرار بدید! چندتا دیگه از سوئیچ های مهم LILO در زیر اومده:
سوئیچ | کاربرد |
---|---|
q- | اطلاعاتی راجع به map فایل بهمون میده که در مسیر boot/map/ قرار داره و شامل کانفیگ های بوت هستش |
R- | فقط توی ریبوت بعدی سیستم رو بوت میکنه ، که معمولا برای سیستم های ریموت استفاده میشه |
l- | لیست اطلاعات راجع به کرنل |
u- | LILO رو پاک میکنه و بوت رکورد قبلی رو برمیگردونه |
وقتی توی منوی LILO هستید با زدن TAB روی آیتم مورد نظر میتونید ویرایشش کنید.
GRUB مخفف GRand Unified Bootloader که بوت لودر جدید تری نسبت به LILO هستش. فایل کانفیگ GRUB ورژن 1 ( در اصل 0.9) در مسیر boot/grub/grub.conf/ ذخیره شده و boot/grub/menu.lst/ هم یک symbolic link بهش هستش که توی درسای بعدی راجع بهش صحبت میکنیم. در زیر یک نمونه از کانفیگ GRUB v1 رو میبینید:
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
# all kernel and initrd paths are relative to /, eg.
# root (hd0,5)
# kernel /boot/vmlinuz-version ro root=/dev/sda6
# initrd /boot/initrd-version.img
#boot=/dev/sda6
default=1
timeout=10
splashimage=(hd0,5)/boot/grub/splash.xpm.gz
#hiddenmenu
password --md5 $1$RW1VW/$4XGAklxB7/GJk0uO47Srx1
title Upgrade to Fedora 11 (Leonidas)
kernel /boot/upgrade/vmlinuz preupgrade \
repo=hd::/var/cache/yum/preupgrade stage2=\
hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/install.img \
ks=hd:UUID=8b4c62e7-2022-4288-8995-5eda92cd149b:/boot/upgrade/ks.cfg
initrd /boot/upgrade/initrd.img
title Fedora (2.6.26.8-57.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.8-57.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.8-57.fc8.img
title Fedora (2.6.26.6-49.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.6-49.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.6-49.fc8.img
title GRUB Menu
rootnoverify (hd0,1)
chainloader +1
title Windows
rootnoverify (hd0,0)
chainloader +1
همونطور که میبینید بخش اول به GRUB میگه که چه کاری انجام بده و بخش دوم گزینه های بوت رو ارائه میده مثلا :
title Fedora (2.6.26.6-49.fc8)
root (hd0,5)
kernel /boot/vmlinuz-2.6.26.6-49.fc8 ro root=LABEL=FEDORA8 rhgb quiet
initrd /boot/initrd-2.6.26.6-49.fc8.img
توی خط اول میگه اسمی که قراره نمایش بدی Fedora باشه
توی خط دوم میگه که سیستم عامل رو از رو هارد اول ( هارد شماره 0) پارتیشن شماره 5 بخون
توی خط سوم میگه که کرنل این سیستم عامل کجاست
و توی خط چهارم آدرس init سیستم عامل کجاست
همینطور یک مثال هم از Chain Loader هستش:
title Windows
rootnoverify (hd0,0)
chainloader +1
که خط اول میگه اسمش رو ویندوز نمایش بده
در خط دوم میگه که لازم نیست verify روش انجام بدی ( کاری نداشته باش چیه) و از روی هارد اول (شماره ی 0) پارتیشن اول (شماره ی 0) بخونش ( توجه داشته باشید که توی GRUB ورژن 1 اعداد از 0 شروع میشن ولی در GRUB2 اعداد از 1)
و توی خط سوم میگه که ادامه ی مراحل بوت رو بده به بوت لودر خود اون سیستم عامل
در زیر هم مجموعه ی Option های مختلف برای این فایل اومده:
دستور | کاربرد |
---|---|
# | کامنت کردن اون خط |
default | سیستم پیش فرض برای بوت ( شروع از 0) |
timeout | چقدر تایم قبل از بوت خودکار مکث شود |
splashimage | عکس پس زمینه |
password | هنگام بوت این رمز که ارائه میشه پرسیده میشود |
title | نام اون بخش |
root | پارتیشنی که باید بوت شود |
kernel | چه کرنلی باید load شود |
initrd | مسیر init ، ماژول هایی اولیه ای که کرنل قبل از مانت شدن فایل سیستم نیاز دارد |
savedefault | آخرین آیتمی که بوت شده است |
chainloader | نشان دهنده ی chain loader هست که بالاتر توضیح دادم |
برای نصب GRUB ورژن 1 از یکدام از دستورات زیر استفاده میشود:
# grub-install /dev/fd0
# grub-install '(fd0)'
که در این مثال GRUB را روی فلاپی دیسک 1 نصب میکند، ولی میشود روی CD یا MBR که مثلا sda هستش یا حتی پارتیشن مثلا sdb2 نصب کرد.
متداول ترین بوت لودری که این روزها استفاده میشود GRUB2 میباشد . فایل اصلی کانفیگ در مسیر boot/grub/grub.cfg/ هستش و میشود با دستور:
grub-mkconfig > /boot/grub/grub.cfg
هم ایجادش کرد .علاوه بر این با دستور update-grub نیز میتوان این کار را انجام داد. همچنین GRUB بسیار به فایل core.img که در مسیر boot/grub/ هستش وابسته هست.
نکته: در بسیاری از سیستم ها دستورات و مسیرها به جای grub خالی با grub2 قابل دسترسی هستند.
با اجرای دستور:
grub-install /dev/sda
GRUB2 یک فایل core image و یک فایل کانفیگ ایجاد میکنه و GRUB2 رو روی MBR نصب میکنه که میشه تمامی این مراحل را جداگانه نیز طی کرد. در زیر یک نمونه از فایل کانفیگ GRUB2 هستش:
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
set pager=1
if [ -f ${config_directory}/grubenv ]; then
load_env -f ${config_directory}/grubenv
elif [ -s $prefix/grubenv ]; then
load_env
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${saved_entry}"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
terminal_output console
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=5
fi
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/00_tuned ###
set tuned_params=""
set tuned_initrd=""
### END /etc/grub.d/00_tuned ###
### BEGIN /etc/grub.d/01_users ###
if [ -f ${prefix}/user.cfg ]; then
source ${prefix}/user.cfg
if [ -n "${GRUB2_PASSWORD}" ]; then
set superusers="root"
export superusers
password_pbkdf2 root ${GRUB2_PASSWORD}
fi
fi
### END /etc/grub.d/01_users ###
### BEGIN /etc/grub.d/08_fallback_counting ###
insmod increment
# Check if boot_counter exists and boot_success=0 to activate this behaviour.
if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then
# if countdown has ended, choose to boot rollback deployment,
# i.e. default=1 on OSTree-based systems.
if [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then
set default=1
set boot_counter=-1
# otherwise decrement boot_counter
else
decrement boot_counter
fi
save_env boot_counter
fi
### END /etc/grub.d/08_fallback_counting ###
### BEGIN /etc/grub.d/10_linux ###
insmod part_msdos
insmod ext2
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 57479d0d-15e1-43c2-9e51-e775c42dcca0
else
search --no-floppy --fs-uuid --set=root 57479d0d-15e1-43c2-9e51-e775c42dcca0
fi
insmod part_msdos
insmod ext2
set boot='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=boot --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 57479d0d-15e1-43c2-9e51-e775c42dcca0
else
search --no-floppy --fs-uuid --set=boot 57479d0d-15e1-43c2-9e51-e775c42dcca0
fi
# This section was generated by a script. Do not modify the generated file - all changes
# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
#
# The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and
# populates the boot menu. Please refer to the Boot Loader Specification documentation
# for the files format: https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/.
set default_kernelopts="root=/dev/mapper/cl-root ro crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet "
insmod blscfg
blscfg
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/10_reset_boot_success ###
# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry
if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then
set menu_hide_ok=1
else
set menu_hide_ok=0
fi
# Reset boot_indeterminate after a successful boot
if [ "${boot_success}" = "1" ] ; then
set boot_indeterminate=0
# Avoid boot_indeterminate causing the menu to be hidden more then once
elif [ "${boot_indeterminate}" = "1" ]; then
set boot_indeterminate=2
fi
# Reset boot_success for current boot
set boot_success=0
save_env boot_success boot_indeterminate
### END /etc/grub.d/10_reset_boot_success ###
### BEGIN /etc/grub.d/12_menu_auto_hide ###
if [ x$feature_timeout_style = xy ] ; then
if [ "${menu_show_once}" ]; then
unset menu_show_once
save_env menu_show_once
set timeout_style=menu
set timeout=60
elif [ "${menu_auto_hide}" -a "${menu_hide_ok}" = "1" ]; then
set orig_timeout_style=${timeout_style}
set orig_timeout=${timeout}
if [ "${fastboot}" = "1" ]; then
# timeout_style=menu + timeout=0 avoids the countdown code keypress check
set timeout_style=menu
set timeout=0
else
set timeout_style=hidden
set timeout=1
fi
fi
fi
### END /etc/grub.d/12_menu_auto_hide ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/20_ppc_terminfo ###
### END /etc/grub.d/20_ppc_terminfo ###
### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/30_uefi-firmware ###
### END /etc/grub.d/30_uefi-firmware ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f ${config_directory}/custom.cfg ]; then
source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
که کاملا با ورژن قبلی متفاوت شده. البته لازم نیست که این فایل رو جز به جز بدونید چون اصلا در همون اولش نوشته که این فایل توسط grub2-mkconfig ایجاد میشه و به صورت دستی نباید ویرایش بشه! خلاصه: در این قسمت توضیحات مختصری راجع به بوت دادیم و به بررسی بوت لودر های مختلف پرداختیم و با فایل ها و دستورات آنها آشنا شدیم.
در قسمت ششم این دوره نگاهی خواهیم داشت به کتابخانه های لینوکس، انواع اون و دستورات مربوط به اونها . در انتهای این قسمت میتونید که کتابخانه های اشتراکی ( shared libraries) رو که اجرای برنامه ها به اونها وابسته است رو تشخیص بدید و در صورت نیاز نصب کنید.
هنگام نوشتن یک برنامه ، برنامه نویس ممکن است نیاز به انجام کارهای مختلفی داشته باشد ، مثلا گرفتن ورودی از کاربر یا مثلا باز کردن یه فایل ویدیویی، برای انجام این کارها ، نیاز نیست که برنامه نویس از اول آن را برای برنامه ی خودش بنویسد در عوض برای اینکار از library ها استفاده میکند و موقعی که کار خاصی را میخواد انجام دهد به اصطلاح اون لایبری را صدا میزند. لایبری ها به دو نوع کلی هستند: لایبری های استاتیک (static) یا لایبری های داینامیک (dynamic)
لایبری های داینامیک با نام shared libraries نیز شناخته میشوند چون بین برنامه های مختلفی که جداگانه نصب شده اند به اشتراک گذاشته شده است.
اول از همه ، لایبری ها کجا قرار دارند؟ برای سیستم های 32 بیتی در lib/ و برای سیستم های 64 بیتی lib64/
این دستور کمک میکند که :
مثال اول :
└─$ ldd /sbin/ldconfig
statically linked
مثال دوم:
└─$ ldd /usr/bin/man
linux-vdso.so.1 (0x00007fff6a556000)
libmandb-2.9.4.so => /usr/lib/man-db/libmandb-2.9.4.so (0x00007f5a2cb37000)
libman-2.9.4.so => /usr/lib/man-db/libman-2.9.4.so (0x00007f5a2caf4000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f5a2cac0000)
libpipeline.so.1 => /lib/x86_64-linux-gnu/libpipeline.so.1 (0x00007f5a2caaf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5a2c8ea000)
libgdbm.so.6 => /lib/x86_64-linux-gnu/libgdbm.so.6 (0x00007f5a2c8da000)
libseccomp.so.2 => /lib/x86_64-linux-gnu/libseccomp.so.2 (0x00007f5a2c8b5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5a2cb5f000)
همونطور که میبیند در مثال اول به ما میگوید که دستور ldconfig دستوری هستش که به صورت استاتیک لینک شده و در مثال دوم به ما لایبری های دستور man را نشان میدهد.
فرض کنید برنامه ای دارید مینویسد که نیاز دارد از udev استفاده کند شما توی برنامه تعریف میکنید که لایبری libudev.so.1 رو صدا بزنه ولی ممکنه توی یک توزیع لینوکس ورژن libudev.so.1.4.0 نصب باشه ، پس قاعدتا برنامه متوجه نمیشه این لایبری هست و نمیتونه کار کنه. برای حل این مشکل symbolic link ها ابداع شدند که کارشون اینکه یه اسم جدید برای همون فایل ایجاد کنه برای دیدن یک سمبولیک لینک اول محل لایبری ای که میخوایم رو پیدا میکنیم:
└─$ locate libudev.so.1
/usr/lib/x86_64-linux-gnu/libudev.so.1
/usr/lib/x86_64-linux-gnu/libudev.so.1.7.0
که به ما دونسخه از libdev رو نشون میده ، ما آدرس اولی رو به دستور زیر میدیم:
└─$ ls -l /usr/lib/x86_64-linux-gnu/libudev.so.1
lrwxrwxrwx 1 root root 16 Apr 12 22:51 /usr/lib/x86_64-linux-gnu/libudev.so.1 -> libudev.so.1.7.0
که نشون میده فایل libudev.so.1.7.0 در اصل یک سمبولیک لینک به libudev.so.1 هستش!
مثل بقیه ی ی ابزارهای لینوکسی ، لینک های داینامیک هم میتونن توسط یک فایل کانفیگ ، تنظیم بشند این فایل در آدرس etc/ld.so.conf/ قرار داره که توی سیستم های اوبونتویی به فایل های کانفیگ توی /etc/ld.so.conf/ اشاره میکنه ولی میشه تمامی اون خط ها رو توی فایل اصلی نیز اورد.
└─$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
که در اون دایرکتوری فایل های کانفیگ هستش:
└─$ ls /etc/ld.so.conf.d/
fakeroot-x86_64-linux-gnu.conf libc.conf oracle.conf x86_64-linux-gnu.conf zz_i386-biarch-compat.conf
که توی اون فایل های کانفیگ به آدرس اون لایبری اشاره میشه:
└─$ cat /etc/ld.so.conf.d/fakeroot-x86_64-linux-gnu.conf
/usr/lib/x86_64-linux-gnu/libfakeroot
و از این بخش هستش که سیستم همیشه میتونه آدرس هر لایبری رو پیدا کنه. ولی خوندن دونه دونه ی این فایل ها برای سیستم کنده پس سیستم یک فایل ld.so.cache هم در کنار فایل کانفیگ درست میکنه برای دسترسی سریع تر، در صورت تغییر ld.so.conf و ( یا کانفیگ های زیرمجموعه اش ) میتوانید این فایل به صورت دستی توسط دستور ldconfig بسازید. با دستور زیر میتوانید اطلاعات ذخیره شده داخل ld.so.cache رو ببینید:
└─$ ldconfig -p | less
1180 libs found in cache `/etc/ld.so.cache'
libz3.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz3.so.4
libz3.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libz3.so
libzvbi.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzvbi.so.0
libzvbi-chains.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzvbi-chains.so.0
libzstd.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzstd.so.1
libzmq.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzmq.so.5
libzip.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzip.so.4
libzip.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libzip.so
libz.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so.1
libz.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so
...
گاهی اوقات لازم هستش که به جای لایبری های نصب شده، لایبری ای که خودتون لازم دارید رو به سیستم بدید که ممکن است به دلایل این باشه که:
در این موارد شما میتوانید از یک متغییر محیطی(environment variable) به نام LD_LIBARARY_PATH استفاده کنید. که به سیستم میگه قبل از چک کردن کش ببینه آیا لایبری مورد نظرش توی مسیر های داده شده هست یا نه.
برای مثال میشه دستور زیر رو داد:
└─$ export LD_LIBARARY_PATH=/mnt/c/Users/Mahdi/libs/:/home/Mahdi/otherlibs
که با جدا کردن مسیر ها با دونقطه (:) میتونیم چنیدن مسیر به متغییرمون بدیم که به ترتیب چک کنه.
با دادن دستور export میشود متغییر های محیطی را دید و با دادن پارامتر n- و نام متغییر محیطی اون رو پاک کرد.
خلاصه: در این درس به انواع لایبری ها که دو نوع استاتیک و داینامیک هستند پرداختیم و با دستورات و تنظیمات مربوط به لایبری ها از قبیل ldd و ldconfig آشنا شدیم همچنین نگاهی هم به متغییرهای محیطی داشتیم و فهمیدیم چگونه میشود یک متغیر محیطی تعریف کرد و چگونه میشود با متغییرها محیطی لایبری مورد نیازمان را به سیستم بدهیم.
در قسمت هفتم این دوره نگاهی خواهیم داشت به مدیر بسته ها و روش نصب برنامه های جدید روی سیستم های Debian بیس. در انتهای این درس شما میتونید بسته ها را آپگرید کنید ، نصب کنید و یا حذف کنید، بسته هایی که شامل یک فایل خاص یا لایبری خاص هستن رو چه نصب باشن چه نصب نباشن پیدا کنید و اطلاعاتی راجع به بسته ها شامل ورژن ، محتوای آن، وابستگیها (dependencies) ، درستی بسته ها و وضعیت نصب رو به دست بیاورید.
نصب برنامه روی لینوکس بر اساس کامپایل کردن سورس کد بوده ولی بعدش توزیع های مختلف از راه رسیدند و در همان زمان عرضه، ابزار هایی مثل apt-get را معرفی کردند. بیشتر توزیع ها از مدیر بسته ی خودشون بهره میبرند که به صورت پیشفرض روشون نصب هست و از repository های مختلف برنامه ها را دانلود میکنه، که کاملا مطمئن و ایمن هستند. توزیع های مبتنی بر دبیان از پسوند deb. و از دستورات apt و dpkg و aptitude استفاده میکنند که در این درس به بررسی اونها میپردازیم و در درس بعدی به توزیع هایی مثل Fedora , RHEL , SUSE و ... میپردازیم که از مدیر های بسته ی RPM و YUM استفاده میکنند.
مثلا من روی سیستمم برنامه ی brz رو ندارم:
که خود سیستم راهنمایی میکنه که به وسیله ی چه دستوری میشه بسته رونصب کرد ، پس برنامه رو با دستور
Sudo apt install brz
یا
Sudo apt-get install brz
که مشابه هم هستند ، نصب میکنیم (فقط توجه داشته باشید برای تغییرات روی پکیج ها حتما باید دسترسی روت داشته باشید) :
اگر دقت کنید مدیرت بسته همون اول یک درخت وابستگی درست میکنه تا تمامی فایل های مورد نیاز برنامه رو دریافت کنه بعدش میگه برنامه چه میزانی دانلود میکنه و بعد از نصب چه مقداری از هارد رو اشغال میکنه و منتظر تایید میمونه که به صورت دیفالت در حال نمایش Y هستش که با زدن Enter برنامه رو نصب میکنه و با زدن n عملیات نصب متوقف میشود. سوئیچ هایی هم برای دستور apt وجود دارد ، مثلا با سوئیچ s- بدون اینکه برنامه رو نصب کنه ، مراحل نصب را رو شبیه سازی میکنه. با سوئیچ d- میتوانید فایل های بسته را بدون نصب آن دانلود کنید و به فایل deb. آن در مسیر /var/cache/apt/archives/ دسترسی داشته باشید. برای نصب یک پکیج از قبل دانلود شده فقط کافی است مسیر و نام کامل آن را به دستور apt یا apt-get بدهید.
برای حذف یک بسته خیلی راحت میتونید به جای install دستور remove را بزارید که خود بسته را حذف میکند و یا با دادن autoremove ، تمامی dependency هایی که فقط برای بسته ی مذکور نصب شده است را هم حذف میکند:
$ apt-get autoremove bzr
حتی میشود دستور autoremove را بدون نام بسته داد که تمامی بسته ها و dependency هایی که دیگر لازم نیستند را به طور خودکار حذف کند:
$ apt-get autoremove
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
linux-image-3.16.0-25-generic linux-image-extra-3.16.0-25-generic
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
After this operation, 203 MB disk space will be freed.
Do you want to continue? [Y/n] y
نکته: هنگام remove کردن یک بسته dependency های آن حذف نمیشود ولی هنگام حذف یک dependency هشداری مبنی بر حذف تمامی بسته های مربوط به آن داده میشود.
پکیج هایی که دانلود میکنیم از کجا می آیند؟ خب جایی هستش که بهش میکن repository که به سیستم میگه هر پکیجی را از کجا دانلود کند. Repository ها در فایل etc/apt/sources.list/ و فایل هایی که در آدرس /etc/apt/sources.list.d/ هستند ، قرار دارند.
برای جستجوی پکیج ها برای دانلود میتوانید از دستور:
apt-cache search "anything you want to find"
استفاده کنید که داخل کش apt را جستجو میکند و تمامی برنامه هایی که با جستجوی شما مطابق باشد را نمایش میدهد.
برای آپدیت کردن repository ها و لیست برنامه های قابل آپدیت از دستور :
apt[-get] update
استفاده میشود. (منظور از قرار دادن get- داخل براکت [ ] این است که گذاشتن آن اختیاری است یعنی میتوانید یا از دستور apt یا apt-get استفاده کنید!)
برای ارتقای تمامی بسته های نصب شده به آخرین ورژن از دستور:
apt[-get] upgrade
استفاده میشود ، که میشود با دادن اسم بسته ی خاصی هم فقط آن بسته را آپگرید کرد.
همچنین میشود از طریق دستور زیر خود توزیع مربوطه را آپگرید کرد:
apt[-get] dist-upgrade
همانند باقی ابزارهای لینوکس از طریق دایرکتوری etc/apt/ میتوانید به تنظیمات برنامه دسترسی داشته باشید یا از طریق دستور apt-config تنظیمات لازم را انجام دهید.
بعضی برنامه ها بعد نصب تنظیمات اولیه ای را ارائه میدهند برای دسترسی دوباره به آن تنظیم ها میتوانید از دستور dpkg-reconfigure استفاده کنید:
Dpkg یک ابزار بسیار قدرتمند برای کار با فایل های deb. هستش. dpkg میتواند بسته ها را نصب ، حذف ، کانفیگ کند یا حتی از آنها کوئری بگیرد تنظیماتش در etc/dpkg/dpkg.cfg/ هستش و از درخت var/lib/dpkg/ برای مدیریت dependency ها استفاده میکند برای دیدن اطلاعات داخل یک پکیج میشود از سوئیچ contents-- استفاده کرد:
سوئیچ مهم دیگری که وجود دارد سوئیچ s- میباشد که وضعیت یک برنامه یا دایکرتوری آن را نشان میدهد:
با سوئیچ P- و یا purge-- تمامی اطلاعات ذخیره شده در مورد بسته همراه با خود بسته به طور کامل از سیستم پاک خواهند شد. سوئیچ دیگری که وجود دارد L- هستش که تمامی فایل های نصب شده توسط یک برنامه را نشان میدهد:
همچنین به وسیله ی دستوراتی مثل type و which و whereis میتوانید ببینید هر دستوری چه فایلی را استفاده میکند:
یک ابزار جدید تر و راحت تر ابزار aptitude میباشد که تمامی امکانات را در اختیار شما قرار میدهد و علاوه بر این یک محیط شبه گرافیکی نیز دارد که با دستور aptitude اجرا میشود:
و یا از دستوراتی مثل دستورات زیر استفاده کنید:
$ aptitude install jcal
$ aptitude remove jcal
$ aptitude search cal
$ aptitude show bzr
همچنین مدیرهای بسته ی گرافیکی ای هم وجود دارد مانند sysnaptic و update manager که نصب و آپدیت و آپگرید و جستجو و پاک کردن و ... رو از طریق یک رابط کاربری گرافیکی در اختیار شما قرار میدهد.
خلاصه: در این درس با مدیر های بسته از جمله apt و apt-get و aptitude آشنا شدیم و دستورات مربوط به انها را دیدیم ، همچنین یاد گرفتیم چجوری میشود بسته ها را نصب ، حذف ، آپدیت و آپگرید کرد؛ چگونه میشود یک بسته ی جدید را جستجو کنیم ، چگونه از ابزار dpkg برای دیدن اطلاعات مربوط به یک فایل deb. استفاده کنیم و یا اطلاعات مربوط به یه بسته ی نصب شده را ببینیم و ببینیم چه فایل هایی را همراه خودش نصب کرده است ، همچنین روش اپگرید خود توزیع لینوکس را دیدیم و یاد گرفتیم چگونه میشود تنظیمات اولیه ی یک بسته را بعد نصب تغییر داد.
در قسمت هشتم از این دوره نگاهی خواهیم داشت به مدیر بسته های YUM و RPM ، در انتهای این درس شما میتونید بسته ها رو نصب ، حذف و آپگرید کنید، اطلاعاتی راجع به بسته ها مثل ورژن و وضعیتشون ، dependency هاشون ، صحتشون و signature هاشون رو به دست بیارید ، بفهمید که چه فایل هایی توسط هر پکیج ارائه داده شده است و همینطور یک فایل خاص توسط چه پکیجی ساخته شده.
RedHat Package Manager (RPM) و Yellowdog Updater Modified (YUM) ابزارهای اصلی مدیریت بسته ها در توزیع های فدورا/ ردهت / RHEL / centos / SUSE و ... هستند، که تمامی قابلیت های اصلی مثل نصب و آپدیت کردن را در اختیار کاربران قرار میدهند.RPM فقط توانایی نصب از روی فایل های rpm. را دارد(که فرمت بسته ها در توزیع های نام برده شده است) YUM یک سری قابلیت های اضافه تر دارد مانند آپدیت اتوماتیک ، مدیریت وابستگی ها و کار با repository های مختلف (مثلا نصب از روی CD یا شبکه)
میخواهیم از برنامه ی bzr استفاده کنیم:
[root@localhost ~]# bzr
bash: bzr: command not found...
همونطور که میبینید این برنامه نصب نیست پس اگه فایل نصب rpm. آن را داشته باشیم با استفاده از دستور rpm -i نصب میکنیم:
[root@localhost ~]# rpm -i bzr-2.6.0-2.fc20.x86_64.rpm
error: Failed dependencies:
python-paramiko is needed by bzr-2.6.0-2.fc20.x86_64
ولی میبینید که بسته نصب نشد ، چون rpm متوجه dependency ها میشود ولی نمیتواند آنها را نصب کند پس برای نصب یک پکیج همراه با وابستگی های آن از دستور yum استفاده میکنیم:
[root@localhost ~]# yum install bzr
Loaded plugins: langpacks
Resolving Dependencies
--> Running transaction check
---> Package bzr.x86_64 0:2.6.0-2.fc20 will be installed
--> Processing Dependency: python-paramiko for package: bzr-2.6.0-2.fc20.x86_64
--> Running transaction check
---> Package python-paramiko.noarch 0:1.15.1-1.fc20 will be installed
--> Processing Dependency: python-crypto >= 2.1 for package: python-paramiko-1.15.1-1.fc20.noarch
--> Running transaction check
---> Package python-crypto.x86_64 0:2.6.1-1.fc20 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=========================================================================================================================
Package Arch Version Repository Size
=========================================================================================================================
Installing:
bzr x86_64 2.6.0-2.fc20 fedora 6.3 M
Installing for dependencies:
python-crypto x86_64 2.6.1-1.fc20 fedora 470 k
python-paramiko noarch 1.15.1-1.fc20 updates 998 k
Transaction Summary
=========================================================================================================================
Install 1 Package (+2 Dependent packages)
Total size: 7.7 M
Total download size: 998 k
Installed size: 36 M
Is this ok [y/d/N]: y
Downloading packages:
Not downloading Presto metadata for updates
python-paramiko-1.15.1-1.fc20.noarch.rpm | 998 kB 00:00:32
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : python-crypto-2.6.1-1.fc20.x86_64 1/3
Installing : python-paramiko-1.15.1-1.fc20.noarch 2/3
Installing : bzr-2.6.0-2.fc20.x86_64 3/3
Verifying : python-crypto-2.6.1-1.fc20.x86_64 1/3
Verifying : python-paramiko-1.15.1-1.fc20.noarch 2/3
Verifying : bzr-2.6.0-2.fc20.x86_64 3/3
Installed:
bzr.x86_64 0:2.6.0-2.fc20
Dependency Installed:
python-crypto.x86_64 0:2.6.1-1.fc20 python-paramiko.noarch 0:1.15.1-1.fc20
Complete!
با اضافه کردن سوئیچ y- میتوانید در هنگام دادن دستور تایید آن را هم داده باشید.
مسیر repository ابزار YUM هم در مسیر /etc/yum.repos.d/ موجود میباشد:
[root@localhost yum.repos.d]# cat CentOS-AppStream.repo
# CentOS-AppStream.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[AppStream]
name=CentOS-$releasever - AppStream
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=AppStream&infra=$infra
#baseurl=http://mirror.centos.org/$contentdir/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
برای پاک کردن یک بسته (مثلا bzr) میشود از دستور:
rpm -e bzr
استفاده کرد ولی باید توجه داشته باشید که:
علاوه بر این میتوانید با دستور yum remove هم پکیج ها را پاک کنید.
متداول ترین دستور yum update هستش که تمامی اطلاعات repository را آپدیت میکند و از کاربر تایید میگیرد و سپس سیستم را آپگرید میکند یا میشود پکیج خاصی را به وسیله ی دستور yum upgrade ، آپگرید کرد. مثلا دستور :
# yum upgrade 'cal*'
تمامی بسته هایی که با cal شروع بشوند را آپگرید میکند.
اگر از دستور rpm استفاده میکنید میتوانیدبا دادن سوئیچ U- و یا F- بجای i- بسته ها را آپگرید کنید . تفاوت این دو سوئیچ در این است که : U- بسته را یا نصب میکند یا اگر موجود باشد آپگریدش میکند، در صورتی که F- اگر بسته نصب باشد آپگریدش میکند و اگر نصب نباشد ، آن را نصب نمیکند.
همچنین در خیلی مواقع با دادن سوئیچ v- میتوانیم اطلاعات بیشتری از پروسه دریافت کنیم و با دادن h- میتوانیم یک نوار نصب با علامت # را ببینیم.
خوب هستش که بدونید اگه تعداد زیادی بسته rpm. داشتید که وابستگی های یک دیگر بودند خیلی راحت میتونید با دستور rpm -U *.rpm تمامی آنها را نصب کنید.
برای دیدن اطلاعات بسته ها دستورات مختلفی وجود دارد مثلا برای دیدن لیست بسته ها میشود از دستور yum list استفاده کرد و حتی میشود نام یک بسته را داد و لیست بسته های موجود را با نام کامل ببینیم:
[root@localhost yum.repos.d]# yum list yum
Last metadata expiration check: 2:00:44 ago on Tue 17 Aug 2021 03:07:27 PM +0430.
Installed Packages
yum.noarch 4.4.2-11.el8 @BaseOS
Available Packages
yum.noarch 4.7.0-1.1 download.opensuse.org_tumbleweed_repo_oss_
یا میشود اطلاعات کامل یک بسته را با دستور yum info دید:
[root@localhost yum.repos.d]# yum info yum
Last metadata expiration check: 2:03:10 ago on Tue 17 Aug 2021 03:07:27 PM +0430.
Installed Packages
Name : yum
Version : 4.4.2
Release : 11.el8
Architecture : noarch
Size : 74 k
Source : dnf-4.4.2-11.el8.src.rpm
Repository : @System
From repo : BaseOS
Summary : Package manager
URL : https://github.com/rpm-software-management/dnf
License : GPLv2+ and GPLv2 and GPL
Description : Utility that allows users to manage packages on their systems.
: It supports RPMs, modules and comps groups & environments.
Available Packages
Name : yum
Version : 4.7.0
Release : 1.1
Architecture : noarch
Size : 116 k
Source : dnf-4.7.0-1.1.src.rpm
Repository : download.opensuse.org_tumbleweed_repo_oss_
Summary : As a Yum CLI compatibility layer, supplies /usr/bin/yum redirecting to DNF
URL : https://github.com/rpm-software-management/dnf
License : GPL-2.0-or-later AND GPL-2.0-only
Description : As a Yum CLI compatibility layer, it supplies /usr/bin/yum redirecting to DNF.
همچنین میشود نام کامل یک بسته را به وسیله ی دستور rpm به دست آور
[root@localhost yum.repos.d]# rpm -q yum
yum-4.4.2-11.el8.noarch
همچنین میشود بسته های مورد نیاز را به وسیله ی دستور yum search جستجو کرد.
به وسیله ی دستور rpm -qa میشود تمامی برنامه های نصب شده روی یک سیستم را دید:
root@localhost yum.repos.d]# rpm -qa | grep ze
zenity-3.28.1-1.el8.x86_64
perl-Unicode-Normalize-1.25-396.el8.x86_64
libbytesize-1.4-3.el8.x86_64
python3-bytesize-1.4-3.el8.x86_64
علاوه بر این ، این امکان وجود دارد که فایل های داخل یک بسته را هم دید:
[root@localhost yum.repos.d]# rpm -ql zenity | head
/usr/bin/zenity
/usr/lib/.build-id
/usr/lib/.build-id/ac
/usr/lib/.build-id/ac/bd873f1276129381ace20110a4d1d208bdc322
/usr/share/doc/zenity
/usr/share/doc/zenity/AUTHORS
/usr/share/doc/zenity/NEWS
/usr/share/doc/zenity/README
/usr/share/doc/zenity/THANKS
/usr/share/help/C/zenity
...
توجه داشته باشید که با اضافه کردن سوئیچ p- همین کار را میتوانید برای یک بسته ی دانلود شده نیز انجام دهید.
کار مهم دیگری هم که وجود دارد پیدا کردن این است که یک فایل متعلق به چه پکیجی است:
[root@localhost yum.repos.d]# which cal
/usr/bin/cal
[root@localhost yum.repos.d]# rpm -qf /usr/bin/cal
util-linux-2.32.1-22.el8.x86_64
اگه نیاز دارید تا وابستگی های مربوط به یک بسته رو چک کنید از سوئیچ R- استفاده کنید:
[root@localhost yum.repos.d]# rpm -qR yum
config(yum) = 4.4.2-11.el8
dnf = 4.4.2-11.el8
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1
یا حتی میشود از دستور deplist نیز به این منظور استفاده کرد.
برای اینکه ببینید هر بسته ای چه چیزی ارائه میدهد میتوانید از سوئیچ whatprovides-- برای دستور rpm و یا دستور :
[root@localhost yum.repos.d]# yum whatprovides telnet
Last metadata expiration check: 2:32:07 ago on Tue 17 Aug 2021 03:07:27 PM +0430.
telnet-1.2-174.8.i586 : A client program for the telnet remote login protocol
Repo : download.opensuse.org_tumbleweed_repo_oss_
Matched from:
Provide : telnet = 1.2-174.8
telnet-1.2-174.8.x86_64 : A client program for the telnet remote login protocol
Repo : download.opensuse.org_tumbleweed_repo_oss_
Matched from:
Provide : telnet = 1.2-174.8
telnet-1:0.17-76.el8.x86_64 : The client program for the Telnet remote login protocol
Repo : AppStream
Matched from:
Provide : telnet = 1:0.17-76.el8
استفاده کنید، البته باید این نکته رو توجه داشته باشید که rpm فقط برای بسته های نصب شده کار میکند.
Rpm قابلیتی ارائه میدهد که میتوانید با آن MD5 و SHA1 فایل ها را چک کنید. به این منظور میتوانید از سوئیچ k- استفاده کنید و ایده ی خوبیه که با سوئیچ v- ترکیبش کنیم!
[root@localhost ~]# rpm -vK bzr-2.6.0-2.fc20.x86_64.rpm
bzr-2.6.0-2.fc20.x86_64.rpm:
Header V3 RSA/SHA256 Signature, key ID 246110c1: OK
Header SHA1 digest: OK (171c91fbd14416ac44c0f6d396826d583c3840ce)
V3 RSA/SHA256 Signature, key ID 246110c1: OK
MD5 digest: OK (c4478d64f009d07cb17d018b377677ab)
که خروجی بالا نشان از صحت فایل دارد.
همچنین این امکان فراهم که چک کنیم که آیا فایل های نصب شده توسط یک بسته سالم هستند یا خیر . این کار با سوئیچ V- ممکن میشه:
[root@localhost ~]# rpm -V bzr
[root@localhost ~]# rm /etc/bash_completion.d/bzr
rm: remove regular file ‘/etc/bash_completion.d/bzr’? y
[root@localhost ~]# rpm -V bzr
missing /etc/bash_completion.d/bzr
و اگر مشکلی باشد خیلی راحت با دستور yum reinstall میشود بسته را مجددا نصب کرد.
ابزار yumdownloader: این ابزار امکانی را فراهم میکند که فایل های rpm. را از repository ها دانلود کنید ولی نصب نکنید همچنین با دادن سوئیچ resolve-- تمامی وابستگی های مورد نیاز هم دانلود میشود.
ابزار rpm2cpio: این ابزار امکان ساخت آرشیوهای cpio را برای ما فراهم میکند. Cpio مثل zip یا rar هستش . به وسیله ی دستور rpm2cpio میتوانید فایل های rpm ای را به آرشیوهای cpio تبدیل کنید و همچنین به وسیله ی دستور cpio بازشان کنید.
همچنین ابزارهای دیگری برای مدیریت بسته ها موجود است مثلا SUSE از ابزار قدرتمند zipper و YaST استفاده میکند و همچنین PackageKit نیز یکی دیگر از این ابزارهاست که برای اکثر سیستم های لینوکس مثل دبیان و فدورا و آرچ ، یک محیط گرافیکی برای نصب و آپدیت و ... پکیج ها فراهم میکند.
خلاصه: در این درس به بررسی کامل مدیر بسته های YUM و RPM پرداختیم با روش نصب بسته ها ، حذف آنها و آپدیتشان آشنا شدیم ، مسیر repository ابزار YUM را دیدیم و یاد گرفتیم چجوری وابستگی های یک بسته را بفهمیم بدون نصب آنها را دانلود کنیم و از صحت پکیج های نصب شده مطمئن شویم.در آخر هم دیدیم که چجوری فایل های rpm را به cpio تبدیل کنیم.
در قسمت نهم از این دوره به سراغ خود bash میریم و یاد میگیریم چجوری باهاش ارتباط برقرار کنیم و دستورات رو از طریق کامند لاین بهش بدیم.در انتهای این آموزش میتونید که دستورات یک خطی را صادر کنید و کار های ابتدایی را به وسیله ی آن انجام بدید، با تاریخچه کار کنید. دستورات را داخل و خارج patch صادر کنید و از shell environment استفاده کنید و آن را تغییر بدهد.
در اکثر لینوکس ها این امکان فراهم هستش که کاند لاین (command line) خودتون رو انتخاب کنید که بهش shell هم گفته میشه که متداول ترینشون Bash هستش . بعضی دستورات داخلی هستن مثل cd یا break و یا exec و از استریم ها استفاده میکنند. سه نوع استریم وجود دارد:
اصولا User Prompts به شکل زیر هستش:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$
و معمولا User Prompts ها در برای روت با علامت # نشان داده میشوند:
root@Mahdi:~#
البته لزوما این علائم نیستش و این نماد ها قابل تغییر هستند!
تنظیمات عمومی Bash در etc/profile/ و تنظیمات مربوط به هر کاربر در profile./~ و bash_profile./~ و bash_logout./~ قرار دارند.
در bash قابلیتی وجود دارد که میتوان به وسیله ی آن کامند ها را کامل کرد مثلا من اگر در مسیری باشم که فایلی با یک نام طولانی مثلا thisismyfilewithitslongname داشته باشم میتوانم با نوشتن بخشی از اسم آن (تا زمانی که اسم منحصر به فرد باشه، مثلا اگر دو فایل داشته باشم که با this شروع بشه برای انتخاب این فایل باید حداقل تا thisi را بنویسیم) و زدن دکمه Tab خود بش اتوماتیک بقیه ی نام فایل را مینویسد. همچنین با زدن دوبار دکمه Tab تمامی احتمالات برای کامل کردن آن اسم نشان داده میشوند.
در اکثر دستورات شما یک نام دستور دارید و چند پارمتر ، مثلا در دستور echo:
$ echo
$ echo Hello lpic
Hello lpic
$ echo Hello lpic #just a simple hi
Hello lpic
همونطور که مشاهده میکنید هرچیزی بعد از # بیاید ، کامنت محسوب میشود و تاثیری نخواهد داشت.
بعضی کاراکتر ها هستند که معانی خاصی دارند و امکانات خاصی به ما ارائه میدهند مثلا در دستور echo با زدن سوئیچ e- و دادن کارکتر n\ هنگام رسیدن به این کارکتر به خط جدید میرود:
$ echo -e "hello\nthere"
hello
there
Escape sequence | کاربرد |
\a | Alert - هشدار ( صدای زنگ) -ctrl+G |
\b | Backspace – پاک کردن کاراکتر قبلی – ctrl+H |
\c | هر چیزی بعد از این کارکتر بیاید حذف میشود |
\f | ایجاد یک feed – در بعضی سیستم ها باعث پاک کردن صفحه میشود |
\n | New line – رفتن به یک خط جدید |
\r | Return (Enter) – برگردوندن کاراکتر return |
\t | Tab – بازگرداندن کارکتر tab - ctrl+I |
همچنین میشود از \ برای شکستن یک دستور به تعداد زیاد خط استفاده کرد:
$ echo but this \
is another \
usage
but this is another usage
همچنین کارکتر های خاصی هستن که برای استفاده از آنها باید به اصطلاح آنها را escape کرد یا پشت آنها بک اسلش \ قرار داد: ; | & ( ) < > *
حالا معنی این کارکتر ها چیست؟ اگر برنامه نویسی انجام داده باشید با بعضی از آنها آشنایی دارید که مهم ترین آنها:
; (که برای جدا کردن دستورات از هم در داخل یک خط هست)
&& (که "و منطقی" هستش و معنی آن اینه که اگر دستور اول خروجی صحیح برگردوند به دستور دوم برو و اگر دستور دوم خروجی صحیح برگردوند به دستور سوم برو و همینطور الی آخر )
|| (که "یا منطقی" هستش و معنیش اینه که تمامی دستورات را تا زمانی که اولین خروجی صحیح را برگردونی ، ادامه بده)
در زیر چند نمونه مثال را میبنیم:
└─$ echo L1 ; echo line2 ; echo "salam chtorid"
L1
line2
salam chtorid
└─$ echo L1 && rm a && echo "salam chtorid"
L1
rm: cannot remove 'a': No such file or directory
└─$ echo L1 || rm a || echo "salam chtorid"
L1
└─$ echo L1 || rm a ; echo "salam chtorid"
L1
salam chtorid
با استفاده از دستور exit میتوانید از shell خارج شوید . همین کار را میشود با کلید ترکیبی ctrl+d نیز انجام داد. همچنین اگر با دادن دستور bash یک shell جدید داخل shell فعلی ایجاد کنید با دادن دستور exit از shell دوم خارج میشوید.میتوانید با دادن یک عدد جلوی دستور exit کد خروج آن را دستی تنظیم کنید. که در بخش متغیرهای محیطی مثال مربوط به آن را میبینید.
همچنین دستور exec یک دستوری را اجرا میکند و شل فعلی را میبندد. به همین صورت اگر دستوری را داخل پرانتز () قرار بدهیم آن دستور را داخل یک sub shell اجرا میکند.
متغییر های محیطی چی هستند؟ یک سری متغییر هستن مخصوص همون محیطی که توش هستیم و به مقادیری برای همون محیط اشاره میکنه ، برنامه ها و فرایند ها میتونن این مقادیر رو بخونن و طبق اون عمل کنن مثلا با خوندن متغییر TEMP میتونن محل مناسبی برای ذخیره ی فایل های موقت پیدا کنند. متغییر های محیطی را میشود با گذاشتن علامت دلار $ جلوی اسم اونها ، و echo کردنشون دید (توجه داشته باشید که متغیرهای محیطی به حروف کوچک و بزرگ حساس اند) مثلا:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $USER $UID
ubuntu 1000
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $SHELL $HOME $PWD
/bin/bash /home/ubuntu /mnt/c/Users/Mahdi
نام متغیر | کاربرد |
---|---|
USER | نام کاربر لاگ این شده |
UID | آی دی عددی کاربر لاگین شده |
HOME | دایرکتوری خانه |
PWD | دایرکتوری کنونی |
SHELL | آدرس و نام شل کنونی |
$ | آی دی پروسه ها ( یا PID بش در حال اجرا یا دیگر پروسه ها) |
PPID | آی دی پروسه ی پرنت ( والد) یعنی آی دی پروسه ای که پروسه ی کنونی را اجرا کرده |
? | کد خروج آخرین دستور |
مثلا برای دیدن کد خروج آخرین دستور ، از دستور زیر استفاده میشود:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ (exit)
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $?
0
همانطور که بالاتر اشاره کردم میشود به exit کد خروج دستی داد مثلا :
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ (exit 18)
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $?
18
برای تعریف یک متغیر محیطی فقط کافی است نام آن را بدهید (اصولا با حروف بزرگ نامگذاری میکنند ولی با حروف کوچک هم میشه) و با یک مساوی جلوی آن مقدار آن را تعین کنید. مثلا:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ COUNTRY=iran
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $COUNTRY
iran
همچنین اگر لازم دارید بلافاصله چیزی را بعد از نام متغیر بنویسید برای اینکه با نام متغیر قاطی نشود میتوانید از براکت { } استفاده کنید :
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo I am an ${COUNTRY}ian
I am an iranian
با export کردن یک دستور میتوان آن را برای دیگر برنامه هایی که از داخل همان شل اجرا میشوند ، قابل دسترسی کرد:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ export COUNTRY
اولین دستوری که باید بدونید ، دستور env هستش به وسیله ی این دستور میتوانید متغیرهای محیطی کنونی را ببینید:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ env
SHELL=/bin/bash
WSL_DISTRO_NAME=Ubuntu
WT_SESSION=9e704d16-fa18-4258-a808-29d2039cc848
NAME=Mahdi
PWD=/mnt/c/Users/Mahdi
LOGNAME=ubuntu
HOME=/home/ubuntu
LANG=C.UTF-8
WSL_INTEROP=/run/WSL/8_interop
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
LESSCLOSE=/usr/bin/lesspipe %s %s
TERM=xterm-256color
LESSOPEN=| /usr/bin/lesspipe %s
USER=ubuntu
DISPLAY=172.19.144.1:0.0
SHLVL=1
WSLENV=WT_SESSION::WT_PROFILE_ID
XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Program Files (x86)/VMware/VMware Workstation/bin/:/mnt/c/Program Files (x86)/Cuminas/Document Express DjVu Plug-in/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Users/Mahdi/AppData/Local/Microsoft/WindowsApps:/snap/bin
HOSTTYPE=x86_64
WT_PROFILE_ID={2c4de342-38b7-51cf-b940-2309a097f518}
_=/usr/bin/env
یک سوئیچ که برای دستور env وجود دارد سوئیچ i- هستش که امکان اجرای یک دستور بدون متغیرهای محیطی فعلی را میدهد مثلا دستور زیر یک بش بدون متغیرهای محیطی فعلی ایجاد میکند:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ env -i bash
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ env
PWD=/mnt/c/Users/Mahdi
LS_COLORS=
LESSCLOSE=/usr/bin/lesspipe %s %s
LESSOPEN=| /usr/bin/lesspipe %s
DISPLAY=172.19.144.1:0.0
SHLVL=1
_=/usr/bin/env
صد در صد متغیرهایی مثل PWD هنوز وجود دارند ولی همونطور که میبنید تعداد آنها خیلی کمتر شد.
دستور بعدی دستور set هستش. این دستور یک دستور پیشرفته هست و میتواند رفتارهای مربوط به متغیرهای محیطی را تغییر بدهد:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $-
himBHs
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $NOVAR
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ set -u;echo $-
himuBHs
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $NOVAR
-bash: NOVAR: unbound variable
در مثال بالا با echo کردن -$ یک سری از ویژگی های مربوط به متغیرهای محیطی را میبینیم. با اکو کردن یک متغیر ناموجود میبینیم که هیچ پیغامی نمایش داده نشده ولی با set کردن مقدار u- میگیم که در صورتی که متغیر ناموجود باشد پیغام خطایی صادر میشود همچنین برای برگردوندنش به حالت قبل میتونید مقدار u+ رو ست کنید.
دستور آخر این بخش هم unset میباشد که به وسیله ی آن میتوانیم یک متغیر محیطی را حذف کنیم:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ VAR=something;echo $VAR
something
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ unset VAR;echo $VAR
-bash: VAR: unbound variable
به وسیله ی این دستور میتوانید اطلاعاتی را راجع به سیستم به دست بیاورید به طور مثال دستور uname بدون هیچ پارامتری به ما میگوید که پشت یک ماشین لینوکسی هستیم. لیست سوئیچ های پرکاربرد این دستور در جدول زیر آمده:
پارامتر | کاربرد |
---|---|
s- | نمایش نام کرنل ، پارمتر دیفالت هستش و بدون زدن این پارمتر نیز همین دستور انجام میشود. |
n- | چاپ hostname یا nodename |
r- | نمایش release کرنل |
v- | نمایش version کرنل |
-m | نمایش نام ماشین (سی پی یو) |
-o | نمایش نام سیستم عامل |
-a | نمایش تمامی اطلاعات مربوطه |
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ uname -a
Linux Mahdi 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
تاریخچه (history) دستوراتی که به بش داده ایم در فایلی به نام را میشود با دستور history دید (که معمولا تا 500 دستور قبلی را ذخیره میکند) آدرس محل ذخیره ی تاریخچه در متغیر محیطی HISTFILE$ میباشد و همچنین میشود تعداد دستورات ذخیره شده را از طریق متغیر محیطی HISTSIZE$ تغییر داد.
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $HISTFILE
/home/ubuntu/.bash_history
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $HISTSIZE
1000
علاوه بر این دستوراتی وجود دارند برای کار با تاریخچه مثلا با دادن یک عدد بعد دستور history میتوانید آن تعداد دستورات داده شده را ببینید:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ history 3
220 echo $HISTSIZE
221 history 10
222 history 3
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ history 6
218 echo $HISTSIZE
219 echo $HISTFILE
220 echo $HISTSIZE
221 history 10
222 history 3
223 history 6
با دادن دو علامت تعجب !! میتوانید دوباره آخرین دستور داده شده را اجرا کنید:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ !!
history 6
218 echo $HISTSIZE
219 echo $HISTFILE
220 echo $HISTSIZE
221 history 10
222 history 3
223 history 6
یا با دادن یک علامت تعجب و نام یک دستور آخرین دستور مشابه را اجرا میکند:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ !echo
echo $HISTSIZE
1000
همچنین میشود با دادن یک علامت تعجب و بعد عبارت مورد نظر در میان دو علامت سوال ، آخرین دستور منطبق را اجرا کرد:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ !?$HOME?
echo $SHELL $HOME $PWD
/bin/bash /home/ubuntu /mnt/c/Users/Mahdi
ولی برای کارهای روزمره روش آسان تری هم وجود دارد! با زدن دکمه ctrl+r میتوایند جستجوی معکوس (reverse search) انجام بدید که مراحلش به صورت زیر میباشد:
بیشتر دستورات بش دستورات خارجی هستند که در جاهای مختلف فایل های آنها ذخیره شده اند. سیستم برای پیدا کردن فایل های این دستورات از متغیر محیطی PATH$ استفاده میکند:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
که هر دو نقطه ( : ) نشان دهنده ی یک مسیر جداگانه میباشد و بش به ترتیب دستور داده شده را در این دایرکتوری ها میگردد. همچنین همانطور که در درس های قبل اشاره شد میتوانید به وسیله ی دستوارت which و type و whereis اطلاعات بیشتری از یک دستور خاص را پیدا کنید:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ which ls
/usr/bin/ls
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ whereis ls
ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ type ls
ls is aliased to `ls --color=auto'
برای اجرای دستوراتی که آدرس آنها داده نشده سه راه حل وجود دارد:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ /mnt/c/Users/Mahdi/newcommand.sh
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ ./newcommand.sh
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ PATH=$PATH:/mnt/c/Users/Mahdi/newcommand.sh
که با اجرای دستور بالا مسیر داده شده به انتهای PATH$ اضافه میشود.
دستور cd مخفف change directory هستش و به ما کمک میکند بین دایرکتوری های مختلف جا به جا شویم ( میشود از . برای رفتن به دایرکتوری فعلی و از .. برای رفتن به یک دایرکتوری بالاتر استفاده کرد) همچنین بدون دادن هیچ آرگومانی دستور cd ما را به مسیر HOME$ میبرد.
دستور pwd مسیر فعلی ای که در آن قرار داریم را نشان میدهد و برابر است با اجرای دستور echo $PWD
یکی از بهترین و جالب ترین بخش های لینوکس manual page یا دفترچه راهنمای لینوکس هستش . شما با زدن دستور man و دادن نام یک دستور دیگر میتونید به راهنمای آن دسترسی پیدا کنید:
همونطور که میبینید اطلاعات متنوع و زیادی از یک دستور میتونیم به دست بیاریم که مهمترینش نوع استفاده و پارمترهای موجودش هست. دستور man به 9 بخش تقسیم شده است:
برای جستجوی man ها میتوانید از سوئیچ f- استفاده کنید:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ man -f ls
ls (1) - list directory contents
برای پیدا کردن مسیر man یک دستور:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ man -w ls
/usr/share/man/man1/ls.1.gz
برای جستجو در بین توضیحات مختصر و نام دستورات از سوئیچ k- استفاده میشود:
ubuntu@Mahdi:/mnt/c/Users/Mahdi$ man -k ls
add-shell (8) - add shells to the list of valid login shells
blockdev (8) - call block device ioctls from the command line
credentials (7) - process identifiers
dircolors (1) - color setup for ls
eatmydata (1) - transparently disable fsync() and other data...
false (1) - do nothing, unsuccessfully
git-credential (1) - Retrieve and store user credentials
git-credential-cache--daemon (1) - Temporarily store user credentia...
git-credential-store (1) - Helper to store credentials on disk
git-difftool (1) - Show changes using common diff tools
....
یا میشود به جای دستور بالا از apropos استفاده کرد و عبارت مورد نظر را بهش داد تا در man ها دنبال آن بگردد. خلاصه:در این درس به صورت کلی با shell و نوع اصلی آن یعنی bash آشنا شدیم،محل فایل ها و تنظیمات مخصوص به آن را دیدیم،با انواع استریم های مربوط به bash آشنا شدیم و یک سری دستورات اولیه را یادگرفتیم ، همچنین فهمیدیم که sequence ها چی هستند و با escape character ها آشنا شدیم و کارکترهای خاص را شناختیم، با متغیرهای محیطی آشنا شدیم و یاد گرفتیم چگونه با آنها کار کنیم و فهمیدیم دستورات در کجاها ذخیره میشوند و بش چجوری به آنها دسترسی پیدا میکند.
وقتایی که نیم کره ی چپ مغزم کار میکنه شبکه و امنیت و وقتایی که نیم کره ی راست مغزم کار میکنه گرافیک :)
متولد 1378 تهران ، دانشجوی رشته ی کامپیوتر گرایش شبکه در دانشگاه شمسی پور
20 مهر 1400 این مطلب را ارسال کرده