فصل نهم - کاراکترهای نقل
در فصل قبل با جانشینیها در شل آشنا شدید. آنها با استفاده از یک الگو یا
کاراکتر امکان جانشین کردن عبارات را برای شما مهیا میکردند. این یکی از
ویژگیهای مفید شل بود که در فصل قبل با آن آشنا شدید. اما در بعضی مواقع
لازم است تا هر کاراکتر خاص(کاراکترهایی مانند * $ [], ...) دقیقا به جای
خود استفاده شود نه به عنوان جانشین و نیاز است تا این قابلیت غیر فعال
شود. به غیر فعال کردن این قابلیت، نقل و قول کاراکتر گفته میشود، که به
یکی از سه شکل زیر قابل استفاده است:
- استفاده از کاراکتر بک اسلش \
- استفاده از کاراکتر نقل منفرد(single quote) ' '
- استفاده از کاراکتر نقل دوگانه(double quote) " "
نحوهی صحیح استفاده از کاراکترهای نقل حتی برای برنامهنویسهای خبرهی یونیکس نیز گاهی اوقات میتوانند مسئله بسیار پیچیدهای شوند. در این فصل با این سه شکل از نقل آشنا شده و نحوهی استفاده از آنها را به طور ساده خواهید آموخت. همچنین قواعد سادهای میاموزید که متوجه میشوید در چه زمانی و چگونه باید از کاراکترهای نقل استفاده نمود.
محتویات[نهفتن] |
کاراکتر بک اسلش (\)
در ابتدا از دستور echo برای مشاهده کاراکترهای ویژه استفاده میکنیم. دستور echo به طور کامل در فصل ۱۳ ،ورودی/خروجی شرح داده میشود، ولی در اینجا شکل سادهای از این دستور را استفاده میکنیم که فقط یک آرگومان به عنوان ورودی گرفته و آنرا چاپ میکند. برای مثال:
$ echo Hello world
منجر به تولید خروجی زیر میشود:
Hello world
حالا خروجی را در صورتی که از یکی از کاراکترهای ویژه استفاده کنیم، مشاهده کنید:
$ echo Hello; world Hello bash: world: command not found...
اشاره: در خط زیر اکثر کاراکترهای ویژه را مشاهده میکنید. به کاراکترهای ویژه، متاکاراکتر نیز گفته میشود.
* ? [ ] ' " \ $ ; & ( ) | ^ < > new-line space tab
کاراکتر سمی کالن (;) در شل به معنی پایان یک دستور است و هرچه در
ادامهی آن قرار گیرد به عنوان دستور جدید قلمداد میشود و با استفاده از
این کاراکتر میتوان چندین دستور را در یک خط نوشت.
با توجه به این توضیحات، در اینجا world به عنوان یک دستور جدید تلقی میشود
و چون چنین دستوری در شل وجود ندارد شما یک پیغام خطا دریافت خواهید
نموند. در صورتی که شما انتظار داشتید پیغام Hello world را مشاهده کنید.
برای حل این مشکل میتوان از کاراکتر بک اسلش(\) استفاده نموند. استفاده از \
در پشت کاراکترهای خاص معنی ویژه آنها را از بین میبرد و میتوان از آنها
به عنوان کاراکترهای معمولی استفاده کرد.
$ echo Hello\; world Hello\; world
توجه کنید که در مثال قبل خود کاراکتر \ در خروجی چاپ نمیشود.
مثالی دیگر:
$ echo You owe $1250
این دستور مشابه استفاده از دستور سادهی خروجی با استفاده از echo است. ولی خروجی چیزی متفاوت از انتظار شماست. زیرا $1 یکی متغیرهای ویژه در شل است. خروجی مطابق زیر باشد:
You owe 250
برای دستیابی به خروجی صحیح باید از کاراکتر \ قبل از کاراکتر ویژهی $ استفاده کرد:
$ echo You owe \$1250 You owe $1250
نکته: در این مثال هم مانند مثال قبل کاراکتر \ در خروجی چاپ نمیشود. برای چاپ هر کاراکتر \ در خروجی باید از دو کاراکتر \ استفاده نموند.
مثال:
$ echo You owe \\\$1250 You owe \$1250
استفاده از single quote (' ')
زمانی که تعداد کاراکترهای ویژه در یک عبارت زیاد باشد یا به ویژه بودن
یک کاراکتر شک داشته باشیم استفاده از بک اسلش چندان مناسب نیست. برای این
منظور میتوان از single quote استفاده نمود.
مثال.
در زیر عبارتی را مشاهده میکنید که شامل چندین کاراکتر ویژه است:
$echo <-$1250.**>; (update?) [y|n]
که برای چاپ صحیح این عبارت با استفاده از \ باید به صورت زیر عمل کرد:
$echo \<-\$1250.\*\*\>\; \(update\?\) \[y\|n\]
راه سادهتر انجام این عمل استفاده از کاراکتر نقل منفرد(') است به این که
صورت در ابتدا و انتهای عبارت از این کاراکتر استفاده میکنیم. مثال بالا را
میتوان به شکل زیر نیز پیاده کرد:
echo '<-$1250.**>; (update?) [y|n]'
در این حالت تمام کاراکترهایی که داخل نقل قول یگانه قرار میگیرند معنای
ویژه خود را از دست میدهند و در دستور echo فقط به عنوان یک کاراکتر
معمولی به آنها نگاه میشود.
توجه: استفاده از نقل قول یگانه برای کاراکترهای معمولی بیخطر است. شما میتوانید برای کل یک عبارت که شامل حروف، اعداد و کاراکترهای ویژه است بدون مشکل از نقل قول یگانه استفاده کنید.
نکته: در صورتی که خود کاراکتر نقل یگانه در عبارتی موجود باشد، شما نباید برای چاپ آن کل عبارت را داخل نقل یگانه قرار دهید. زیرا منجر به بروز نتیجهی اشتباه میشود.
عبارت زیر را در نظر بگیرید:
$echo 'It's Friday' > _
تنها عملی که بعد از اجرای این دستور انجام میشود، نمایش خروجی به شکل
< است. این علامت به معنی ورود یک دستور چند خطی است که هنوز کامل نشده
است.
برای دستیابی به نتیجه صحیح میتوانید از یکی از دو کاراکتر \ یا double
quote (که در بخش بعد بررسی شده است) استفاده کنید.
مثال:
$echo It\'s Friday
استفاده از double quote " "
در بخش قبل نحوهی استفاده از single quote توضیح داده شد. عبارت زیر میتواند نمونهای از کاربرد کاراکتر single quoteباشد:
$echo '$USER owes <-$1250.**>; [ as of (`date +%m/%d`) ]'
که منجر به چاپ عبارت زیر میشود:
$USER owes <-$1250.**>; [ as of (`date +%m/%d`) ]
اما در این موارد ممکن است این دقیقا عبارت مد نظر شما نباشد. کاراکتر
نقل یگانه از جانشینی متغیرها جلوگیری میکند. در نتیجه USER$ با مقدار
واقعی خود جانشین نمیشود. همچنین کاراکتر نقل یگانه از جانشینی دستورات نیز
جلوگیری میکند در نتیجه خروجی دستور date +%m/%d نیز جانشین نمیشود. در
نتیجه استفاده از کاراکتر نقل یگانه در این موارد مفید نیست.
برای حل اینگونه مشکلات میتوان از کاراکتر نقل دوگانه " استفاده نموند.
به طور کلی کاراکتر نقل دوگانه در موارد زیر معنای عبارات و کاراکترهای ویژه را حفظ میکند:
- برای کاراکتر $
- کاراکتر ` برای جانشینی در دستورات
- $\ برای استفاده از کاراکتر $
- '\ برای استفاده از کاراکتر '
- "\ برای استفاده از کاراکتر "
- \\ برای استفاده از کاراکتر \
- همچنین تمام کاراکترهای معمولی که بعد از \ بیایند
حالا خروجی مثال قبل را با "" مشاهده کنید:
$echo "$USER owes <-$1250.**>; [ as of (`date +%m/%d`) ]" baroon owes <-250.**>; [ as of (12/21) ]
همانطور که مشاهده میکنید کاراکتر نقل دوگانه به شما اجازهی استفاده از بسیاری کاراکترهای خاص به عنوان کاراکترهای معمولی را میدهد، در حالی که در بعضی موارد این مانند کاراکتر $ این تبدیل انجام نمیشود و کاراکتر $ به معنای ویژه خود استفاده میشود. توجه کنید در این مثال همچنان مقدار 1250$ به دلیل وجود 1$ به درستی نمایش داده نمیشود که باید برای اصلاح آن از بک اسلش \ استفاده نموند.
echo "$USER owes <-$\1250.**>; [ as of (`date +%m/%d`) ]" baroon owes <-1250.**>; [ as of (12/21) ]
یک مثال دیگر:
$echo "The DOS directory is \"\\windows\\temp\"" The DOS directory is "\windows\temp"
مقایسه کاراکترهای نقل
نقل قول یگانه ' ' : تمام کاراکترهای ویژه و معمولی داخل این نقل، به عنوان کاراکترهای معمولی در نظر گرفته میشوند.
نقل قول دوگانه " " : به جز موارد زیر بقیه کاراکترها به عنوان کاراکترهای عادی در نظر گرفته میشوند.
( $ ` \\ \$ \' \" )
بک اسلش \ : قبل از هر کارکتر ویژه قرار بگیرد، آن کاراکتر معادل کاراکتری خود را پیدا میکند.
قواعد و وضعیتهایی که میتوان از کاراکترهای نقل استفاده کرد
در ادامه چند مورد از استفادههای کاراکترهای نقل شرح داده شده است:
نادیده گرفتن مرز کلمات
اجباری به استفاده از کاراکترهای نقل دوگانه یا منفرد در ابتدا یا
انتهای عبارات نیست. به بیان دیگر میتوان از کاراکترهای خاص در وسط یک
عبارت نیز استفاده کرد.
به عنوان مثال هر دو دستور زیر یک خروجی تولید میکنند:
echo Hel"lo; w"orld echo "Hello; world" Hello; world
ترکیب کاراکترهای نقل مختلف در دستورات
شما آزادید در یک عبارت به هر شکل ممکن کاراکترهای نقل را با هم ترکیب
کنید و از یک یا چند کاراکتر نقل برای رسیدن به نتیجهی مطلوب سدر یک عبارت
استفاده کنید.
مثال:
echo The '$USER' variable contains this value \> "|$USER|" The $USER variable contains this value > |baroon|
تعبیه کردن چندین فاصله به عنوان یک آرگومان
در شل یک یا چند فاصله، tab به صورت یک آرگومان برای یک دستور در نظر گرفته میشوند. به عنوان مثال عبارت زیر را در نظر بگیرید:
$echo Name Address
که منجر به تولید خروجی زیر میشود:
Name Address
در این مثال اگرچه چندین فاصله بین دو کلمه Name و Address وجود دارد،
ولی شل تمام آنها را به عنوان یک آرگومان در نظر میگیرد و در نتیجه دستور
echo چندین فاصله را چاپ نمیکند.
برای این منظور میتوان از کاراکترهای نقل استفاده کرد:
$echo "Name Address" Name Address
مثال: برای ایمیل کردن یک پیغام خاص به چندین کاربر میتوان از یکی از سه دستور زیر استفاده کرد:
mail -s Meeting\ tomorrow fred jane < meeting.notice mail -s 'Meeting tomorrow' fred jane < meeting.notice mail -s "Meeting tomorrow" fred jane < meeting.notice
توجه کنید به عنوان مثال اگر در شکل اول از \ استفاده نشود، کلمه tomorrew نیز به عنوان یکی از کاربران در نظر گرفته میشود.
ادامه دادن عبارت در خط بعد
در پایان هر کدام از خطوطی که در محیط شل یا یک ویرایشگر متن قرار
دارند، یک کاراکتر خط جدید وجود دارد. به عبارت دیگر آخرین کاراکتر هر خط،
کاراکتر خط است. در واقع شل با مشاهده این کاراکتر است که متوجه میشود که
خط جاری تمام شده و در نتیجه به سراغ خط بعدی میرود.
شما میتوانید با استفاده از کاراکترهای نقل عباراتی بنویسید که میتوانند شامل یک یا چند کاراکتر خط جدید نیز باشند.
مثال: هر دو دستور زیر منجر به تولید یک خروجی میشوند:
$ echo 'Line 1 > Line 2'
$ echo "Line 1 > Line 2"
که هر دو منجر به تولید زیر میشوند:
Line 1 Line 2
مثال: همچنین میتوان با استفاده از بک اسلش \ ادامهی یک دستور را در خط بعدی ادامه داد:
$ cp file1 file2 file3 file4 file5 file6 file7 \ > file8 file9 /tmp
که معادل دستور زیر است:
$ cp file1 file2 file3 file4 file5 file6 file7 file8 file9 /tmp
دستکاری فایلی که اسم آن شامل کاراکترهای خاص آن
در فصل قبل آموختید که هر کدام از کاراکترهای * ? [] معنای خاصی
دارند و استفاده از آنها هنگام دسترسی به فایلها، موجب جانشینی نام میشود.
به عنوان مثال دستور زیر تمام فایلهایی که با ch1 شروع میشوند را حذف میکند:
$ rm ch1*
فرض کنید بعد از انجام این دستور فایلهای زیر از دایرکتوری جاری حذف شوند:
ch1 ch1* ch1a ch15
توجه کنید که نام یکی از فایلها *ch1 است و شما تنها قصد حذف کردن همین
فایل را دارید، در صورتی که دستور بالا تمام فایلها را پاک میکند.
برای این منظور و برای جلوگیری از بروز مشکلات اینچنین میتوان از
کاراکترهای نقل استفاده کرد، در این صورت دستور بالا به شکل زیر تبدیل
میشود:
$ rm 'ch1*'
که در این حالت تنها فایل با نام *ch1 حذف میشود.
عبارات منظم
دربارهی عبارات منظم در فصل ۱۶ باعنوان "فیلترهای متن و عبارات منظم"
به صورت مفصل توضیح داده شده است. یکی از کاربردهای عبارات منظم استفاده به
عنوان جانشین در نامفایل است که در دستور grep به شکل زیر میتوانند
مورد استفاده قرار بگیرد :
(دستور grep در فصل ۱۵ "فیلترهای متن"بررسی شده است)
grep '[0-9][0-9]*$' report2 report7
رشته $*[0-9][0-9] که بین دو single quote قرار دارد، یک عبارت منظم است و در اینجا در محتوای فایلهای report2 و report7 به دنبال آن جستوجو میشود. جانشینهایی که به عنوان الگو در دستور grep قرار میگیرند باید در بین دو کاراکتر نقل قرار بگیرند.
نکته: هنگام استفاده از عبارات منظم برای جلوگیری از بروز مشکل باید همیشه آنها در بین دو کاراکتر نقل قرار داد، هر چند که در برخی موارد هم بدون انجام این کار میتوان به درستی از آنها استفاده کرد.
استفاده از n\ در دستور echo
در فصل ۱۳ "ورودی/خروجی" به چگونگی استفاده از برخی کاراکترهای خاص مانند n\ در دستور echo پرداخته میشود.
مثال:
$ echo -e "Line 1\nLine 2"
خروجی این دستور به صورت زیر میباشد:
Line 1 Line 2
همانطور که در این مثال مشاهده میکنید، استفاده از آپشن e در دستور echo موجب فعال شدن قابلیت استفاده از کاراکترهای خاص میشود.
در اینجا کاراکتر n\ همانند کاراکتر خط جدید عمل میکند.
در صورتی که کاراکتر n\ بین کاراکترهای نقل منفرد یا دوگانه قرار نگیرد به عنوان کاراکتر خاص عمل نمیکند.
اگر دستور بالا را به صورت زیر اجرا کنیم:
$ echo -e Line 1\nLine 2
خروجی زیر حاصل میشود:
Line 1\nLine 2
که در آن n\ به عنوان کاراکتر خاص در نظر گرفته نمیشود.
استفاده در دستور cpio
از این دستور برای ذخیره و بازیابی فایلها استفاده میشود. که شل را
قادر میسازد تا برای انتخاب فایلها از جانشینها در نام فایل استفاده کند،
به صورتی که این جانشینی برای نام باید در بین کاراکترهای نقل منفرد ' '
قرار بگیرد.
مثال:
$cpio -icvdum 'usr2/*' < /dev/rmt0
که در این دستور آپشن icvdum نحوهی بازگشت اطلاعات و رشته */usr2 مشخص کنندهی تمام فایلهای موجود در دایرکتوری usr2 است.
استفاده در دستور find
این دستور در فصل ۱۸ به طور کامل بررسی شده است و در اینجا به ذکر یک مثال از کاربرد نقل منفرد در دستور find بسنده میکنیم
مثال:
$find / -name 'ch*.doc' -print
در این مثال استفاده از عبارت ch*.doc به این معنی است که دستور find تمام فایلهای موجود در دایرکتوری ریشه که با ch شروع میشوند و با doc. پایان میابد را نمایش دهد.
Eman ۱۵ فوریهٔ ۲۰۱۲، ساعت ۱۱:۵۱ (UTC)