یکی از مسائل بسیار مهمی که هنگام اسکریپت نویسی به زبان بش قطعا از آن بارها استفاده خواهیذ کرد انتقال خروجی دستورهای لینوکس به یک فایل می باشد. این کار بسیار ساده بوده و کافیست در این آموزش با ما همراه باشید تا روش های مختلفی که برای نوشتن خروجی دستورهای لینوکس در یک فایل وجود دارد را با یکدیگر بررسی کنیم.
روش اول
در این روش شما از علامت های < و << میتوانید در پایان هر دستور استفاده کنید. در اینجا خروجی یک فایل فارغ از اینکه دستور درست اجرا شده باشد یا نادرست در فایل مورد نظر شما ذخیره میشود. علامت < برای بازنویسی در فایل استفاده میشود. بعنوان مثال اگر شما فایلی را ایجاد نکرده اید و یا ایجاد کرده اید و محتوای آن خالیست یا حتی محتوای آن پر باشد برای آن فرقی نمیکند و اطلاعات مورد نظر شما را در فایل ذخیره میکند.
فرض کنید فایل out.txt وجود ندارد و شما میخواهید خروجی یک دستور به عنوان مثال دستور ls را در آن ذخیره کنید. ابتدا خروجی دستور ls را در مسیر که هستیم بررسی میکنیم تا به محتویات دایرکتوری که در آن هستیم پی ببریم:
1 2 |
lsc@arshatech:$ ls dir1 dir2 dir3 file1.txt file2.txt file3.txt file4.txt |
حال اگر بخواهیم این خروجی را به فایل out.txt ببریم در حالی که out.txt یا وجود ندارد و یا وجود دارد و محتوای آن خالیست(فرض میکنیم این فایل در شاخه tmp/ قرار دارد):
1 |
lsc@arshatech:$ ls > /tmp/out.txt |
حال اگر بخواهیم محتوای فایل را بررسی کنیم خواهیم داشت:
1 2 3 4 5 6 7 8 |
lsc@arshatech:$ cat /tmp/out.txt dir1 dir2 dir3 file1.txt file2.txt file3.txt file4.txt |
مشاهده میکنید که خروجی دستور در فایل مورد نظر ذخیره شده است. حال اگر مجددا بخواهیم این کار را انجام دهیم(انتقال خروجی ls یا هر دستور دیگر) اتفاقی که می افتد این است که محتوای قبلی فایل out.txt پاک شده و خروجی روی محتوای قبل بازنویسی میشود.
حال اگر از علامت << استفاده بشود خروجی دستور جدید به انتهای فایل اضافه و یا به اصطلاح append میشود:
1 |
lsc@arshatech:$ ls >> /tmp/out.txt |
محتوای خروجی دستور فوق را با هم بررسی میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
lsc@arshatech:$ cat /tmp/out.txt dir1 dir2 dir3 file1.txt file2.txt file3.txt file4.txt dir1 dir2 dir3 file1.txt file2.txt file3.txt file4.txt |
همانطور که ملاحظه میکنید خروجی به انتهای فایل اضافه شده است.
حال در صورتی که یک دستور در لینوکس به صورت نادرست در ترمینال وارد بشود و یا خروجی دستور دارای خطا باشد دیگر محتوای نمایش داده شده در ترمینال در فایل مورد نظر ذخیره نمیشود و فایل out.txt اگر دارای محتوا هم باشد با این کار محتوای آن پاک میشود و چیزی در آن ریخته نمیشود:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
lsc@arshatech:$ lss > /tmp/out.txt No command 'lss' found, did you mean: Command 'lsh' from package 'lsh-client' (universe) Command 'ss' from package 'iproute2' (main) Command 'les' from package 'atm-tools' (universe) Command 'ls' from package 'coreutils' (main) Command 'less' from package 'less' (main) Command 'lsx' from package 'suckless-tools' (universe) Command 'lssu' from package 'nilfs-tools' (universe) Command 'lvs' from package 'lvm2' (main) Command 'ass' from package 'irpas' (multiverse) Command 'gss' from package 'libgss-dev' (universe) Command 'lrs' from package 'lrslib' (universe) Command 'lsw' from package 'suckless-tools' (universe) lss: command not found |
ما دستور ls در لینوکس را به صورت عمدی به شکل lss نوشتیم تا دستور با خطا مواجه شود. شما میتوانید از علامت & نیز برای ذخیره دستور چه به صورت صحیح وارد شده باشد چه به صورت غلط استفاده کنید. به مثال زیر توجه نمائید:
1 |
lsc@arshatech:$ ls &> /tmp/out.txt |
در این روش با توجه به اینکه خطایی دریافت نشده است محتوای دستور در فایل out.txt ذخیره شده است. حال اگر بجای ls از دستوری که خطا برمیگرداند استفاده بشود با همان مکانیزم استفاده از & خواهید دید که محتوای خطا در فایل out.txt ذخیره میشود.
روش دوم
ما در این روش از دستور tee برای ذخیره سازی خروجی استفاده میکنیم. این دستور به خودی خود مانند علامت < در روش اول عمل میکند و چنانچه از سوئیچ ‘a-‘ (حرف کوچک) در کنار آن استفاده کنیم رفتاری مشابه علامت << در روش اول خواهد داشت. تنها تفاوت دستور tee با روش قبل این است که در هنگام استفاده از این دستور علاوه بر اینکه خروجی در فایل مورد نظر ذخیره میشود همزمان خروجی ها بر روی ترمینال نیز نمایش داده میشود:
1 2 3 4 5 6 7 8 |
lsc@arshatech:$ ls | tee /tmp/out.txt dir1 dir2 dir3 file1.txt file2.txt file3.txt file4.txt |
اگر بعد از دستور tee از سوئیچ ‘a-‘ استفاده کنید علاوه بر اینکه خروجی به شما نمایش داده میشود محتوای دستور به انتهای فایل out.txt اضافه میشود.
روش سوم
ما در روش دوم از استانداردهای stdout و stderr استفاده میکنیم. اما معنا و مفهوم این دو عبارت چیست؟
- stdout: به طور ساده stdout همان خروجی صحیح هر دستور بوده که در ترمینال لینوکس به شما نمایش داده میشود. از عدد ۰ بعنوان نماد این استاندارد استفاده میکنیم.
- stderr: استاندارد stderr در لینوکس نیز خطاهای نمایش داده شده در ترمینال به ازای دستوراتیست که شما وارد میکنید. از عدد ۱ بعنوان نماد این استاندارد استفاده میکنیم.
- stdin: استاندارد سومی نیز وجود دارد که ما به آن اشاره میکنیم و آن stdin یا همان ورودی هاییست که شما در ترمینال وارد کرده و یا به دستورات خود میدهید.
حال به مثال زیر دقت کنید. در این مثال چون خطایی چاپ نمیشود خروجی دستور در out.txt ذخیره شده و فایل error.txt ایجاد شده اما محتوای آن خالی میماند.
1 |
lsc@arshatech:$ ls 1> /tmp/out.txt 2>/tmp/error.txt |
حال اگر به صورت عمد دستور نادرستی در خط فرمان لینوکس وارد کنیم مقدار out.txt خالی و محتوای پیغام خطا در فایل error.txt ذخیره میشود.
1 |
lsc@arshatech:$ lss 1> /tmp/out.txt 2>/tmp/error.txt |
محتوای error.txt به صورت زیر خواهد بود:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
lsc@arshatech:/tmp/test$ cat /tmp/error.txt No command 'lss' found, did you mean: Command 'ls' from package 'coreutils' (main) Command 'lsh' from package 'lsh-client' (universe) Command 'gss' from package 'libgss-dev' (universe) Command 'ss' from package 'iproute2' (main) Command 'lrs' from package 'lrslib' (universe) Command 'les' from package 'atm-tools' (universe) Command 'ass' from package 'irpas' (multiverse) Command 'lvs' from package 'lvm2' (main) Command 'lssu' from package 'nilfs-tools' (universe) Command 'less' from package 'less' (main) Command 'lsw' from package 'suckless-tools' (universe) Command 'lsx' from package 'suckless-tools' (universe) lss: command not found |