فصل شانزدهم - دستورات متفرقه
در این فصل به شرح مختصر برخی دستورات کاربردی شل میپردازیم.
محتویات[نهفتن] |
دستور eval
دستور eval زمانی مورد استفاده قرار میگیرد که نیاز باشد یک دستور دوبار پردازش شود.
مثال:
مجموعه دستورات زیر را در نظر بگیرید:
$ b=\$a $ a=foo $ echo $b
که منجر به تولید خروجی زیر میشود:
$a
در این مثال زمانی که از متغیر b استفاده میکنیم مشابه آن است که از
متغیر a استفاده کنیم. زیرا مقدار b با متغیر a برابر است. ولی همانطور که
مشاهده میکنید نتیجه این چنین نیست. و زمانی که مقدار متغیر b برای چاپ در
خروجی فراخوانی میشود a$ بر روی صفحه نمایش ظاهر میشود.
برای حل این مشکل میتوان از دستور eval استفاده کرد. درواقع زمانی که
دستور echo $b اجرا میشود، در پردازش اول مقدار متغیر b ارزیابی شده و
برابر a$ قرار میگیرد و در پردازش دوم مقدار a$ محاسبه شده و در نهایت
عبارت foo در خروجی چاپ میشود.
$ b=\$a $ a=foo $ echo $b foo
مثال: اسکریپت زیر را در نظر بگیرید:
command='grep $grepopts $searchstring $file' for opt do case "$opt" in file) output=' > $ofile' ;; read) output=' | more' ;; sort) postproc=' | sort $sortopts';; esac done eval $command $postproc $output
خط آخر در این اسکریپت معادل دستور زیر است: $ grep $grepopts $searchstring $file | sort $sortopts > $ofile
در صورتی که در خط آخر از دستور eval استفاده نشود اسکریپت به درستی اجرا نمیشود.
دستور “:”
کاراکتر : در شل معادل دستوری است که همیشه مقدار صفر را
بازمیگرداند. درواقع این دستور معادل دستوری است که اجرای آن همیشه موفقیت
آمیز بوده و با مقدار صفر خارج میشود ولی هیچ عملی انجام نمیدهد.
در این بخش چند مثال از کاربرد کاراکتر : در حلقهها و کنترل جریانها ارائه میشود.
مثال
اسکریپت زیر را در نظر بگیرید:
if [ -x $CMD ] then : else echo Error: $CMD is not executable >&2 fi
فرض کنید در این اسکریپت هنوز تصمیم به نوشتن قسمت then نگرفتهاید. در این صورت میتوان با استفاده : قسمت then را بدون ایجاد مشکل خالی گذاشت.
مثال:
از آنجا که کاراکتر : همیشه مقدار صفر را به عنوان کد بازگشت خود بازمیگرداند میتوان از آن در حلقههای نامتناهی استفاده نمود.
while :; do echo "Enter some input: \c" read INPUT [ "$INPUT" = stop ] && break done
از آنجا شرط این حلقه همیشه درست است کنترل برنامه تنها در صورتی از بدنهی حلقه خارج میشود که دستور break اجرا شود. به عبارتی تنها در صورتی که کاربر عبارت stop وارد کند از حلقه خارج میشود.
دستور type
این دستور مسیر کامل یک دستور را به شما نمایش میدهد. شکل کلی استفاده از این دستور به صورت زیر است:
type command1 command2 …
همچنین چنانچه دستور مورد نظر به عنوان یک ابزار جدا گانه نباشد و یکی از موارد زیر باشد نیز دستور type نوع آن را اعلام میکند:
- دستورات توکار شل
- کلمات کلیدی و رزرو شده در شل
- alias ها
مثال
$ type true vi case ulimit history
خروجی میتواند به شکل زیر باشد:
true is /bin/true vi is /usr/bin/vi case is a keyword ulimit is a shell builtin history is an exported alias for fc -l
دستور sleep
این دستور برای توقف اجرای دستورات به مقدار معین استفاده میشود. درواقع هر گاه کنترل جریان دستورات به دستور sleep برسد به مقدار معین توقف کرده و سپس روند اجرای دستورات را ادامه میدهد. شکل کلی دستور sleep به صورت زیر است:
$ sleep n
که در اینجا n یک عدد به ثانیه است.
مثال:
$ sleep 180 ; echo "Lunch time.."
$ (sleep 10000 ; myprogram) &
دستور find
شکل کلی دستور:
find [path] [options] [what-to-do]
اشاره: هر جا از حرف n استفاده شده میتوان با استفاده از + و - ، به ترتیب حداقل و حداکثر مقادیر را مشخص کرد (به مثالهایی که آخر پست قرار دارند توجه کنید)
برخی option های کاربردی:
نمایش تمام فایلهایی و دایرکتوریهایی که دقیقا در n روز پیش دسترسی به أنها انجام شده است(-amin n برای n دقیقه پیش)
-atime n
نمایش تمام فایلهایی و دایرکتوریهایی که وضعیت(status) آنها دقیقا در n روز پیش تغییر کرده است(-cmin n برای n دقیقه پیش)
-ctime n
نمایش تمام فایلهایی و دایرکتوریهایی که دقیقا در n روز پیش تغییر کردهاند(-mmin n برای n دقیقه پیش)
-mtime n
نمایش تمام فایلهایی و دایرکتوریهایی که نام آنها مطالبق pattern میباشد(غیر حساس به بزرگ و کوچک بودن حروف)
-name pattern
نمایش تمام فایلهایی و دایرکتوریهایی که نام آنها مطالبق pattern میباشد(غیر حساس به بزرگ و کوچک بودن حروف)
-iname pattern
حداکثر تا m زیر دایرکتوی شاخهی جاری جستوجو را انجام میدهد
-maxdepth m
حداقل از m زیر دایرکتوی شاخهی جاری به بعد، جستوجو را انجام میدهد
-mindepth m
نمایش فایلها در صورتی که فایل سیستمی که در آن ذخیره شدهاند مطابق با fs باشد
-fstype fs
نمایش فایلها در صورتی که گروهی که در آن قراردارند مطابق با gn باشد.
-group gn
نمایش تمام فایلهای path با نمایش مشخصات زیر برای هر فایل:
-ls
inode number size in kilobytes (1024 bytes) protection mode number of hard links user group size in bytes modification time
نمایش فایلهای خالی
-empty
نمایش فایلی که inode آن برابر با عدد n دارند
-inum n
نمایش فایلهایی به تعداد n لینک دارند (یا n-1 هاردلینک از یک فایل اولیه ایجاد شده است)
-links n
پاک کردن فایلها و دایرکتوریهای موجود در نتایج جستوجو
-delete
نمایش فایلهایی که بعد از file تغییر کردهاند
-newer file
نمایش فایلها در صورتی که زیر مجموعهی /etc/group نباشند
-nogroup
نمایش آدرس تمام زیردایرکتوریها
نمایش فایلها با امکان شخصی سازی و مرتب سازی اطلاعات چاپ شده
-prinf [option]
نمایش فایلهایی که حجم آنها برابر n(به کیلوبایت) است
-size nk
نمایش فایلهای متعلق به username
-user username
نمایش فایلها در صورتی که زیرمجموعه /etc/passwd نباشند
-nouser
نمایش فایلهایی که نوع آنها با type تطابق دارد. (برخی از مقادیر type):
-type type
نمایش تمام فایلهایی که مجوز دسترسی آنها مقدار permission است.
(میتوان از مجوز بیشتر(+)، کمتر(-)، یا همه مجوزها به جز(!) مقدار وارد شده
نیز، استفاده کرد)
اشاره: permission میتواند هم به صورت یک عدد سه(یا چهار) رقمی در مبنای هشت(۷۷۱ یا ۰۶۶۲) یا یک عبارت منظم باشد(a+x یا u+w یا gu=r)
b block (buffered) special c character (unbuffered) special d directory p named pipe (FIFO) f regular file l symbolic link s socket D door (Solaris) -perm [-,+,!]permission
-exec
اجرا کردن یک دستور خاص بر روی تکتک فایلها/دایرکتوریهای پیدا شده.
مثال:
find . -type f -iname '*.pdf' -exec gzip '{}' \;
تمام فایلهای pdf را فشرده میکند
find . -type f -exec chmod u+x '{}' \;
برای تمام فایلها، مجوز اجرا به صاحب فایل را میدهد.
چند مثال عملی و کاربردی: جستوجوی تمام فایلها و پوشههایی که در زیر شاخههای دایرکتوری home قرار دارند و اسم آنها دقیقا عبارت baroon است
$ find ~ -name baroon
جستوجوی تمام فایلها و پوشههایی که در زیر شاخههای دایرکتوریهای /etc
~/Desktop قرار دارند و اسم آنها با عبارت baroon پایان میپذیرد
$ find /etc ~/Desktop -name '*baroon'
جستوجوی تمام فایلها و پوشههایی که در زیر شاخههای دایرکتوریهای /etc
~/Desktop قرار دارند و اسم آنها با عبارت baroon پایان نمیپذیرد(غیر حساس
به بزرگ و کوچکی حروف)
$ find /etc ~/Desktop ! -iname '*baroon'
جستوجوی تمام فایلها و پوشههایی که در زیر شاخههای دایرکتوریهای /etc
home/ قرار دارند و اسم آنها با عبارت و sobh با عبارت baroon پایان
میپذیرد
$ find /etc $HOME -name 'sobh\*baroon'
جستوجوی تمام فایلها و پوشههای موجود در دایرکتوری ریشه و نمایش فایلهایی که از نوع f(فایل معمولی) و زمان آخرین تغییر آنها کمتر از ۷روز است
$ find / -type f -mtime -7
جستوجوی تمام فایلها و پوشههای موجود در دایرکتوری جاری و نمایش فایلهایی که حجم آنها بیشتر از ۵۰۰۰کیلوبایت است
$ find . -size +5000k
پاک کردن تمام فایلهایی که در دایرکتوری(و زیر دایرکتوریهای آن) وجود دارد و پسوند bak دارند
$ find . -name '*.bak' -type f -print -delete
که معادل است با:
$ find . -name '*.bak' -type f -print -exec rm -f '{}' \;
پیدا کردن همه چیز به جز آنهایی که در زیر شاخههای /dev قرار دارند
$ find / ! -path /dev\*
پیدا کردن تمام فایلهای موجود در دایرکتوری جاری که بین ۵ تا ۱۰ دقیقه پیش تغییر کردهاند
$ find . -mmin +5 -mmin -10
نمایش تمام فایلهایی که با دات (.) شروع نمیشوند در فقط دایرکتوری جاری (نمایش فایلهای غیر مخفی) دو دستور بالا فقط در شکل نمایش خروجی تفاوت دارند
$ find . -maxdepth 1 -name '[!.]*' $ find . -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n'
جستوجو در دایرکتوری جاری و نمایش تمام فایلهایی که گروه آنها مجوز خواندن دارد و از نوع f(فایلهای معمولی) هستند
$ find . -perm -g=r -type f
دستور xargs
این دستور لیستی از کلمات را ار ورودی استاندارد دریافت کرده و هر کلمه
را به عنوان آرگومان برای دستوری که تعیین میشود، ارسال میکند.
مثال
$ cat filelist | xargs rm
در این دستور محتویات فایل filelist به عنوان آرگومان به دستور rm ارسال و حذف میشوند.
مثال:
$ find . -name '*.bak' -type f -print | xargs rm -f
که معادل است با:
$ find . -name '*.bak' -type f -print -delete
تمام فایلهای در پوشهی جاری که پسوند آنها bak است حذف میشوند.
استفاده از آپشن n
با استفاده از این آپشن میتوان هر n کلمه را به عنوان یک آرگومان در نظر گرفت.
مثال
$ echo aa bb cc dd ee ff gg | xargs -n 2 aa bb cc dd ee ff gg $ $ ls acme report16 baroon report34 report527 $ ls | xargs -n 2 echo === === acme report16 === baroon report34 === report527 $
در این دو مثال هر دو کلمه به عنوان یک آرگومان در نظر گرفته میشوند.
دستور expr
این دستور برای انجام عملیات سادهی حسابی برای اعداد صحیح مورد استفاده قرار میگیرد. شکل کلی این دستور به صورت زیر است:
expr arg1 opr arg1
که در آن opr میتواند یکی از موارد زیر باشد:
- + محاسب جمع
- - محاسب تفریق
- / محاسبه تقسیم صحیح
- *\ محاسبه ضرب
- % محاسبه باقیمانده تقسیم arg1/arg2
- <\ در صورت کوچکتر بودن arg1 صفر و در غیر اینصورت 1 بازگشت داده میشود
- <=\ در صورت کوچکتر بودن arg1 یا برابری دو عدد، صفر و در غیر اینصورت 1 بازگشت داده میشود
- >\ در صورت کوچکتر بودن arg2 صفر و در غیر اینصورت 1 بازگشت داده میشود
- >=\ در صورت کوچکتر بودن arg2 یا برابری دو عدد، صفر و در غیر اینصورت 1 بازگشت داده میشود
- |\ در صورت صفر یا null نبودن یکی از دو آرگومان، arg1 و در غیر اینصورت1 بازگشت داده میشود
- &\ در صورت صفر یا null نبودن هر دو آرگومان، arg1 و در غیر اینصورت 1 بازگشت داده میشود
- = مقایسه دو عدد. در صورت برابری 1 و در غیر اینصورت 0 بازگردانده میشود
- : مقایسه دو رشته. در صورت برابر بودن n کاراکتر اول دو رشته، عدد n ودر غیر اینصورت 0 بازگردانده میشود
نکته: توجه کنید بین عملگر و عملوندها حتماً باید یک فاصله باشد. مثال زیر را در نظر بگیرید:
$ expr 13%5
منجر به تولید خروجی زیر میشود:
13%5
مثال:
$ expr 12 \* 3 36 $ expr 13 % 5 3 $ var1='10' $ var2='20' $ expr $var1 = $var2 0 $ expr $var1 \< $var2 1 $ expr $var1 \!= $var2 1 $ expr $var1 + 5 \>= 16 0
همچنین عملوندهای دستور expr میتوانند متغیر نیز باشند.
مثال
$ CNT=`expr $CNT + 1`
که متغیر CNT را یک واحد افزایش میدهد.
چند مثال از عملگر “:”
$ expr linux : lin 3 $ expr linux : linx 0 $ expr linux : '.*' 5 $ expr abcdefgh : '[a-e]*' 5 $ expr abcdef : '..\(...\)' cde
دستور bc
این نیز دستور همانند دستور expr ابزاری برای اعمال حسابی است با این تفاوت که محدود به اعداد صحیح نیست.
عملیات مختلفی میتوان با استفاده از دستور bc انجام داد که برخی از آنها به شرح زیر هستند
انجام عملیات مختلف در دستور bc
عمل جمع:
$ echo '57+43' | bc 100
عمل تفریق:
$ echo '57-43' | bc 14
عمل ضرب:
$ echo '57*43' | bc 2451
تعین دقت محاسبات:
با مقدار دهی متغیر scale میتوان دقت محاسبات را تعیین نمود.
عمل تقسیم:
$ echo 'scale=25; 57/43' | bc 1.3255813953488372093023255
محاسبهی ریشه nام یک عدد:
$ echo 'scale=30;sqrt(2)' | bc 1.414213562373095048801688724209
محاسبهی توان:
$ echo '6^6' | bc 46656
استفاده از پرانتز:
$ echo '7+(6*5)' | bc 37 $ echo '(7+6)*5' | bc 65
تبدیل یک عدد دهدی به مبنای ۱۶:
$ echo 'obase=16;255' | bc FF
تبدیل یک عدد دهدی به مبنای ۲:
$ echo 'obase=2;12' | bc 1100
تبدیل یک عدد دودوی به مبنای ۱۰:
$ echo 'ibase=2;obase=A;10' | bc 2 $ echo 'ibase=2;obase=A;10000001' | bc 129
تبدیل یک عدد مبنای ۱۶ به مبنای ۱۰:
$ echo 'ibase=16;obase=A;FF' | bc 255
استفاده به صورت تعاملی:
$ bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'.
در این حالت و زمانی که دستور bc به تنهایی وارد میشود، صحفهی ترمینال
به حالت تعاملی درآمده و منتظر وارد کردن عبارات حسابی میشود، و بعد از
وارد کردن هر عبارت نتیجه آن را در خط بعد نمایش میدهد.
مثال:
$ bc bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. scale=4 8/3 2.6666 2.5 * 4.1/6.9 1.4855 quit
در این مثال پس از وارد کردن دستور bc ابتدا اطلاعاتی از خود دستور نمایش داده میشود و سپس با وارد کردن عبارات نتیجه محاسبه و نمایش داده میشود. در پایان نیز با دستور quit از حالت تعاملی خارج میشود.
نکته: دستور bc هیچ محدودیتی در اندازهی اعداد قائل نمیشود.
مثال:
$ bc 9238472938742937 * 29384729347298472 271470026887302339647844620892264