در برنامه خود از رشتههای escape رنگ ANSI استفاده نکنید! فرمان tput محاوره با بانک اطلاعاتی ترمینال به روشی معقول، را برای شما میسر میسازد:
# Bourne tput setaf 1; echo this is red tput setaf 2; echo this is green tput bold; echo "boldface (and still green)" tput sgr0; echo back to normal
کاربران Cygwin: شما برای به دست آوردن tput نیاز به نصب بسته ncurses دارید( Where did "tput" go in 1.7? را ببینید).
tput بانک اطلاعاتی terminfo را میخواند که شامل تمام کُدهای escape لازم برای محاوره با ترمینال شما میباشد. این کدها در متغیر $TERM تعیین شدهاند. برای اطلاعات تفصیلی صفحه man terminfo(5) را بخوانید.
دستور tput sgr0 رنگها را دوباره به مقادیر پیش فرض تنظیم میکند. این دستور همچنین حالت حروف ضخیم (tput bold)، underline، و غیره را غیر فعال میکند.
اگر رنگهای تفننی برای اعلان فرمان خود میخواهید، استفاده از مورد قابل مدیریت را در نظر بگیرید:
# Bash red=$(tput setaf 1) green=$(tput setaf 2) blue=$(tput setaf 4) reset=$(tput sgr0) PS1='\[$red\]\u\[$reset\]@\[$green\]\h\[$reset\]:\[$blue\]\w\[$reset\]\$ '
توجه نمایید که ما از رشتههای escape رنگ ANSI استفاده نکردیم. به جای آن ذخیره خروجی فرمان tput در متغیرها را به کار بردیم، که بعداً هنگامی که $PS1 بسط داده میشود، به کار میروند. ذخیره کمیتها به معنای آنست که در هر نوبت نمایش اعلان، چندین انشعاب پردازش tput نداریم، tput فقط چهار بار در حین شروع اولیه پوسته فراخوانی میشود. علائم \[ و \] اجازه میدهند bash بفهمد کدام قسمتهای اعلان موجب حرکت نشانگر نشوند، بدون آنها سطرها به طور نادرست شکسته خواهند شد.
همچنین برای یک مرور اجمالی http://wiki.bash-hackers.org/scripting/terminalcodes ببینید.
در ادامه دامنه وسیعتری از رشته متغیرهای ترمینال آمده است. هر کدام را که میخواهید برگزینید:
# .متغیرها برای درخواستهای ترمینال [[ -t 2 ]] && { alt=$( tput smcup || tput ti ) # Start alt display ealt=$( tput rmcup || tput te ) # End alt display hide=$( tput civis || tput vi ) # Hide cursor show=$( tput cnorm || tput ve ) # Show cursor save=$( tput sc ) # Save cursor load=$( tput rc ) # Load cursor bold=$( tput bold || tput md ) # Start bold stout=$( tput smso || tput so ) # Start stand-out estout=$( tput rmso || tput se ) # End stand-out under=$( tput smul || tput us ) # Start underline eunder=$( tput rmul || tput ue ) # End underline reset=$( tput sgr0 || tput me ) # Reset cursor blink=$( tput blink || tput mb ) # Start blinking italic=$( tput sitm || tput ZH ) # Start italic eitalic=$( tput ritm || tput ZR ) # End italic [[ $TERM != *-m ]] && { red=$( tput setaf 1|| tput AF 1 ) green=$( tput setaf 2|| tput AF 2 ) yellow=$( tput setaf 3|| tput AF 3 ) blue=$( tput setaf 4|| tput AF 4 ) magenta=$( tput setaf 5|| tput AF 5 ) cyan=$( tput setaf 6|| tput AF 6 ) } white=$( tput setaf 7|| tput AF 7 ) default=$( tput op ) eed=$( tput ed || tput cd ) # Erase to end of display eel=$( tput el || tput ce ) # Erase to end of line ebl=$( tput el1 || tput cb ) # Erase to beginning of line ewl=$eel$ebl # Erase whole line draw=$( tput -S <<< ' enacs smacs acsc rmacs' || { \ tput eA; tput as; tput ac; tput ae; } ) # Drawing characters back=$'\b' } 2>/dev/null ||:
در بالا موقعی که stderr به ترمینال متصل نباشد، متغیرهای تنظیم نشده رها میشوند و متغیر های رنگ تنظیم نشده برای ترمینالهای تک رنگ چشمپوشی میشوند. اجراهای جایگزین tput به کد اجازه میدهند روی سیستمهایی که در آنها tput به جای نامهای ANSI مربوطه، نامهای قدیمی termcap را میپذیرد، کار را ادامه دهد. این کد همچنین از 2>/dev/null ||: برای خاموش کردن خطاهای بالقوه و پرهیز از عدم پیشروی اسکریپت در اثر خطا، استفاده میکند. این مورد اجازه میدهد این کد در گسترهای از وضعیتها از قبیل آن اسکریپتها که set -e را به کار میبرند و ترمینالها یا سیستم عاملهایی که از رشتههای معینی پشتیبانی میکنند، قابل استفاده باشد(کد از http://to.lhunath.com/bashlib اقتباس گردیده است).
این مطلب بحثانگیز خواهد بود، اما من موافقت نمیکنم و پیشنهاد میکنم از کدهای escape در ANSI به صورت hard-codedزیرنویس1 استفاده کنید به دلیل آنکه در دنیای واقعی بانکهای اطلاعاتی مربوط به ترمینالها بیشتر اوقات ناقص میباشند.
tput setaf به طور لفظی به معنای «قرار دادن ANSI در پیش زمینه» است و نباید هیچ تفاوتی با رشته escapeهای ANSI به صورت hard-coded داشته باشد، غیر ازآنکه با بانکهای اطلاعاتی ناقص terminfo کار خواهد کرد، بنابراین رنگها در یک VT با نوع ترمینال linux-16color یا هر نوع ترمینال به شرطی که واقعاً ترمینالی با توانایی نمایش شانزده رنگ ANSI باشد، به طور صحیح دیده خواهند شد.
بنابراین تنظیم آن متغیرها به رشتههای ANSI به صورت hard-coded را در نظر بگیرید.همچون:
# Bash white=$'\e[0;37m'
شما فرض میکنید تمام ترمینالهای جهان که شما در هر صورت استفاده خواهید نمود همواره با یک مجموعه منفرد رشتههای escape مطابقت میکنند. این یک فرض بسیار ضعیف است. شاید پیری خود را نمایش میدهم، اما در اولین شغل خود بعد از دانشگاه، در سال 1993-1994، با طیف متنوع گستردهای از ترمینالهای فیزیکی کار کردم (IBM 3151, Wyse 30, NCR or other, etc.) همه در همان محل کار. تمام آنها طرح کلیدهای متفاوت، رشتههای escape متفاوت داشتند. اگر من رشتههای escape یک ترمینال را به طوری که شما پیشنهاد میکنید به صورت hard-code استفاده میکردم، فقط در یکی از آن ترمینالها کار میکرد، و سپس اگر من از اداره دیگری یا از کنسول سرویسدهنده لاگین میکردم، سردرگم میشدم. بنابراین، اگر برای استفاده شخصی، این کار شما را خوشحال میکند، من نمیتوانم جلوی شما را بگیرم. اما اندیشه نوشتن اسکریپتی که از رشتههای escape به طور hard-coded استفاده کند و سپس توزیع آن برای دیگران باید به فوریت دور انداخته شود. - GreyCat
من گفتم این بحثانگیز خواهد شد، اما دیدگاه جایگزینی وجود دارد. امروزه بسیاری افراد در هر طرف از لینوکس در سرویسدهندههای خود یا میزکارهایشان با پروفایلهای خود، استفاده میکنند. بانک اطلاعاتی ترمینال برای لینوکس ۱۶ رنگ نابسامان است. با انجام این کار به آن روش «درست»
-- GreyCat
پرسش و پاسخ 37 (آخرین ویرایش 2012-10-25 17:54:48 توسط Lhunath)