برنامهها در خط فرمان لینوکس عموما خروجی خود را به خروجی استاندارد ارسال میکنند. اما گاهی اوقات برخی از برنامهنویسان ترجیح میدهند خروجی برنامه را به جای خروجی استاندارد به TTY ارسال کنند. اگر برنامه نویس خروجی را به TTY ارسال کند خروجی برنامه را نمیتوان به دستور بعدی ارسال کرد (PIPE) و یا خروجی برنامه را نمیتوان در فایل ریخت.
اسکریپت CXS که یک آنتی شل است خروجی خود را به TTY ارسال میکند در نتیجه خروجی این اسکریپت را نمیتوان با ارسال به فایل یا PIPE کردن خروجی به برنامههای دیگر پردازش کرد.
نمونه خروجی این برنامه را در زیر ببینید.
# cxs -U cxs is already at the latest version: v6.29 cxs daily fingerprint database up to date
در مثال بالا دستور CXS را با پارامتر U اجرا میکنیم تا اسکریپت به آخرین نسخه آپدیت شود. همانطور که مشاهده میکنید اسکریپت خروجی خود را در ترمینال چاپ میکند اما این خروجی به خروجی استاندارد و یا standard output ارسال نشده است. اجازه بدهید دستور را مجددا اجرا کنیم و این بار خروجی را در فایل بریزیم. همانطور که مشاهده میکنید با اینکه خروجی را در فایل ریخته ایم اما خروجی در فایل ذخیره نشده است.
# cxs -U > out.txt # cat out.txt #
اگر خروجی دستور را به دستوری مانند grep نیز ارسال کنیم (PIPE کنیم) مجددا مشاهده میکنید که هیچ خروجی نمایش داده نمیشود و در حقیقت اسکریپت CXS خروجی را به دستور بعدی یعنی grep ارسال نمیکند.
# cxs -U | grep already
اما چگونه باید خروجی برنامههایی که خروجی را به TTY ارسال میکنند را پردازش کنیم؟ برای پردازش خروجی چند راه حل داریم.
روش اول: باید پارامترهای برنامه را بررسی کنیم. برخی برنامهها گزینهای دارند که اجازه میدهند خروجی را ذخیره کنیم و یا خروجی را به خروجی استاندارد ارسال کنیم. در مورد اسکریپت CXS گزینهای به نام pipe وجود داشته است که خروجی را به خروجی استاندارد ارسال میکرده که متاسفانه در نسخههای تازه این گزینه حذف شده است. اما همچنان از گزینه script میتوان استفاده کرد.
روش دوم: در این روش باید برای برنامه یک wrapper بنویسیم و به جای descriptor یک و دو که خروجی خطا است به فایل معرفی کنیم. برای انجام این کار میتوان از زبانهایی مانند C و یا پایتون استفاده کرد. و روال کلی کار به این شکل است که قبل از اجرا (fork) کردن دستور در برنامه TTY را نیز fork میکنیم که در نتیجه نسخه خودمان از TTY را خواهیم داشت. در نتیجه وقتی دستور را اجرا میکنیم میتواننم از TTY فورک شده خودمان خروجی را بخوانیم و این خروجی را به خروجی استاندارد ارسال کنیم.
این یک نمونه ساده از کد پایتونی است که این پیاده سازی را انجام میدهد.
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 استفاده میکنیم.
# 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 اختصاصی نیز وجود دارد که پیچیدگی زیادی دارد.
1 دیدگاه. دیدگاه تازه ای بنویسید
لطفا مورد چهارم را هم توضیح دهید