حال که میتوانید بدون دردسر توصیفگرهای فایل را برای هدایت انواع معینی از خروجیها به فایلهای معین، مدیریت نمایید، وقت آنست که رموز مبتکرانهتری که برای تغییرمسیر ورودی و خروجی در دسترس میباشد را بیاموزید.
میتوانید از تغییرمسیرفایل برای نوشتن خروجی در فایلها یا خواندن ورودی از فایلها، استفاده کنید. اما اگر بخواهید خروجی یک برنامه را به طور مستقیم به ورودی برنامه دیگر مربوط کنید چطور؟ از آن طریق میتوانید زنجیر پیوستهای از پردازش خروجی ایجاد کنید. اگر از قبل درباره
$ ls $ mkfifomyfifo ; lsmyfifo $ grepbea myfifo & [1] 32635 $ echo "rat > cow > deer > bear > snake"> myfifo bear
از دستور mkfifo برای ایجاد یک فایل جدید به نام 'myfifo' در دایرکتوری جاری استفاده کردیم. این یک فایل معمولی نیست، بلکه یک
در مثال ما،
اما این فایلهای موقتی یک اذیت واقعی هستند. شاید شما مجوز نوشتن نداشتهباشید. لازم است به خاطر داشته باشید که فایلهای موقتی که ایجاد نمودهاید را پاک کنید. لازم است مطمئن شوید که دادهها وارد و خارج میشوند، یا شاید
به خاطر این مسائل، ویژگی دیگری در دسترس قرارگرفته است: لولهها. در اصل، لوله فقط
$ echo "rat > cow > deer > bear > snake"| grepbea bear
لوله با استفاده از عملگر
لولهها به طور وسیعی به عنوان پسپردازش خروجی برنامهها به کار میروند. به
عملگر لوله برای هر دستور یک محیط پوسته فرعی ایجاد میکند. آگاهی از این مطلب اهمیت دارد، به علت آنکه، هر متغیری که در دستور دوم تعیین یا ویرایش کنید، در خارج از آن به صورت ویرایش نشده قبلی ظاهر میگردد. اجازه بدهید تشریح نمایم:
$message = Test $ echo 'Salut, le monde!'| readmessage $ echo "The message is:$ message "The message is: Test $ echo 'Salut, le monde!'| { readmessage ; echo "The message is: $message";} The message is: Salut, le monde! $ echo "The message is:$ message "The message is: Test
وقتی خط لوله به پایان میرسد، پوستههای فرعی که برای آن ایجاد شدهاند نیز خاتمه مییابند. همراه با پوستههای فرعی، هر تغییر و تبدیل انجام شده در آنها نیز از بین میرود. بنابراین مراقب باشید!
تکرار مفید:
لولهها به عنوان پسپردازشگر خروجی برنامهها، خیلی جالب هستند. به هرحال، شما بایدمراقب باشید در کاربرد آنها زیادهروی نکنید. اگر شما خطلولهای که شامل سه برنامه یا بیشتر باشد را به انتها برسانید، وقت آنست که از خود بپرسید آیا در حال انجام امور به روش هوشمندانهای هستید؟ امکان دارد قادر باشید ویژگیهای بیشتری از برنامه را نسبت به آنچه در یک پسپردازش در لوله به کار گرفتهاید، استفاده کنید. هر دستور جدید در یک خطلوله موجب یک پوسته فرعی جدید میگردد و یک برنامه جدید باید بارگزاری شود. همچنین این مطلب دنبال کردن منطق اسکریپت شما را دشوار میسازد!
من متغیرهایی را در یک حلقه مقرر میکنم. چرا آنها پس از اتمام حلقه، ناگهان ناپدید میگردند؟ یا، چرا نمیتوانم دادهها را برای خواندن لولهکشی نمایم؟
چطور میتوان دو پردازش را با استفاده از لولههای بانام (fifoها)به یکدیگر ارتباط داد؟
گاهی نگهداری دادهها در یک فایل زائد است. ممکن است فقط مقدار بسیارکمی داشته باشیم -- مناسب برای به راحتی گنجاندن آن در خود اسکریپت .یا ممکن است خواسته باشیم محتوای متغیری را ، بدون آنکه اول آن را در یک فایل بنویسیم، به یک دستور تغییر مسیر بدهیم.
$ grep proud<< END > I am a proud sentence. >END I am a proud sentence.
این یک Heredoc (یا سند اینجا) میباشد. وقتی میخواهید یک قطعه کوچک چند سطری دادهها را در اسکریپت خود تعبیه کنید Heredocها سودمند هستند. (تعبیه قطعات بزرگ تکنیک نامناسبی است. شما باید منطق خود(کد خودتان) و ورودی خود(دادههایتان) را جداگانه و ترجیحاً در فایلهای مختلف نگاه دارید، مگر اینکه دادهها جزئی باشند.)
در یک Heredoc، کلمهای برای ایفای نقش نگهبان انتخاب میکنیم. هر کلمهای میتواند باشد، ما از
چند مورد متمایز برای Heredocها وجود دارد. به طور معمول، نمیتوانید آنها را دندانهدار کنید، همه فاصلههایی که در اینجا برای دندانهدار کردن اسکریپت به کار ببرید در
echo "Let's test abc:"if [[ abc = a * ]]; then cat<< END abc seems to start with an a!END fi
چنین نتیجه خواهد داد:
Let's test abc: abc seems to start with an a!
میتوانید با حذف موقتی توگذاری برای سطرهای Heredocهای خود، از این مطلب اجتناب کنید. به هر حال، موجب بدشکل شدن تورفتگی شکیل و زیبای شما میگردد. یک جایگزین وجود دارد. اگر از
به طور پیشفرض، جایگزینیهای BASH در محتوای Heredoc انجام میشود. هر چند، اگر کلمهای که برای جداکردن Heredoc خود به کار میبرید را نقلقولی نمایید، BASH هیچگونه جایگزینی در محتویات انجام نخواهد داد. برای دیدن تفاوت، این مثال را با و بدون کاراکترهای نقلقول امتحان کنید:
$ cat<<' XYZ ' > My home directory is$ HOME >XYZ My home directory is $HOME
رایجترین کاربرد Heredocها، در ارائه مستندات به کاربر است:
usage() { cat<< EOF usage: foobar [-x] [-v] [-z] [file ...] A short explanation of the operation goes here. It might be a few lines long, but shouldn't be excessive.EOF }
حالا اجازه بدهید Herestring خیلی مشابه اما فشردهتر را آزمایش کنیم:
$ grepproud <<< "I am a proud sentence"I am a proud sentence.
ایندفعه،
$ grepproud <<< "$USER sits proudly on his throne in$ HOSTNAME ."lhunath sits proudly on his throne in Lyndir.
Herestringها کوتاهتر، کمتر مزاحم، و به طور کلی مناسبتر از Heredocهای حجیم همتای خود میباشند. گرچه آنها قابل حمل به پوسته Bourne نیستند.
بعداً، شما در باره لولهها و اینکه چطور میتوانند برای ارسال خروجی یک دستور به
$ echo 'Wrap this silly sentence.'| fmt -t -w 20Wrap this silly sentence. $ fmt-t -w 20<<< 'Wrap this silly sentence.'Wrap this silly sentence.
heredocهای بلند به طور معمول ایده نامناسبی هستند، زیرا اسکریپتها باید محتوی منطق باشند، نه دادهها. اگر اسکریپت به سند حجیمی نیاز دارد، باید آن را در یک فایل جداگانه با اسکریپت همراه کنید. با این وجود Herestringها، اغلب کاملاً سودمند هستند بویژه برای ارسال محتوای یک متغیر(به جای فایلها) به فیلترهایی مانند grep یا sed.
در مستندات گنو: Here Documents, Here Strings