برنامهها در خط فرمان لینوکس عموما خروجی خود را به خروجی استاندارد ارسال میکنند. اما گاهی اوقات برخی از برنامهنویسان ترجیح میدهند خروجی برنامه را به جای خروجی استاندارد به TTY ارسال کنند.
اگر برنامه نویس خروجی را به TTY ارسال کند خروجی برنامه را نمیتوان به دستور بعدی ارسال کرد (PIPE) و یا خروجی برنامه را نمیتوان در فایل ریخت.
اسکریپت CXS که یک آنتی شل است خروجی خود را به TTY ارسال میکند در نتیجه خروجی این اسکریپت را نمیتوان با ارسال به فایل یا PIPE کردن خروجی به برنامههای دیگر پردازش کرد.
نمونه خروجی این برنامه را در زیر ببینید.
1
2
3
|
# cxs -U
cxs is already at the latest version: v6.29
cxs daily fingerprint database up to date
|
در مثال بالا دستور CXS را با پارامتر U اجرا میکنیم تا اسکریپت به آخرین نسخه آپدیت شود. همانطور که مشاهده میکنید اسکریپت خروجی خود را در ترمینال چاپ میکند اما این خروجی به خروجی استاندارد و یا standard output ارسال نشده است. اجازه بدهید دستور را مجددا اجرا کنیم و این بار خروجی را در فایل بریزیم. همانطور که مشاهده میکنید با اینکه خروجی را در فایل ریخته ایم اما خروجی در فایل ذخیره نشده است.
1
2
3
|
# cxs -U > out.txt
# cat out.txt
#
|
اگر خروجی دستور را به دستوری مانند grep نیز ارسال کنیم (PIPE کنیم) مجددا مشاهده میکنید که هیچ خروجی نمایش داده نمیشود و در حقیقت اسکریپت CXS خروجی را به دستور بعدی یعنی grep ارسال نمیکند.
1
|
# cxs -U | grep already
|
اما چگونه باید خروجی برنامههایی که خروجی را به TTY ارسال میکنند را پردازش کنیم؟ برای پردازش خروجی چند راه حل داریم.
روش اول: باید پارامترهای برنامه را بررسی کنیم. برخی برنامهها گزینهای دارند که اجازه میدهند خروجی را ذخیره کنیم و یا خروجی را به خروجی استاندارد ارسال کنیم. در مورد اسکریپت CXS گزینهای به نام pipe وجود داشته است که خروجی را به خروجی استاندارد ارسال میکرده که متاسفانه در نسخههای تازه این گزینه حذف شده است. اما همچنان از گزینه script میتوان استفاده کرد.
روش دوم: در این روش باید برای برنامه یک wrapper بنویسیم و به جای descriptor یک و دو که خروجی خطا است به فایل معرفی کنیم. برای انجام این کار میتوان از زبانهایی مانند C و یا پایتون استفاده کرد. و روال کلی کار به این شکل است که قبل از اجرا (fork) کردن دستور در برنامه TTY را نیز fork میکنیم که در نتیجه نسخه خودمان از TTY را خواهیم داشت. در نتیجه وقتی دستور را اجرا میکنیم میتواننم از TTY فورک شده خودمان خروجی را بخوانیم و این خروجی را به خروجی استاندارد ارسال کنیم.
این یک نمونه ساده از کد پایتونی است که این پیاده سازی را انجام میدهد.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import pty
import os
def updateCXS():
pid, fd = pty.fork()
out = “”
if pid == 0:
os.execv(‘/usr/sbin/cxs’, [‘cxsname’ , ‘-U’])
else:
while True:
try:
out+=str(os.read(fd,65536),)
except OSError:
break
return out
print(updateCXS())
|
روش سوم: در این روش که نوعی پیاده سازی دیگر از روش بالاست از دستوراتی مانند SCRIPT استفاده میکنیم.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# script -c “cxs -U” out.txt
Script started, file is out.txt
cxs is already at the latest version: v6.29
cxs daily fingerprint database up to date
Script done, file is out.txt
# cat out.txt
Script started on Thu 09 Feb 2017 11:18:33 AM IRST
cxs is already at the latest version: v6.29
cxs daily fingerprint database up to date
Script done on Thu 09 Feb 2017 11:18:34 AM IRST
# script -c “cxs -U” | grep latest
cxs is already at the latest version: v6.29
|
روش چهارم: روشهای دیگری مانند ایجاد TTY اختصاصی نیز وجود دارد که پیچیدگی زیادی دارد.
بن مایه: https://blog.iranserver.com