در این پست میخواهیم به روش استفاده از استریمها، پایپها و ریدایرکتها و استفاده از پیغام های استاندارد ارور و مدیریت وردی ها و خروجی ها در دستورات لینوکس بپردازیم.
همانطور که در پست های قبل توضیح دادیم لینوکس سه حالت دارد:
- stdin: منظور از آن Standard input یا ورودی استاندارد می باشد که در فایل تشریحی مقدار ۰ به آن تخصیص می یابد که به آن STDIN نیز گفته میشود. هر سیستم یونیکس یا لینوکس مقدار پیش فرض ورودی را از STDIN میخواند.
- stdout: منظور از آن Standard Output یا خروجی استاندارد می باشد که در فایل تشریحی مقدار ۱ به آن تخصیص می یاید که به آن STDOUT نیز گقته میشود. هر سیستم یونیکس یا لینوکس مقدار پیشفرض خروجی استاندارد را در STDOUT می نویسد.
- stderr: منظور از آن Standard Error یا خطای استاندارد می باشد که در فایل تشریحی مقدار ۲ به آن تخصیص می یابد که به آن STDERR نیز گفته میشود. هر سیستم یونیکس یا لینوکس پیام پیشفرش خطا را در STDERR می نویسد.
برای مثال ما در یک مسیر چند دارکتوری داریم:
$ ls
fiona habib mahmoodrm minoo mojtaba sina
حالا خروجی دستور زیر که به ما میگه چیزی با j پیدا نکرده یک Standard Error است:
$ ls j*
ls: cannot access j*: No such file or directory
ولی خروجی دستور زیر که تمام m ها را پیدا کرده است یک Standard Output است:
$ ls m*
mahmoodrm minoo mojtaba
همچنین در صورتی که این دو را با هم اجرا کنید شما هم Standard Output دارید و هم Standard Error:
$ ls m*
mahmoodrm minoo mojtaba
با استفاده از < می توانید خروجی یک دستور را به دستور دیگر بدهید، در مثال زیر ما خروجی دستور ls را که Standard Output آن 1 است را در فایلی به اسم output و Standard Error آن که عدد 2 است را به فایلی به اسم errors می ریزیم:
$ ls j* m* > output 2> errors
نکته: همانطور که در اول هم گفتیم عدد Standard input صفر است، Standard Output عدد یک و Standard Error نیز عدد دو می باشد.
در نهایت خروجی دو فایل ساخته شده به صورت زیر است:
$ cat output
mahmoodrm
minoo
mojtaba
$ cat errors
ls: cannot access j*: No such file or directory
دو نکته مهم
- اگر شما به صورت <n استفاده کنید (یعنی یکی از <) فایل شما overwritten میشه یعنی اگر در مثال بالا دوباره ما دستور رو اجرا کنیم تمام محتوای قبلی پاک میشه و محتوای جدید جای آن قرار می گیرد.
- اگر شما به صورت <<n استفاده کنید (یعنی دوتا <<) محتوای جدید append میشه به محتوای قدیمی، یعنی محتوای قدیمی باقی می ماند و محتوای جدید به خط آخر آن اضافه می شود.
<& و <<& یعنی هم Standard Output و هم Standard Error
0& و 1& و 2& یعنی بریز همجا که الان داره استاندارد ریخته میشه، برای مثال وقتی شما دارید خروجی یه دستور رو داخل یک فایل میریزید برای خروجی دوم لازم نیست همان مسیر رو بدید فقط کافی از یکی از این ها استفاده کنید.
ls > file1 2>&1 خروجی ls میره داخل file1 و خروجی ارور (2) هم میره داخل file1
ارسال به null
یک دیوایسی در لینوکس داریم به نام null یا عملا هیچی! کار این قسمت این که شما هرچی بریزید داخلش ازبین میره!! حالا کاربردش چیه؟ فکر کنید یک برنامه دارید که کلی خروجی به شما میده ولی شما فقط خروجی ارور برنامه را می خواهید ببینید، پس شما می توانید خروجی استاندارد برنامه خود را داخل null بریزید و فقط خروجی ارور برای شما نمایش داده شود:
$ ls -R / x* > /dev/null
و یا در مثال زیر ما تمام خروجی های ارور را ریختیم دور:
$ ls j* m* > file1
ls: cannot access j*: No such file or directory
$ ls j* m* > file1 2>/dev/null
$ cat file1
mahmoodrm
minoo
mojtaba
هدایت ورودی
شما در لینوکس می تونید حتی وردی را هم مدیریت کنید، برای مثال ما یک فایل متنی داریم به شکل زیر:
$ cat uses
you fedora
jadi ubuntu
rubic windows
neda mac
narsin arch
با دستور tr تمام space ها رو به , (کاما) تغییر می دهیم و می گوییم ورودی را از فایل user بگیر:
$ tr ' ' ',' < uses
you,fedora
jadi,ubuntu
rubic,windows
neda,mac
narsin,arch
اگر میخواهیم ورودی را از کیبورد وارد کنید می توانید از دوتا >> استفاده کنید:
$ tr ' ' '.' << END_OF_DATA
> this is a line
> and then this
>
> we'll still type
> and,
> done!
> END_OF_DATA
this.is.a.line
and.then.this
we'll.still.type
and,
done!
در مثال بالا ما از دستور tr استفاده کردیم تا تمام spase ها رو به نقطه تغییر دهد و بعد از >> یک عبارت یونیک و خاص می نویسیم که در هیچ جای ورودی که میخوایم وارد کنیم نباشه، حال ما میتوانیم هر تعداد وردی بهش بدیم تا زمانی که اون عبارت یونیک و خاصی که در اینجا END_OF_DATA نوشتیم را بنویسیم.
پایپ Pipe ( | ) در لینوکس
پایپ کردن در لینوکس را می توان یکی از کاربردی ترین کار ها دانست. توسط پایپ کردن دو یا چند دستور در محیط لینوکسی خود قادر خواهید بود خروجی های مرتبی دریافت کنید و کار های مفید زیادی با سیستم لینوکسی خود انجام دهید.
حتما تا به حال برای شما پیش آمده است که تصمیم داشته اید دستوری اجرا کنید و خروجی آن دستور را به عنوان ورودی، به دستور دیگری بدهید.
$ cat what_i_have.txt
laptop
socks
tshirt
ball
socks
glasses
$ cut -f1 -d' ' what_i_have.txt | sort | uniq -c | sort -nr
2 socks
1 tshirt
1 laptop
1 glasses
1 ball
استفاده از دستور xargs برای اجرای دستورات
xargs جریان داده ها را از ورودی استاندارد می خواند، سپس خطوط فرمان را تولید و اجرا می کند، عملا هر چیزی که دریافت کند میزارد جلوی دستور بعدی:
$ cat what_i_have.txt
laptop
socks
tshirt
ball
socks
glasses
$ cat what_i_have.txt | xargs -I DATA echo I have DATA and I love it.
I have laptop and I love it.
I have socks and I love it.
I have tshirt and I love it.
I have ball and I love it.
I have socks and I love it.
I have glasses and I love it.
استفاده از دستور tee برای اجرای دستورات
tee خواندن از ورودی استاندارد و به طور همزمان به خروجی استاندارد و یک یا چند فایل می نویسد. این بیشتر از یک فرمان redirection است، در دستور زیر بعد از ls دستور tee محتوای ls را در دو فایل llfiles myfiles مینویسد و سپس بر روی صفجه نیز نمایش می دهد:
$ ls -1 | tee allfiles myfiles
allfiles
f
fiona
habib
mahmoodrm
minoo
mojtaba
myfiles
sina