پرسش و پاسخ شماره ۹۱ - آموزش اسکریپت نویسی
X
تبلیغات
رایتل

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

#!/bin/bash

پرسش و پاسخ شماره ۹۱

پرسش و پاسخ شماره ۹۱

من تلاش می‌کنم تعداد سطر و ستون ترمینال خود را دریافت کنم، اما متغیرهای COLUMNS و LINES همیشه تهی هستند

COLUMNS و LINES در وضعیت محاوره‌ای توسط BASH تنظیم می‌شوند، آنها به طور پیش‌فرض در یک اسکریپت در دسترس نیستند. در اکثر سیستم‌ها خودتان می‌توانید با ترمینال پرس و جو کنید:

unsup() { echo "Your system doesn't support retrieving $1 with tput.  Giving up." >&2; exit 1; }
COLUMNS=$(tput cols) || unsup cols
LINES=$(tput lines) || unsup lines

Bash به طور خودکار متغیرهای COLUMNS و LINES را موقعی که پوسته محاوره‌ای تغییر اندازه داده می‌شود، به هنگام می‌کند. اگر شما این متغیرها را در اسکریپت تنظیم می‌کنید و می‌خواهید موقعی که اندازه ترمینال تغییر می‌کند، آنها به هنگام شوند، یعنی به مجرد دریافت سیگنال SIGWINCH، می‌توانید خودتان یک trap تنظیم کنید:

trap 'COLUMNS=$(tput cols) LINES=$(tput lines)' WINCH

همچنین می‌توانید در سرآیند اسکریپت، پوسته را به عنوان محاوره‌ای تنظیم کنید:

#!/bin/bash -i
echo $COLUMNS

به هر حال، این مورد دارای اشکالاتی هست:

  • بررسی بواسطه گزینه ‎-i‎ به منظور تعیین آنکه آیا پوسته محاوره‌ای است، و سپس انصراف یا درست رفتار نکردن، برای اسکریپت‌ها خیلی غیر معمول نیست، اگرچه بهترین کار نمی‌باشد. هیچ روش کاملاً خالی از نقصی برای بررسی این مطلب، وجود ندارد، بنابراین بعضی از اسکریپت‌ها ممکن است به سبب آن ناموفق شوند.

  • اجرا با گزینه ‎-i‎ فایل ‎.bashrc‎ را منبع می‌کند، و گزینه‌های مختلفی از قبیل ‎job-control‎ را تنظیم می‌کند که شاید آثار جانبی ناخواسته داشته باشند.

اگر چه از لحاظ تکنیکی می‌توانید ‎-i‎ را در میان اسکریپت تنظیم کنید، اما تأثیری بر تنظیم COLUMNS و LINES ندارد -- ‎-i‎ باید ابتدا، موقعی که Bash احضار می‌شود برقرار باشد.

معمولاً Bash موقعی که ترمینال شما سیگنال SIGWINCH نشان دهنده تغییر اندازه را ارسال می‌کند،COLUMNS و LINES را به روز رسانی می‌کند. برخی ترمینالها ممکن است این کار را انجام ندهند، بنابراین اگر متغیرهای شما حتی موقعی که یک پوسته محاوره‌ای در حال اجرا است به روز رسانی نمی‌شوند، استفاده از ‎shopt -s checkwinsize‎ را امتحان کنید. این دستور باعث استعلام ترمینال توسط Bash پس از هر فرمان می‌شود، بنابراین تنها در صورتی که واقعاً لازم است از آن استفاده کنید.

البته، tput به ترمینال نیاز دارد. مطابق POSIX، اگر خروجی استاندارد tty نباشد، نتایج تعیین شده نیستند، و stdin استفاده نمی‌شود، اگر چه بعضی پیاده‌سازی‌ها ممکن است سعی کنند به هرحال از آن استفاده کنند. در لینوکس OpenBSD و Gentoo (و ظاهراً حداقل برخی لینوکس‌های دیگر)، دست کم یکی از stdout یا stderr باید tty باشد، وگرنه tput فقط بعضی مقادیر پیش‌فرض را برمی‌گرداند.

linux$ tput -S <<<$'cols\nlines' 2>&1 | cat
80
24

openbsd$ tput cols lines 2>&1 | cat
80
24


پرسش و پاسخ 91 (آخرین ویرایش ‎2013-01-11 22:11:44‎ توسط GreyCat)