سند اینجا(here document) خصیصهای از ترکیب دستوری(syntactic) پوسته بورن است، که تغذیه دادهها به برنامه را بدون ذخیره آنها در یک فایل خارجی میسر میسازد. این ویژگی به همان خوبی در پوستههای POSIX، Korn و Bash نیز کار میکند.
قالب اصلی عبارت است از:
someprogram <<WORD دادههای شما go hereWORD
در اینجا، someprogram میتواند هر برنامهای باشد که از ورودی استاندارد میخواند (رایجترین آنها cat است)، و WORD میتواند هر کلمه متمایز کنندهای که مایل هستید، باشد. (EOF یک انتخاب رایج است.)
سند اینجا(Here document)ها با این قالب خصوصیات ویژهای دارند:
جایگزینیهای پوسته( از قبیل $variable) در سند اینجا انجام میشوند.
اگر بخواهیم از جایگزینی پوسته اجتناب کنیم، میتوانیم کلمه متمایز کننده را نقلقولی نماییم:
someprogram <<'WORD ' دادههای شما $go `here`WORD
اگر میخواهیم قادر به ایجاد تورفتگی در سنداینجا باشیم، میتوانیم کاراکتر - (خط تیره) را پیشوند کلمه متمایزکننده نماییم:
if ... while .... someprogram <<-WORD this is an indented here documentWORD done fi
در این شکل تمام کاراکترهای tab پیشتاز (فاصلهها خیر!) حذف خواهند شد. هیچگونه مقرراتی برای حذف فاصلههای پیشتاز سطر یا فاصلهها و tabهای همراه هم از ابتدای سطر وجود ندارد. (محدودیتهای قواعد دستوری Makefileها را به خاطر بیاورید، مجاب خواهید شد.)
سنداینجا ها به طور نوعی هنگامی که برنامه فراخوانی میگردد، به وسیله ایجاد فایل موقتی و تغییر مسیر ورودی استاندارد به این فایل، پیادهسازی میشوند.
در bash، گونهای از سنداینجا به نام رشتهاینجا(here string) وجود دارد. این جمع و جور تر است، اما محدودتر نیز میباشد:
read -a octets <<< "$ipaddr"
عملگر <<< نقشی مشابه نقش << در سنداینجا دارد، اما کلمه نگهبان برای اینکه به ما بگوید، کجا ورودی تمام میشود، وجود ندارد. در عوض، عملگر <<< با یک کلمه منفرد دنبال میشود(نقلقول ها دوست شما هستند!). کلمه به اضافه سطر جدید، ورودی استاندارد فرمان میشود.
لولهها امکان ارتباط پردازشها با یکدیگر را فراهم میکنند. همچنین لوله ممکن است به عنوان FIFO (اختصاری برای First In- First Out) شناخته شود.
برتری آنها از کاربرد فایلها به عنوان وسیله ارتباط، آن است که با استفاده از لولهها، پردازشها با یکدیگر همگام میشوند: اگر پردازشی از یک لوله نخواند، پردازش نوشتن در لوله مسدود میشود، و اگر نویسنده وجود نداشته باشد، پردازش خواندن از لوله، مسدود میشود.
مثال زیر نمونهای از لوله نامگذاری شده است، در اینجا به عنوان pipe1 نامیده شده.
cd /tmp mkfifo pipe1
برای ارسال یک پیغام به لوله، از این استفاده کنید:
echo "hello" > pipe1
در این نقطه به نظر میرسد پردازش هنگ شده باشد. پردازش دیگری برای جمعآوری داده در حال اجرا نیست، بنابراین کرنل پردازش را به حالت تعلیق در میآورد. گفته میشود پردازش در این مرحله مسدود(blocked) گردیده است.
امکان دارد در ترمینال دیگری، اطلاعات از لوله جمع آوری گردد، به این شکل:
cat /tmp/pipe1
اکنون توسط cat اطلاعات از لوله خوانده خواهد شد( و در ترمینال نوشته میشود)، و پردازش نویسندهِ مسدودشده برای ادامه یافتن آزاد میشود.
برای برخی اطلاعات بیشتر، پرسش و پاسخ شماره ۸۵ را ببینید.
این مثال کوچکی از مخابره کردن یک پردازش سرویسدهنده با یک پردازش سرویسگیرنده است. سرویسدهنده فرمانها را به سرویسگیرنده ارسال میکند، و سرویس گیرنده هر فرمان را تصدیق میکند:
ادامه مطلبموقع تنظیم noclobber رونویسی محتویات یک فایل موجود توسط عملگر تغییر مسیر > غیرممکن خواهد شد. شاید در حالیکه قصد شما استفاده از عملگر تغییر مسیرِ >> باشد، > را برای تغییر مسیر خروجی یک فرمان به یک فایل موجود تایپ کرده باشید. اینجاست که noclobber به کار میآید، پیشگیری از حذف تصادفی محتوای یک فایل موجود.
ls > list
تنظیم noclobber را امتحان کنید
set -o noclobber
دوباره انجام بدهید
ls > list bash: list: cannot overwrite existing file
اگر تصمیم به رونویسی فایل گرفتهاید، میتوانید روش >| را به کار ببرید. از این قرار:
ls >| list
درست مانند برقرار کردن noclobber، غیرفعال کردن آن نیز میسر است، چنان که با کاربرد عملگر تغییر مسیر > رونویسی بتواند انجام گردد.
set +o noclobber
NoClobber (آخرین ویرایش 2012-09-27 12:53:11 توسط Valentin Bajrami)
nullglob یک گزینه پوسته Bash است که بسط glob را به گونهای اصلاح میکند تا الگوهایی که بر هیچ نام فایلی منطبق نمیگردند به جای بسط یافتن به خود آن الگوها، به صفر شناسه بسط داده شوند.
به طور عادی، وقتی یک glob که بر هیچ نام فایلی منطبق نمیشود، بسط داده میشود، بدون تغییر باقی میماند. بدین معنی که نتایجی مانند این به دست میآورید:
$ rm *.bak rm: cannot remove `*.bak': No such file or directory
جانشین غیر منطبق *.bak با هیچ چیزی تعویض نمیشود، به طور مستقیم به فرمان rm تحویل میگردد، همانطور که اگر نام یک فایل بود. پس فرمان rm سعی میکند آن را حذف کند، و شکست میخورد، با یک پیغام خطای معقول.
به هرحال، این موضوع در برنامهنویسی باعث برخی نتایج نامطلوب میگردد. یک آرایه مانند این را ملاحظه کنید:
# Bash در پوسته files=(*) echo "There are ${#files[*]} files here."
اگر هیچ فایلی با glob انطباق نیابد، این ناموفق است درحالیکه یک فایل گزارش خواهد نمود، به علت آنکه آرایه با یک عنصر منفرد * بارگیری میشود.
گزینه nullglob امکان اجتناب از این مشکل را برای ما فراهم میکند. اگر این گزینه تنظیم شود، جانشینِ منطبق نشده به جای اینکه به عنوان یک کلمه منفرد آنجا بماند، کاملاً کنار گذاشته میشود. -- با صفر کلمه جایگزین میشود-- .
# Bash در پوسته shopt -s nullglob files=(*) echo "There are ${#files[*]} files here."
گزینه nullglob به طور پیشفرض فعال نیست زیرا موقعیتهای دیگری موجود است، که در آنها این رفتارش میتواند بینهایت مبهوت کننده باشد. برای نمونه، اگر یک جانشین انطباق نیافته، از لیست شناسههای ls حذف گردد، به طور کاملاً غیر منتظرهای رفتار میکند:
shopt -s nullglob ls *.xyzqj # .در این حالت تمام فایلهای این دایرکتوری لیست خواهند شد # .بدون شناسه به کار برود ls درست مانند موقعی که دستور
ممکن است گزینه nullglob خودش برای تمام حالات کفایت نکند. به طور پیشفرض glob بر نام فایلهایی که نامشان با نقطه شروع میشود، منطبق نمیشود، مگر اینکه خود جانشین نیز با نقطه شروع شود. اگر این فایلها که فایلهای پنهان نیز شناخته میشوند، باید با جانشین مطابقت داده شوند، آنوقت ممکن است شخص مایل باشد از گزینه dotglob استفاده کند.
# Bash در پوسته shopt -s dotglob shopt -s nullglob files=(*) echo "There are ${#files[*]} files here."
فقط به خاطر داشته باشید که این گزینهها تا موقعی که غیر فعال نشدهاند، برای پردازش پوسته جاری مؤثر باقی میمانند.
ادامه مطلبیک توصیفگر فایل(FD) یک عدد است که به یک فایل باز اشاره میکند. هر پردازش مجموعه توصیفگرهای فایل اختصاصی خود را دارد، اما FDها از پردازش پدر به پردازشهای فرزند به ارث میرسند.
هر پردازشی سه FD را از پدرش به ارث خواهد برد: 0 (ورودی استاندارد)، باز برای خواندن، و 1 (خروجی استاندارد)، و 2 (خطای استاندارد) باز برای نوشتن. پردازشی که بدون یکی از اینها یا بیشر، شروع بشود ممکن است به طور غیر قابل پیشبینی رفتار کند. (بنابراین هرگز stderr را نبندید. به جای آن همیشه به /dev/null هدایت نمایید.)
امکان دارد پردازشها چنانکه لازم باشد (تا هر اندازهای که محدودیت آن را سیستم عامل تحمیل کند) توصیفگر فایل اضافه باز کنند. در اکثر زبانها، وقتی شما فایل جدیدی باز میکنید، شماره FD که سیستم عامل انتحاب میکند به شما مسترد میشود (یا یک کتابخانه شماره FD را مدیریت میکند و جزئیات را پنهان میسازد). اگر چه، در اسکریپتهای پوسته، الگو متفاوت است: شما اول شماره FD را انتخاب میکنید، و سپس فایل را برای استفاده از آن توصیفگر، باز میکنید. این یعنی شما به عنوان نویسنده اسکریپت، باید از آن FDهایی که در حال استفاده برای هر وظیفهای هستید، پیوسته آگاهی داشته باشید.
پوستهها برای کار با توصیفگرهایفایل از تغییر مسیر استفاده میکنند. برای FDهای از قبل موجود، با استفاده از ترکیب دوتایی کردن توصیفگرفایل، خروجی میتواند، به آنها ارسال گردد, یا ورودی میتواند از آنها خوانده شود:
echo "unexpected error: $foo" 1>&2 while read -r line 0<&3; do ...ادامه مطلب