4. تغییر مسیر
اساسی ترین شکل دستکاری ورودی و خروجی در BASH تغییر مسیر است. تغییر مسیر برای تغییر منبع داده یا مقصد توصیفگرهای فایل یک برنامه کاربردی به کار میرود. به طریقی، که میتوانیدخروجی برنامه را به جای ترمینال به یک فایل ارسال کنید، یا برنامهای داشته باشید که به جای خواندن از صفحه کلید از یک فایل بخواند.
همچنین، تغییر مسیر به اشکال مختلف میباشد. که عبارتند از تغییر مسیر فایل، دستکاری توصیفگرفایل، Heredocها و Herestringها.
در مستندات گنو: Redirections
تغییر مسیر: شیوه تغییر یک توصیفگرفایل معین برای خواندن وردیاش از جای دیگر یا ارسال خروجیاش به جایی دیگر میباشد
4.1. تغییر مسیر فایل
تغییر مسیر فایل تغییر یک توصیفگر فایل منفرد برای اشاره به یک فایل را شامل میگردد. بیایید با یک تغییر مسیر خروجی شروع کنیم:
$ echo \"It was a dark and stormy night. Too dark to write.\"> story $ catstory It was a dark and stormy night. Too dark to write.
عملگر
در نتیجه، فرمان echo خروجیاش را به ترمینال ارسال نمیکند، به جای آن، تغییر مسیر
بایستی توجه گردد که این تغییر مسیر فقط برای دستور منفرد echo که برایش به کار برده شده، مؤثر است . دستورات دیگری که بعد اجرا میشوند، ارسال خروجی خود به محل
سپس ما از برنامه cat برای چاپ محتویات آن فایل استفاده کردیم. cat برنامه کاربردی است که محتویات تمام فایلهایی که به عنوان شناسه به آن دادهایم را میخواند. سپس هر فایل را یکی پس از دیگری به
هشدار:مثالهای بسیار زیادی از کد ها و خودآموزهای شل در اینترنت به شما میگویند، هر جا احتیاج به خواندن محتویات یک فایل دارید از cat استفاده کنید. این کار ضرورت ندارد! cat در الحاق چند فایل به یکدیگر خوب خدمت میکند، یا به عنوان یک ابزار سریع در اعلان شل برای دیدن آنچه داخل یک فایل است. شما نباید از cat در اسکریپتهای خود برای لولهکشی فایلها به دستورات، استفاده کنید. تقریباً همیشه راههای بهتری برای انجام این کار وجود دارد. لطفاً این هشدار را به خاطر بسپارید. استفاده بیمورد از cat صرفاً به ایجاد یک پردازش اضافی منجر خواهد شد، و غالباً سرعت خواندن ضعیفتری را نتیجه میدهد، زیرا cat نمیتواند مفهوم آنچه میخواند و هدفی که داده، برای آن خوانده میشود را تشخیص دهد.
موقعی که ما برنامه cat را بدون هرگونه شناسهای به کار میبریم، به طور آشکاری نمیداند که کدام فایل را بخواند. در این وضعیت، cat به جای خواندن از یک فایل، فقط از
$ cat
حتی اعلان فرمان را به شما باز نمیگرداند! چه اتفاقی رخ میدهد؟ cat هنوز در حال خواندن از
$ cattest? test?
حالا چرا test? را دو مرتبه نمایش میدهد؟ خوب، همانطور که شما تایپ میکنید، ترمینال شما تمام کاراکترهایی را که به
بیایید یک تغییر مسیر ورودی را برای پیوست یک فایل به
$ cat< story The story of William Tell. It was a cold december night. Too cold to write.
نتیجه این دقیقاً همانند نتیجه cat
عملگرهای تغییر مسیر میتوانند با تقدم یک عدد همراه گردند. آن عدد توصیفگرفایلی که تغییر میکند را مشخص مینماید.
اجازه دهید با چند مثال خلاصه کنیم:
command
> file :خروجی استاندارد فرمان را بهfile ارسال میکند.command 1
> file :خروجی استاندارد فرمان را بهfile میفرستد. چون خروجی استاندارد در FD شماره1 باز شده، عدد آن رابر عملگر تغییر مسیر مقدم نمودهایم. توجه،تأثیر این درست مانند مثال قبل است، زیرا FD شماره 1 پیشفرض عملگر > میباشد.command
< file : موقعی که فرمان ازstdin میخواند، محتویاتfile را به کار میبرد.command
0 < file : موقعی که فرمان ازstdin میخواند، محتویاتfile را استفاده میکند، دقیقاً مانند مثال قبل، چون FD شماره0 (stdin) پیشفرض عملگر < میباشد.
عدد مربوط به FD(توصیفگرفایل)
$for homedir in /home/* >do rm \"$ homedir /secret \" >done 2> errors
در این مثال، روی هر دایرکتوری(یا فایل) در شاخه /home حلقه ایجاد میکنیم. سپس ما سعی در حذف فایل
ممکن است توجه نموده باشید که عملگرتغییر مسیر روی فرمان rm نمیباشد، بلکه روی
اجازه بدهید ببینیم نتیجه حلقه ما چه بوده:
$ caterrors rm: cannot remove `/home/axxo/secret\': No such file or directory rm: cannot remove `/home/lhunath/secret\': No such file or directory
دو پیغام خطا در فایل ثبت خطا. دو نفر که فایل
اگر یک اسکریپت مینویسید، و پیشبینی میکنید که یک دستور معین تحت شرایطی ممکن است ناموفق باشد، اما نمیخواهید کاربر اسکریپت، با خطاهایی که ممکن است دستور ایجاد کند پریشان گردد، میتوانید FD آن را ساکت کنید. ساکت کردن آن به آسانی یک تغییر مسیر فایل معمولی است. فقط تمام خروجی برای آن FD را به سیاهچاله سیستم ارسال میکنیم:
$for homedir in /home/* >do rm \"$ homedir /secret \" >done 2 > /dev/null
فایل /dev/null همیشه خالی است، مسئلهای نیست که در آن چه مینویسید یا از آن میخوانید. همینطور، موقعی که ما پیغام خطاها را در آن مینویسیم، آنها ناپدید میشوند. فایل /dev/null همچنان مانند قبل خالی میماند. چنین است زیرا یک فایل معمولی نمیباشد، یک دستگاه مجازی است. بعضیها /dev/null را bit bucketزیرنویس مترجم 1 مینامند.
یک مطلب نهایی هست که باید در باره تغییر مسیر فایل بدانید. جالب است که شما میتوانید یک فایل ثبت وقایع برای نگهداری پیغامهای خطایتان ایجاد کنید، اما همانطور که قبلاً اشاره کردم، BASH موقعی که به یک فایل تغییر مسیر داده میشود، محتویات موجود آن فایل را ازبین میبرد. در نتیجه، هر دفعه که ما آن حلقه را برای حذف کردن فایلهای secret اجرا کنیم، فایل ثبت وقایع ماقبل از اینکه دوباره با پیغامهای جدید پر شود،از سر کوتاه و خالی میشود. چه کار باید بکنیم، اگر میخواهیم رکوردی از هر پیغام خطای تولید شده در حلقه را حفظ کنیم؟ چه کار کنیم که با هر بار اجرای حلقهزیرنویس مترجم 2 فایل از سر کوتاه نشود؟ چاره کار با دوگانه کردن عملگر تغییر مسیر به دست میآید.
$for homedir in /home/* >do rm \"$ homedir /secret\" >done 2 >> errors
!Hooray
درضمن، فاصله بین عملگر تغییر مسیر و نام فایل، اختیاری است. بعضی افراد مینویسند
تکرار مفید:
وقتی که یک برنامه به فایل دادهای نیاز دارد، و برای خواندن داده ازstdin ساخته میشود، تغییر مسیر ایده خوبی است. مقدار بسیار زیادی نمونههای بد در اینترنت هست، که به شما میگویند خروجی cat را به پردازشها لولهکشی(بعد میخوانید) کنید، اما این چیزی بیش از یک ایده نامساعد نمیباشد.
موقعی که برنامه ای طراحی مینمایید که میتواند دادهها را از منابع مختلفی تغذیه کند، واقعاً اغلب بهترین راه آنست که برنامه شما ازstdin بخواند، به این ترتیب، کاربر میتواند از تغییر مسیر برای تغذیه برنامه از هر آنچه مایل است، استفاده کند. یک برنامه کاربردی که ورودی استاندارد را از یک مسیر کلی میخواند filter نامیده میشود.
در مستندات گنو: Redirecting Input, Redirecting Output, Appending Redirected Output, Redirecting Standard Output and Standard Error
مترجم: bit bucket در اصل برای مخزنی موهوم جهت گرفتن بیتهایی که با دستورالعمل shift اسمبلی به انتهای یک ثَبّات(register) عقب رانده میشوند به کار رفته است (1)مترجم: منظور از هر بار اجرای حلقه در این قسمت آن است که اگر به فرض این حلقه در یک اسکریپت باشد، با هر بار اجرای آن اسکریپت، فایل خالی و بازنویسی می شود. نه تکرار حلقه که به ازای هر مقدار homdir انجام میشود. چون همانطور که قبلاًتوضیح داده شده برای جلوگیری از خالی شدن فایل به ازای مقادیر homdir، در هر بار تکرار حلقه، عملگر تغییر مسیر بعد از کلمهکلیدی done قرار داده شده است. (2)