انتقال ورودی‌ها و خروجی‌ها در لینوکس

لوله‌کشی به ‌شیوه منبع‌باز

یکی از ویژگی‌های جدید Bash نگارش4 نسبت به ویژگی‌های قبلی آن، دستور coproc است. دستور coproc برای ایجاد یک فرایند همزمان به‌کار می‌رود که به پوسته سازنده آن با دو خط لوله (Pipe) متصل است:
کد خبر: ۳۴۵۴۷۷

یکی برای ارسال ورودی و دیگری برای ارسال خروجی. نخستین کاربردی که برای این دستور می‌توان پیدا کرد عملیات گزارش‌گیری است. فرض کنیم می‌خواهیم خروجی تمام دستورها را در یک فایل گزارش بگیریم. مشکل اصلی این حالت این است که شاید یک اسکریپت خروجی خاص خودش را داشته باشد و مثلا آن‌را در یک فایل قرار دهد. برای این حالت، باید حتما خروجی دستور را به‌صورت دستی تغییر دهیم که از نظر کاربری ساده‌تر مناسب نیست.

یک روش این است که از لوله‌های نامدار استفاده کنیم. دستور زیر را ببینید:‌

#!/bin/bash

echo hello

if test -t 1; then

# Stdout is a terminal.

exec »log

else

# Stdout is not a terminal.

npipe=/tmp/$$.tmp

trap "rm -f $npipe" EXIT

mknod $npipe p

tee «$npipe log &

exec 1»&-

exec 1»$npipe

fi

echo goodbye

در این دستور stdout به ترمینال متصل نیست. بنابراین ما یک لوله نامدار ( لوله‌ای که در سیستم فایل موجود است ) را با کمک دستور mknod ایجاد می‌کنیم و بعد از اتمام اجرای دستور، تله‌ای طراحی می‌کنیم که این لوله را حذف کند. سپس به سراغ پس‌زمینه رفته و هرچه قرار است گزارش داده شود را در فایل گزارش‌گیری می‌نویسیم. به ‌یاد داشته باشید که در این فایل گزارش‌گیری هر چیزی که در ورودی یا خروجی نوشته شود جزو گزارش محسوب می‌شود. همچنین به ‌یاد داشته باشید که خروجی این گزارش‌گیری همانند خروجی دستور خواهد بود. بنابراین خروجی حاصل شده از stdout موجود در اسکریپت درست معادل همان چیزی است که stdout برنامه اصلی خواهد بود. بنابراین در این قسمت می‌توانیم خروجی‌ها را یکسان کنیم. حالا همین کار را هم می‌توان با پردازش‌های همزمان انجام داد. مثال زیر را ببینید:‌

echo hello

if test -t 1; then

# Stdout is a terminal.

exec »log

else

# Stdout is not a terminal.

exec 7»&1

coproc tee log 1»&7

#echo Stdout of coproc: ${COPROC[0]} »&2

#echo Stdin of coproc: ${COPROC[1]} »&2

#ls -la /proc/$$/fd

exec 7»&-

exec 7»&${COPROC[1]}-

exec 1»&7-

eval "exec ${COPROC[0]}»&-"

#ls -la /proc/$$/fd

fi

echo goodbye

echo error »&2

در این مثال خروجی استاندارد ما در ترمینال به ‌چاپ می‌رسد و می‌توانیم از دستور exec برای انتقال خروجی به فایل مناسب استفاده کنیم. اگر خروجی ما به ترمینال نمی‌رفت باید از coproc استفاده می‌کردیم تا tee را به‌عنوان یک فرایند همزمان اجرا کرده و خروجی را به ورودی tee بدهد و سپس خروجی tee را به‌جایی که می‌خواهیم بفرستیم ببرد.

اجرای اسکریپت tee با استفاده از دستور coproc همانند اجرای tee در پس‌زمینه است با این تفاوت که bash این‌بار اسکریپت tee را اجرا می‌کند ولی هم ورودی و هم خروجی را به لوله‌هایی که ساختیم منتقل می‌کند. از نظر فنی Bash توضیح‌دهنده‌های فایل لوله‌ها را در آرایه‌ای به‌‌نام COPROC قرار می‌دهد. بنابراین:

آرایهCOPROC[0] توضیح‌دهنده فایل برای لوله‌ای است که به خروجی استاندارد یک فرایند همزمان متصل شده است.

آرایهCOPROC[1] به ورودی فرایند همزمان متصل شده است. توجه داشته باشید که لوله‌ها قبل از هرگونه انتقال ورودی یا خروجی تولید شده باشند. همچنین بهتر است به‌ بخشی توجه کنید که خروجی اسکریپت به ترمینال منتقل نمی‌شود. در این حالت خط پایین خروجی استاندارد ما را برای توضیح‌ دهنده فایل 7 کپی می‌کند.

exec 7»&1

بعد از این کار، اسکریپت tee را برای انتقال خروجی به توضیح ‌دهنده فایل7 اجرا می‌کنیم.

coproc tee log 1»&7

به این ترتیب اسکریپت tee هر چه در ورودی استاندارد نوشته شود را در فایلی به‌نام log ذخیره خواهد کرد. در انتها نیز توضیح ‌دهنده فایل7 را با دستور زیر حذف می‌کنیم:

exec 7»&-

از آنجا که 7 را بستیم، می‌توانیم دوباره از آن استفاده کنیم. بنابراین لوله‌ای که به ورودی7 متصل شده است را به‌صورت زیر منتقل می‌کنیم:

exec 7»&${COPROC[1]}-

حالا خروجی استاندارد خود را به لوله‌ای منتقل می‌کنیم که به ورودی استاندارد tee متصل شده است.

exec 1»&7-

سپس لوله‌ای که به خروجی tee متصل شده است را با دستور زیر می‌بندیم:

eval "exec ${COPROC[0]}»&-"

دستور eval در اینجا لازم است، در غیر این صورت BASH می‌اندیشد که مقدار ${COPROC[0]} یک دستور است. البته به‌صورت خاص و در این دستور، این کار ضروری نیست چون Bash می‌تواند متوجه شود که 7 شروع توضیح ‌دهنده فایل است و دستور نیست. همچنین دستور زیر را ببینید:

#ls -la /proc/$$/fd

این دستور برای دیدن فایل‌های بازی که توسط فرایند فعلی باز هستند به کار می‌رود. حالا می‌توان نتیجه دلخواه را دریافت کرد: خروجی استاندارد به اسکریپت tee می‌رود، سپس عملیات گزارش‌گیری انجام می‌شود و به مسیر خود باز می‌گردد و خروجی مشخص نرم‌افزار یا اسکریپت چاپ می‌شود.

محمدرضا قربانی

newsQrCode
ارسال نظرات در انتظار بررسی: ۰ انتشار یافته: ۰

نیازمندی ها