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

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

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

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

منظقه

locale

منطقه

1. کد گذاری‌های کاراکتری

در عمل کامپیوترها نمی‌توانند کاراکترها و علائم را ذخیره کنند، آنها فقط اعداد را ذخیره می‌کنند. روشهای بیشماری برای نمایش دادن کاراکترهای زبان انسانی( مانند حرف A، علامت به اضافه، وغیره ) به عنوان عدد، وجود دارد، و این امر که روشهای متفاوت بسیار زیادی، واقعاً به کار برده شد، به بی‌نظمی منجر گردیده است.

کامپیوترهای اولیه (حداقل در ایالات متحده) در دو استاندارد برای طرح‌ریزی(نگاشت) کاراکترهای ‎ US English‎ به اعداد و بالعکس، به یکدیگر نزدیک شدند: ASCII و EBCDIC. دومی به تدریج تا اواخر قرن بیستم منسوخ گردید و ASCII ( کد استاندارد امریکایی برای تبادل اطلاعات) را به عنوان استاندارد اصلی باقی گذاشت.

مشکل با ASCII آن است که برای زبانهای غیر از انگلیسی، یا حتی برای برخی کلمات انگیسیِ وابسته به مزیت‌های انشایی نویسنده، یا شاید نوشته شده با آوا نماها (به عنوان مثال rôle و naïve) خیلی محدود است. ASCII تنها بیست و شش حرف از الفبای انگلیسی (بزرگ و کوچک)، ارقام 0 تا 9، و مقداری نشانه‌گذاری اصلی را پوشش می‌دهد -- به طور معمول آنهایی که شما در صفحه کلید US کامپیوتر می‌بینید. در ماشین‌های یونیکسی برای دیدن فهرست آنها می‌توانید ‎man ascii‎ را تایپ کنید.

اکثر کامپیوترها از یک بایت هشت بیتی به عنوان واحد ذخیره‌شان (یعنی یک دامنه از 0 تا 255 هنگامی که مانند اعداد صحیح غیر منفی بیان می‌شوند) استفاده می‌کنند. ASCII فقط کاراکترهای هفت بیتی (0 تا 127) تعریف می‌کند، یک میرات روزهایی که ارتباطات راه دور داده‌ها به طور قابل ملاحظه‌ای آهسته و بیشتر مستعد خطا بود. چون ASCII تنها نصف محدوده یک بایت را استفاده می‌کند، این مطلب فضایی را برای افراد باقی گذاشت که مجموعه‌های کاراکتری خودشان را داخل یک بایت منفرد تعریف کنند.

(بسیاری از کاربران ‎DOS/Windows‎ مایکروسافت باور دارند که ASCII تمام دامنه 0 تا 255 را با صورتک‌های خندان و کاراکترهای ترسیم خطوط و مانند آن پوشش می‌دهد. این تصور نادرست است. مجموعه کاراکتر معروف DOS در حقیقت ‎IBM code page 437‎ است، که یکی از چندین فوق‌مجموعه ASCII می‌باشد. ASCII خودش منحصر به 127 کاراکتر است.)

کاربران کامپیوتر در کشورهای خارج از US با استفاده از ASCII قادر به نمایش زبانهای نوشتاری خود نبودند، بنابراین در حالیکه برنامه‌نویسان US از فضای 128 تا 255 برای ایجاد کاراکترهای ترسیمی و نمادهای ریاضی استفاده می‌کردند، اروپایی‌ها آنها را برای افزودن حروف اضافی‌شان و حروف دارای تکیه صدا به کار می‌بردند. این مطلب بواسطه مجموعه دیگری از استانداردهای رشد یافته یعنی ISO 8859 به بی‌نظمی بیشتر (نه به طور تعجب‌آور) منجر گردید. توجه نمایید که اینها فوق‌مجموعه‌های ASCII می‌باشند. استاندارد ‎ISO-8859-1‎ که به عنوان Latin-1 نیز شناخته می‌شود، استاندارد مسلط برای ایستگاههای کاری یونیکس در امریکای شمالی و غرب اروپا شد.

به هر حال، این نیز برخی موضوعات را حل نشده باقی گذاشت. نخست آنکه بازهم رقابت استانداردها وجود داشت، اروپای شرقی دارای الفبای بسیار متفاوت با اروپای غربی است، و استانداردهای متنوع ‎ISO 8859‎ نیز با هم ناسازگار هستند. دوم، کشورهای آسیایی در مقایسه با کشورهای امریکایی-اروپایی دارای روشهای به طور ریشه‌ای متفاوتی در نوشتن می‌باشند، و حتی مجموعه کاراکترهای آنها با فضای یک بایت منفرد (که تنها 256 علامت مختلف را مجاز می‌کند) مطابقت ندارد.

استاندارد Unicode تلاش دارد این مطلب را هدف‌گیری نماید: به جای تعریف فقط 256 علامت، هزارها نشانه تعریف می‌کند. اگر یک کامپیوتر باید هر علامت سندی را که از مجموعه کدهای یونیکد استفاده نموده، نمایش بدهد، به سه بایت برای هر علامت نیاز دارد، این مطلب فضای مورد نیاز برای اسناد انگلیسی ساده را نسبت به آنچه قبلاً استفاده می‌شد، سه برابر می‌سازد، که قسمت اعظم آن فضا با صفرها اشغال می‌شود.

بنابراین، به منظور تلاش برای حفظ برخی اثربخشی‌ها (و همچنین بعضی سازگاری‌ها با فایلهای داده‌ای موجود)، کدگذاری‌های متنوعی از کاراکترهای یونیکد ایجاد گردید، در حال حاضر محبوب‌ترینِ اینها (حداقل در میان انگلیسی زبانان) UTF-8 می‌باشد، که یک کدگذاری با پهنای متغییر است. یک سند اسکی(ASCII) ساده، همچنین یک سند UTF-8 معتبر نیز هست، کاراکترهای یک بایتی اسکی در UTF-8 با استفاده از همان یک بایت نمایش داده می‌شوند. به هرحال، UTF-8 رشته‌های چندبایتی قادر به نمایش تمام کاراکترهای یونیکد را ارائه می‌کند (در برخی حالت‌ها تا استفاده از چهار بایت برای هر کاراکتر).

از سال 2009، UTF-8 استاندارد نمایان برای توزیع‌های لینوکس است، هرچند که بازهم مشکلات زیادی با پیاده‌سازی‌ها وجود دارد.

2. مناطق

بنابراین، «منطقه»(locale) چیست؟ چون این‌همه استانداردهای غیر معمول، و انواع مختلف کامپیوتر اینقدر زیاد وجود دارد، که برخی از آنها فقط از بعضی استانداردها پشتیبانی می‌کنند، اهمیت دارد که قادر باشیم بگوییم که شما در حال کار با کدام استاندارد هستید. این جایی است که مناطق از آن ناشی می‌شوند.

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

مثالها: یک امریکایی ممکن است «روز سوم ژانویه سال 2009 میلادی» را به صورت ‎1/3/09‎ بنویسد، در حالیکه یک شخص انگلیسی ممکن است همان تاریخ را به صورت ‎3/1/09‎ بنویسد. یک برنامه‌نویس کامپیوتر احتمالاً ‎2009-01-03‎ را به کار خواهد برد. در ضمن دوست امریکایی ما عدد «ده هزار و یکصدم» را به شکل ‎10,000.01‎ می‌نویسد، بسیار آزار دهنده برای همکار آلمانی‌اش که به جای آن به صورت ‎10000,01‎ می‌نویسد.

یک سیستم یونیکس دارای فرمانی به نام locale می‌باشد که برای نشان دادن منطقه‌ای که یک کاربر(یا به طور دقیق‌تر، یک فرایند) در لحظه مشغول استفاده از آن است، و لیست کردن تمام مناطق به کار می‌رود. برای مثال

imadev:~$ locale
LANG=en_US.iso88591
LC_CTYPE="en_US.iso88591"
LC_COLLATE="en_US.iso88591"
LC_MONETARY="en_US.iso88591"
LC_NUMERIC="en_US.iso88591"
LC_TIME=POSIX
LC_MESSAGES="en_US.iso88591"
LC_ALL=

این دستور منطقه‌ای را که در حال حاضر مورد استفاده است نشان می‌دهد. برای دیدن آنهایی که به جای آن می‌توانند انتخاب بشوند:

imadev:~$ locale -a
C
POSIX
C.iso88591
C.utf8
univ.utf8
ar_DZ.arabic8
ar_SA.arabic8
ar_SA.iso88596
bg_BG.iso88595
cs_CZ.iso88592
da_DK.iso88591
da_DK.roman8
nl_NL.iso88591
nl_NL.roman8
en_GB.iso88591
en_GB.roman8
en_US.iso88591
en_US.roman8
fi_FI.iso88591
fi_FI.roman8
fr_CA.iso88591
fr_CA.roman8
fr_FR.iso88591
fr_FR.roman8
de_DE.iso88591
de_DE.roman8
el_GR.greek8
el_GR.iso88597
iw_IL.hebrew8
iw_IL.iso88598
hu_HU.iso88592
is_IS.iso88591
is_IS.roman8
it_IT.iso88591
it_IT.roman8
no_NO.iso88591
no_NO.roman8
pl_PL.iso88592
pt_PT.iso88591
pt_PT.roman8
ro_RO.iso88592
ru_RU.iso88595
hr_HR.iso88592
sk_SK.iso88592
sl_SI.iso88592
es_ES.iso88591
es_ES.roman8
sv_SE.iso88591
sv_SE.roman8
th_TH.tis620
tr_TR.iso88599
tr_TR.turkish8
C.iso885915
da_DK.iso885915@euro
de_DE.iso885915@euro
en_GB.iso885915@euro
es_ES.iso885915@euro
fi_FI.iso885915@euro
fr_CA.iso885915
fr_FR.iso885915@euro
is_IS.iso885915@euro
it_IT.iso885915@euro
nl_NL.iso885915@euro
no_NO.iso885915@euro
pt_PT.iso885915@euro
sv_SE.iso885915@euro
zh_CN.hp15CN
zh_TW.eucTW

در این مرحله، خواننده باید درک کند که چرا بخش نخست این صفحه به مجموعه کدگذاری‌های کاراکتر اختصاص یافته بود. بدون فهم آنکه ‎"iso885915"‎ به چه معنا می‌باشد، این لیست تا اندازه‌ای مرموز می‌بود.

یک نام منطقه دارای سه جزء سازنده است. بخش اول که دو حرف کوچک می‌باشد، زبانی را که استفاده می‌شود، نشان می‌دهد. برای مثال en به معنی انگلیسی و es اسپانیولی، de آلمانی است و به همین منوال، با استفاده از دو حرف کدهای کشوری که گویش اصلی هر زبان از آن ناشی گردیده است.

بخش دوم (پس از خط زیر) کشور واقعی که کاربر در آن است(یاآنکه کاربر می‌خواهد قواعد منطقه آن را به اجرا درآورد)، و اساساً برای گویش‌های متفاوت یک زبان به کار می‌رود. en_US و en_GB دارای چند تفاوت در املای واژه‌ها، علائم پول رایج مختلف، و مانند آن می‌باشند.

جزء سازنده سوم(بعد از نقطه) کدگذاری کاراکتر است. توجه نمایید که املای نام کدگذاری در میان سیستم‌ها کاملاً استاندارد شده نمی‌باشد. iso885915 املای معمولی برای یک کدگذاری ‎ISO-8859-15‎ می‌باشد، اماسیستم‌های دیگر ممکن است(برای مثال) به ISO8859-15 نیاز داشته باشند. شما باید از دستور ‎locale -a‎ برای دیدن آنچه در سیستم شما معتبر است و چطور نوشته می‌شود، استفاده نمایید.

نام‌های خاص C و POSIX برای این مطلب یک استثنا هستند. آنها در هرجایی لازم می‌شوند و مترادف هستند، آنها(به طور اساسی) به معنی «اسکی، انگلیسی US بدون اِعمال هیچ قاعده خاص» می‌باشند. خروجی تحت این منطقه به طور عادی با استانداردهای ISO و RFC برای تاریخ، زمان و غیره مطابقت دارد، جداکننده هزارها را کاملاً حذف می‌کند، از کدگذاری ASCII واقعی کمیت‌ها برای مرتب‌سازی کاراکترها و مانند آن، استفاده می‌کند(به طور کلی با پیش فرض قرار دادن «قواعد محاسبه قراردادی US»).

شما منطقه‌ای را که می‌خواهید استفاده کنید به وسیله تنظیم متغیرهای محیط تعیین می‌کنید. (برای بحث در باره اینکه چگونه و کجا متغیرهای محیط جهت نشست‌های محاوره‌ای خود را تنظیم کنید، صفحه DotFiles را ببینید.) متغیرهای متنوع ‎LC_*‎ اگر تنظیم شوند، قواعد ویژه‌ای جهت پیروی تعریف می‌کنند، متغیر LANG ذخیره‌ای برای هر کدام از متغیرهای ‎LC_*‎ که تنظیم نشوند تعریف می‌کند. در اکثر حالت‌های رایج، شما تنها LANG را تنظیم خواهید نمود.

برای به دست آوردن تنظیماتی که در مثال سیستم خود دیدیم، می‌توانستیم از موردی مانند این استفاده کنیم:

imadev:~$ cat .profile
...
LANG=en_US.iso88591; LC_TIME=POSIX
export LANG LC_TIME
...

(توجه: فایل ‎.profile‎ تنها برای برخی از انواع لاگین‌ها درست است. در صورتیکه نمی‌دانید به ویرایش یا ایجاد کدام فایل نیاز دارید صفحه DotFiles را ببینید.)

این مثال قواعد «US English، با کدگذاری ISO-8859-1» را برای اکثر موارد، اما قواعد POSIX را به منظور نمایش تاریخ و زمان به ما ارائه می‌کند.

چون اینها متغیرهای محیط هستند، می‌توانیم بررسی کنیم که وقتی مواردی را تغییر می‌دهیم چه اتفاقی رخ می‌دهد.

imadev:~$ LC_TIME=POSIX date
Thu Apr 16 10:32:03 EDT 2009
imadev:~$ LC_TIME=en_US.iso88591 date
Thu, Apr 16, 2009 10:32:13 AM

برای دانستن جزئیات آنچه سیستم شما با مناطق انجام می‌دهد، لازم است مستندات سیستم خودتان (چنین مواردی بسیار زیاد در معرض برداشت پیاده‌سازی کنندگان می‌باشد) را بررسی کنید. سیستم‌های دبیان دارای ‎locale(7)‎ (برای خواندن آن ‎man 7 locale‎ را تایپ کنید)، و HP-UX دارای ‎lang(5)‎ می‌باشند و به همین ترتیب.

وقتی تعیین کرده‌اید که می‌خواهید جلسه کاری‌تان چطور کار کند و لازم است متغیرها را در کدام محل قرار بدهید، اقلام را درست همانطور که ترجیح می‌دهید تنظیم کنید.

3. نوشتن برنامه‌های آگاه از منطقه

موقع نوشتن برنامه‌ها -- مخصوصاً اسکریپت‌های پوسته، اما این مطلب به همان اندازه برای سایر اشکال برنامه‌نویسی هم صدق می‌کند -- شخص باید از امکان بالقوه رفتار متفاوت سیستم مقصد نسبت به منطقه انتخابی، آگاه باشد.

قبلاً دیده‌ایم که در یک سیستم، خروجی فرمان date چگونه در واکنش به مناطق، با جابجایی فیلدها، درج کاراکترهای کامای اضافی، و زمان سنج 12 ساعتی به جای 24 ساعتی، تغییر می‌کند. (مورد شما ممکن است تا آن اندازه اساسی نباشد، یا حتی می‌تواند ریشه‌ای‌تر باشد.) پیغام‌ خطاهای برنامه‌های دیگر یا کتابخانه‌های سیستم می‌توانند به سایر زبانها ترجمه شوند.

اگر شما به این استناد می‌کنید که خروجی برنامه یا کتابخانه فراخوانده، در یک قالب استاندارد باشد، باید برای قسمت‌هایی که نیاز به سازگاری دارند، متغیرهای محیط منطقه را با تنظیم منطقه به C، باطل کنید. متغیر LC_ALL دارای اولویتی برتر از متغیرهای جداگانه ‎LC_*‎ می‌باشد، که اینها نیز دارای تقدم بالاتر از متغیر LANG هستند. به این ترتیب، شما می‌توانید در نقاط حساس با تحمیل ‎LC_ALL=C‎ ، رفتار مورد انتظارتان را به دست آورید.

مثال:

imadev:~$ echo Hello World | tr A-Z a-z
hÉMMÓ wÓSMÐ
imadev:~$ echo Hello World | LC_ALL=C tr A-Z a-z
hello world

(این مورد همواره یکی از مثالهای مطلوب من است.)

فرمان‌های بسیاری برای تعویض رفتارهای قراردادی، روشهای منطقه-مراقب، ارائه می‌نمایند. به عنوان مثال، tr دارای ‎[:upper:]‎ برای جانشینی ‎A-Z‎ می‌باشد، و نظایر آن. اینها در جایی که در دسترس هستند باید ترجیح داده شوند. در نظر بگیرید که ‎[:upper:]‎می‌تواند مواردی مانند Á را شامل گردد که در ‎A-Z‎ منطقه C نخواهد بود. اما در نهایت، شما به عنوان برنامه‌نویس، مسئولیت انتخاب آنچه را برای پروژه شما مناسب‌ترین است به عهده دارید.

رفتار globها نیز منطقه-مرتبط می‌باشد، متغیر ‎LC_COLLATE‎ ترتیبی را تعیین می‌کند که نامها براساس آن مرتب می‌شوند. فرمان ls نیز خروجی‌اش را به طور پیش‌فرض با استفاده از همان ترتیب وابسته به منطقه مرتب می‌کند. متأسفانه، روش‌های استانداردی برای آموختن آنکه داخل یک منطقه مفروض کدام ترتیب به کار می‌رود، وجود ندارد. شخص باید به قدرت زبان بسته شگردها متوسل گردد. برای نمونه:

imadev:/tmp/greg$ for i in {1..255}; do eval touch \$\'\\x$(printf %02x $i)\'; done
touch: cannot change times on /
imadev:/tmp/greg$ ls -b
   8  Ä  C  É  G  Î  M  Ò  P  t  ü  ý  {  -  ;  ¶  ¥  _  \002  \014  \026  \200  \212  \224  \236
   9  ä  c  é  g  î  m  ò  p  U  V  ÿ  }  ×  :  §  ¤  ­­­   \003  \015  \027  \201  \213  \225  \237
0  A  Å  Ç  È  H  Ï  N  Ô  Q  u  v  Z  «  ÷  "  @  µ  ª  \004  \016  \030  \202  \214  \226  \177
1  a  å  ç  è  h  ï  n  ô  q  Ú  W  z  »  ±  ¿  &  ^  º  \005  \017  \031  \203  \215  \227
2  Á  Ã  D  Ê  I  J  Ñ  Ö  R  ú  w  Þ  <  ¬  ?  °  ~  ¹  \006  \020  \032  \204  \216  \230
3  á  ã  d  ê  i  j  ñ  ö  r  Ù  X  þ  >  ¼  ¡  %  ´  ²  \007  \021  \033  \205  \217  \231
4  À  Æ  Ð  Ë  Í  K  O  Õ  S  ù  x  (  `  ½  !  #  ¨  ³  \010  \022  \034  \206  \220  \232
5  à  æ  ð  ë  í  k  o  õ  s  Û  Y  )  '  ¾  \  $  ¸  ©  \011  \023  \035  \207  \221  \233
6  Â  B  E  F  Ì  L  Ó  Ø  ß  û  y  [  =  *  |  ¢  ·  ®  \012  \024  \036  \210  \222  \234
7  â  b  e  f  ì  l  ó  ø  T  Ü  Ý  ]  +  ,  ¦  £  ¯  \001  \013  \025  \037  \211  \223  \235

این کد کاراکتر / را از قلم می‌اندازد چون ما نمی‌توانیم فایلی با آن نام ایجاد نماییم، اما ترتیب تمام کاراکترهای دیگر درپیاده‌سازی ‎HP-UX 10.20‎ از ‎en_US.iso88591‎ را نشان می‌دهد. به استثنای یک مورد که من نمی‌توانم آن را در محیط متنی این صفحه وب درج کنم (در محل خالی سمت چپ ‎\003‎). البته، در یک کدگذاری چند بایتی مانند ‎UTF-8‎ ممکن است قدری آشفتگی در آماده سازی مشاهده شود. (احتمالاً بهتر است به صورت قطعه قطعه بررسی گردد.)

چون مرتب‌سازی از منطقه تأثیر می‌پذیرد، در صورتیکه مرتب‌سازی سنتی برحسب ASCII را لازم داشته باشید، می‌توانید ابطال LC_COLLATE را در نظر بگیرید، اما به طور کلی تا آنجا که ممکن است باید به انتخاب منطقه کاربر احترام بگذارید.


CategoryUnix

  • منطقه (آخرین ویرایش ‎2011-05-06 15:26:52‎ توسط 149)

locale

منطقه

1. کد گذاری‌های کاراکتری

در عمل کامپیوترها نمی‌توانند کاراکترها و علائم را ذخیره کنند، آنها فقط اعداد را ذخیره می‌کنند. روشهای بیشماری برای نمایش دادن کاراکترهای زبان انسانی( مانند حرف A، علامت به اضافه، وغیره ) به عنوان عدد، وجود دارد، و این امر که روشهای متفاوت بسیار زیادی، واقعاً به کار برده شد، به بی‌نظمی منجر گردیده است.

کامپیوترهای اولیه (حداقل در ایالات متحده) در دو استاندارد برای طرح‌ریزی(نگاشت) کاراکترهای ‎ US English‎ به اعداد و بالعکس، به یکدیگر نزدیک شدند: ASCII و EBCDIC. دومی به تدریج تا اواخر قرن بیستم منسوخ گردید و ASCII ( کد استاندارد امریکایی برای تبادل اطلاعات) را به عنوان استاندارد اصلی باقی گذاشت.

مشکل با ASCII آن است که برای زبانهای غیر از انگلیسی، یا حتی برای برخی کلمات انگیسیِ وابسته به مزیت‌های انشایی نویسنده، یا شاید نوشته شده با آوا نماها (به عنوان مثال rôle و naïve) خیلی محدود است. ASCII تنها بیست و شش حرف از الفبای انگلیسی (بزرگ و کوچک)، ارقام 0 تا 9، و مقداری نشانه‌گذاری اصلی را پوشش می‌دهد -- به طور معمول آنهایی که شما در صفحه کلید US کامپیوتر می‌بینید. در ماشین‌های یونیکسی برای دیدن فهرست آنها می‌توانید ‎man ascii‎ را تایپ کنید.

اکثر کامپیوترها از یک بایت هشت بیتی به عنوان واحد ذخیره‌شان (یعنی یک دامنه از 0 تا 255 هنگامی که مانند اعداد صحیح غیر منفی بیان می‌شوند) استفاده می‌کنند. ASCII فقط کاراکترهای هفت بیتی (0 تا 127) تعریف می‌کند، یک میرات روزهایی که ارتباطات راه دور داده‌ها به طور قابل ملاحظه‌ای آهسته و بیشتر مستعد خطا بود. چون ASCII تنها نصف محدوده یک بایت را استفاده می‌کند، این مطلب فضایی را برای افراد باقی گذاشت که مجموعه‌های کاراکتری خودشان را داخل یک بایت منفرد تعریف کنند.

(بسیاری از کاربران ‎DOS/Windows‎ مایکروسافت باور دارند که ASCII تمام دامنه 0 تا 255 را با صورتک‌های خندان و کاراکترهای ترسیم خطوط و مانند آن را پوشش می‌دهد. این تصور نادرست است. مجموعه کاراکتر معروف DOS در حقیقت ‎IBM code page 437‎ است، که یکی از چندین فوق‌مجموعه ASCII می‌باشد. ASCII خودش منحصر به 127 کاراکتر است.)

کاربران کامپیوتر در کشورهای خارج از US با استفاده از ASCII قادر به نمایش زبانهای نوشتاری خود نبودند، بنابراین در حالیکه برنامه‌نویسان US از فضای 128 تا 255 برای ایجاد کاراکترهای ترسیمی و نمادهای ریاضی استفاده می‌کردند، اروپایی‌ها آنها را برای افزودن حروف اضافی‌شان و حروف دارای تکیه صدا به کار می‌بردند. این مطلب بواسطه مجموعه دیگری از استانداردهای رشد یافته یعنی ISO 8859 به بی‌نظمی بیشتر (نه به طور تعجب‌آور) منجر گردید. توجه نمایید که اینها فوق‌مجموعه‌های ASCII می‌باشند. استاندارد ‎ISO-8859-1‎ که به عنوان Latin-1 نیز شناخته می‌شود، استاندارد مسلط برای ایستگاههای کاری یونیکس در امریکای شمالی و غرب اروپا شد.

به هر حال، این نیز برخی موضوعات را حل نشده باقی گذاشت. نخست آنکه بازهم رقابت استانداردها وجود داشت، اروپای شرقی دارای الفبای بسیار متفاوت با اروپای غربی است، و استانداردهای متنوع ‎ISO 8859‎ نیز با هم ناسازگار هستند. دوم، کشورهای آسیایی در مقایسه با کشورهای امریکایی-اروپایی دارای روشهای به طور ریشه‌ای متفاوتی در نوشتن می‌باشند، و حتی مجموعه کاراکترهای آنها با فضای یک بایت منفرد (که تنها 256 علامت مختلف را مجاز می‌کند) مطابقت ندارد.

استاندارد Unicode تلاش دارد این مطلب را هدف‌گیری نماید: به جای تعریف فقط 256 علامت، هزارها نشانه تعریف می‌کند. اگر یک کامپیوتر باید هر علامت سندی را که از مجموعه کدهای یونیکد استفاده نموده، نمایش بدهد، به سه بایت برای هر علامت نیاز دارد، این مطلب فضای مورد نیاز برای اسناد انگلیسی ساده را نسبت به آنچه قبلاً استفاده می‌شد، سه برابر می‌سازد، که قسمت اعظم آن فضا با صفرها اشغال می‌شود.

بنابراین، به منظور تلاش برای حفظ برخی اثربخشی‌ها (و همچنین بعضی سازگاری‌ها با فایلهای داده‌ای موجود)، کدگذاری‌های متنوعی از کاراکترهای یونیکد ایجاد گردید، در حال حاضر محبوب‌ترینِ اینها (حداقل در میان انگلیسی زبانان) UTF-8 می‌باشد، که یک کدگذاری با پهنای متغییر است. یک سند اسکی(ASCII) ساده، همچنین یک سند UTF-8 معتبر نیز هست، کاراکترهای یک بایتی اسکی در UTF-8 با استفاده از همان یک بایت نمایش داده می‌شوند. به هرحال، UTF-8 رشته‌های چندبایتی قادر به نمایش تمام کاراکترهای یونیکد را ارائه می‌کند (در برخی حالت‌ها تا استفاده از چهار بایت برای هر کاراکتر).

از سال 2009، UTF-8 استاندارد نمایان برای توزیع‌های لینوکس است، هرچند که بازهم مشکلات زیادی با پیاده‌سازی‌ها وجود دارد.

2. مناطق

بنابراین، «منطقه»(locale) چیست؟ چون این‌همه استانداردهای غیر معمول، و انواع مختلف کامپیوتر اینقدر زیاد وجود دارد، که برخی از آنها فقط از بعضی استانداردها پشتیبانی می‌کنند، اهمیت دارد که قادر باشیم بگوییم که شما در حال کار با کدام استاندارد هستید. این جایی است که مناطق از آن ناشی می‌شوند.

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

مثالها: یک امریکایی ممکن است «روز سوم ژانویه سال 2009 میلادی» را به صورت ‎1/3/09‎ بنویسد، در حالیکه یک شخص انگلیسی ممکن است همان تاریخ را به صورت ‎3/1/09‎ بنویسد. یک برنامه‌نویس کامپیوتر احتمالاً ‎2009-01-03‎ را به کار خواهد برد. در ضمن دوست امریکایی ما عدد «ده هزار و یکصدم» را به شکل ‎10,000.01‎ می‌نویسد، بسیار آزار دهنده برای همکار آلمانی‌اش که به جای آن به صورت ‎10000,01‎ می‌نویسد.

یک سیستم یونیکس دارای فرمانی به نام locale می‌باشد که برای نشان دادن منطقه‌ای که یک کاربر(یا به طور دقیق‌تر، یک فرایند) در لحظه مشغول استفاده از آن است، و لیست کردن تمام مناطق به کار می‌رود. برای مثال

imadev:~$ locale
LANG=en_US.iso88591
LC_CTYPE="en_US.iso88591"
LC_COLLATE="en_US.iso88591"
LC_MONETARY="en_US.iso88591"
LC_NUMERIC="en_US.iso88591"
LC_TIME=POSIX
LC_MESSAGES="en_US.iso88591"
LC_ALL=

این دستور منطقه‌ای را که در حال حاضر مورد استفاده است نشان می‌دهد. برای دیدن آنهایی که به جای آن می‌توانند انتخاب بشوند:

imadev:~$ locale -a
C
POSIX
C.iso88591
C.utf8
univ.utf8
ar_DZ.arabic8
ar_SA.arabic8
ar_SA.iso88596
bg_BG.iso88595
cs_CZ.iso88592
da_DK.iso88591
da_DK.roman8
nl_NL.iso88591
nl_NL.roman8
en_GB.iso88591
en_GB.roman8
en_US.iso88591
en_US.roman8
fi_FI.iso88591
fi_FI.roman8
fr_CA.iso88591
fr_CA.roman8
fr_FR.iso88591
fr_FR.roman8
de_DE.iso88591
de_DE.roman8
el_GR.greek8
el_GR.iso88597
iw_IL.hebrew8
iw_IL.iso88598
hu_HU.iso88592
is_IS.iso88591
is_IS.roman8
it_IT.iso88591
it_IT.roman8
no_NO.iso88591
no_NO.roman8
pl_PL.iso88592
pt_PT.iso88591
pt_PT.roman8
ro_RO.iso88592
ru_RU.iso88595
hr_HR.iso88592
sk_SK.iso88592
sl_SI.iso88592
es_ES.iso88591
es_ES.roman8
sv_SE.iso88591
sv_SE.roman8
th_TH.tis620
tr_TR.iso88599
tr_TR.turkish8
C.iso885915
da_DK.iso885915@euro
de_DE.iso885915@euro
en_GB.iso885915@euro
es_ES.iso885915@euro
fi_FI.iso885915@euro
fr_CA.iso885915
fr_FR.iso885915@euro
is_IS.iso885915@euro
it_IT.iso885915@euro
nl_NL.iso885915@euro
no_NO.iso885915@euro
pt_PT.iso885915@euro
sv_SE.iso885915@euro
zh_CN.hp15CN
zh_TW.eucTW

در این مرحله، خواننده باید درک کند که چرا بخش نخست این صفحه به مجموعه کدگذاری‌های کاراکتر اختصاص یافته بود. بدون فهم آنکه ‎"iso885915"‎ به چه معنا می‌باشد، این لیست تا اندازه‌ای مرموز می‌بود.

یک نام منطقه دارای سه جزء سازنده است. بخش اول که دو حرف کوچک می‌باشد، زبانی را که استفاده می‌شود، نشان می‌دهد. برای مثال en به معنی انگلیسی و es اسپانیولی، de آلمانی است و به همین منوال، با استفاده از دو حرف کدهای کشوری که گویش اصلی هر زبان از آن ناشی گردیده است.

بخش دوم (پس از خط زیر) کشور واقعی که کاربر در آن است(یاآنکه کاربر می‌خواهد قواعد منطقه آن را به اجرا درآورد)، و اساساً برای گویش‌های متفاوت یک زبان به کار می‌رود. en_US و en_GB دارای چند تفاوت در املای واژه‌ها، علائم پول رایج مختلف، و مانند آن می‌باشند.

جزء سازنده سوم(بعد از نقطه) کدگذاری کاراکتر است. توجه نمایید که املای نام کدگذاری در میان سیستم‌ها کاملاً استاندارد شده نمی‌باشد. iso885915 املای معمولی برای یک کدگذاری ‎ISO-8859-15‎ می‌باشد، اماسیستم‌های دیگر ممکن است(برای مثال) به ISO8859-15 نیاز داشته باشند. شما باید از دستور ‎locale -a‎ برای دیدن آنچه در سیستم شما معتبر است و چطور نوشته می‌شود، استفاده نمایید.

نام‌های خاص C و POSIX برای این مطلب یک استثنا هستند. آنها در هرجایی لازم می‌شوند و مترادف هستند، آنها(به طور اساسی) به معنی «اسکی، انگلیسی US بدون اِعمال هیچ قاعده خاص» می‌باشند. خروجی تحت این منطقه به طور عادی با استانداردهای ISO و RFC برای تاریخ، زمان و غیره مطابقت دارد، جداکننده هزارها را کاملاً حذف می‌کند، از کدگذاری ASCII واقعی کمیت‌ها برای مرتب‌سازی کاراکترها و مانند آن، استفاده می‌کند(به طور کلی با پیش فرض قرار دادن «قواعد محاسبه قراردادی US»).

شما منطقه‌ای را که می‌خواهید استفاده کنید به وسیله تنظیم متغیرهای محیط تعیین می‌کنید. (برای بحث در باره اینکه چگونه و کجا متغیرهای محیط جهت نشست‌های محاوره‌ای خود را تنظیم کنید، صفحه DotFiles را ببینید.) متغیرهای متنوع ‎LC_*‎ اگر تنظیم شوند، قواعد ویژه‌ای جهت پیروی تعریف می‌کنند، متغیر LANG ذخیره‌ای برای هر کدام از متغیرهای ‎LC_*‎ که تنظیم نشوند تعریف می‌کند. در اکثر حالت‌های رایج، شما تنها LANG را تنظیم خواهید نمود.

برای به دست آوردن تنظیماتی که در مثال سیستم خود دیدیم، می‌توانستیم از موردی مانند این استفاده کنیم:

imadev:~$ cat .profile
...
LANG=en_US.iso88591; LC_TIME=POSIX
export LANG LC_TIME
...

(توجه: فایل ‎.profile‎ تنها برای برخی از انواع لاگین‌ها درست است. در صورتیکه نمی‌دانید به ویرایش یا ایجاد کدام فایل نیاز دارید صفحه DotFiles را ببینید.)

این مثال قواعد «US English، با کدگذاری ISO-8859-1» را برای اکثر موارد، اما قواعد POSIX را به منظور نمایش تاریخ و زمان به ما ارائه می‌کند.

چون اینها درست متغیرهای محیط می‌باشند، می‌توانیم کاوش کنیم که وقتی موارد را تغییر می‌دهیم چه اتفاقی رخ می‌دهد.

imadev:~$ LC_TIME=POSIX date
Thu Apr 16 10:32:03 EDT 2009
imadev:~$ LC_TIME=en_US.iso88591 date
Thu, Apr 16, 2009 10:32:13 AM

برای جزئیات آنچه سیستم شما با مناطق انجام می‌دهد، نیاز دارید مستندات سیستم خودتان (چنین مواردی بسیار زیاد در معرض برداشت پیاده‌سازی کنندگان می‌باشد) را بررسی کنید. سیستم‌های دبیان دارای ‎locale(7)‎ (برای خواندن آن ‎man 7 locale‎ را تایپ کنید)، و HP-UX دارای ‎lang(5)‎ می‌باشند و به همین ترتیب.

وقتی تعیین کرده‌اید که می‌خواهید جلسه کاری‌تان چطور کار کند و لازم است متغیرها را در کدام محل قرار بدهید، اقلام را درست همانطور که ترجیح می‌دهید تنظیم کنید.

3. نوشتن برنامه‌های آگاه از منطقه

موقع نوشتن برنامه‌ها -- مخصوصاً اسکریپت‌های پوسته، اما این مطلب به همان اندازه برای سایر اشکال برنامه‌نویسی هم صدق می‌کند -- شخص باید از امکان بالقوه رفتار متفاوت سیستم مقصد نسبت به منطقه انتخابی، آگاه باشد.

قبلاً دیده‌ایم که در یک سیستم، خروجی فرمان date چگونه در واکنش به مناطق، با جابجایی فیلدها، درج کاراکترهای کامای اضافی، و زمان سنج 12 ساعتی به جای 24 ساعتی، تغییر می‌کند. (مورد شما ممکن است تا آن اندازه اساسی نباشد، یا حتی می‌تواند ریشه‌ای‌تر باشد.) پیغام‌ خطاهای برنامه‌های دیگر یا کتابخانه‌های سیستم می‌توانند به سایر زبانها ترجمه شوند.

در صورتیکه شما به به این استناد می‌کنید که خروجی برنامه یا کتابخانه مخاطب قرار گرفته در یک قالب استاندارد باشد، باید برای قسمت‌هایی که نیاز به سازگاری دارند، متغیرهای محیط منطقه را با تنظیم منطقه به C، باطل کنید. متغیر LC_ALL دارای اولویتی برتر از متغیرهای جداگانه ‎LC_*‎ می‌باشد، که اینها نیز دارای تقدم بالاتر از متغیر LANG می‌باشند. به این ترتیب، شما می‌توانید در نقاط حساس با تحمیل ‎LC_ALL=C‎ ، رفتار مورد انتظارتان را به دست آورید.

مثال:

imadev:~$ echo Hello World | tr A-Z a-z
hÉMMÓ wÓSMÐ
imadev:~$ echo Hello World | LC_ALL=C tr A-Z a-z
hello world

(این مورد همواره یکی از مثالهای مطلوب من است.)

فرمان‌های بسیاری برای تعویض رفتارهای قراردادی، روشهای منطقه-مراقب، ارائه می‌نمایند. به عنوان مثال، tr دارای ‎[:upper:]‎ برای جانشینی ‎A-Z‎ می‌باشد، و نظایر آن. اینها در جایی که در دسترس هستند باید ترجیح داده شوند. در نظر بگیرید که ‎[:upper:]‎ ممکن است مواردی مانند Á را که در ‎A-Z‎ منطقه C نخواهد بود را شامل گردد. اما در نهایت، شما به عنوان برنامه‌نویس، مسئولیت انتخاب آنچه برای پروژه شما مناسب‌ترین است را به عهده دارید.

رفتار globها نیز منطقه-مرتبط می‌باشد، متغیر ‎LC_COLLATE‎ ترتیبی را تعیین می‌کند که نامها براساس آن مرتب می‌شوند. فرمان ls نیز خروجی‌اش را به طور پیش‌فرض با استفاده از همان ترتیب منطقه-مرتبط مرتب می‌کند. متأسفانه، روش‌های استانداردی برای آموختن آنکه داخل یک منطقه مفروض کدام ترتیب به کار می‌رود، وجود ندارد. شخص باید به قدرت زبان بسته شگردها متوسل گردد. برای نمونه:

imadev:/tmp/greg$ for i in {1..255}; do eval touch \$\'\\x$(printf %02x $i)\'; done
touch: cannot change times on /
imadev:/tmp/greg$ ls -b
   8  Ä  C  É  G  Î  M  Ò  P  t  ü  ý  {  -  ;  ¶  ¥  _  \002  \014  \026  \200  \212  \224  \236
   9  ä  c  é  g  î  m  ò  p  U  V  ÿ  }  ×  :  §  ¤  ­­­   \003  \015  \027  \201  \213  \225  \237
0  A  Å  Ç  È  H  Ï  N  Ô  Q  u  v  Z  «  ÷  "  @  µ  ª  \004  \016  \030  \202  \214  \226  \177
1  a  å  ç  è  h  ï  n  ô  q  Ú  W  z  »  ±  ¿  &  ^  º  \005  \017  \031  \203  \215  \227
2  Á  Ã  D  Ê  I  J  Ñ  Ö  R  ú  w  Þ  <  ¬  ?  °  ~  ¹  \006  \020  \032  \204  \216  \230
3  á  ã  d  ê  i  j  ñ  ö  r  Ù  X  þ  >  ¼  ¡  %  ´  ²  \007  \021  \033  \205  \217  \231
4  À  Æ  Ð  Ë  Í  K  O  Õ  S  ù  x  (  `  ½  !  #  ¨  ³  \010  \022  \034  \206  \220  \232
5  à  æ  ð  ë  í  k  o  õ  s  Û  Y  )  '  ¾  \  $  ¸  ©  \011  \023  \035  \207  \221  \233
6  Â  B  E  F  Ì  L  Ó  Ø  ß  û  y  [  =  *  |  ¢  ·  ®  \012  \024  \036  \210  \222  \234
7  â  b  e  f  ì  l  ó  ø  T  Ü  Ý  ]  +  ,  ¦  £  ¯  \001  \013  \025  \037  \211  \223  \235

این کد کاراکتر / را از قلم می‌اندازد چون ما نمی‌توانیم فایلی با آن نام ایجاد نماییم، اما ترتیب تمام کاراکترهای دیگر درپیاده‌سازی ‎HP-UX 10.20‎ از ‎en_US.iso88591‎ را نشان می‌دهد. به استثنای یک مورد که من نمی‌توانم آن را در محیط متنی این صفحه وب درج کنم (در محل خالی سمت چپ ‎\003‎). البته، در یک کدگذاری چند بایتی مانند ‎UTF-8‎ ممکن است قدری آشفتگی در آماده سازی مشاهده شود. (احتمالاً بهتر است به صورت قطعه قطعه بررسی گردد.)

چون مرتب‌سازی از منطقه تأثیر می‌پذیرد، در صورتیکه مرتب‌سازی سنتی برحسب ASCII را لازم داشته باشید، شاید ابطال LC_COLLATE را در نظر بگیرید، اما به طور کلی تا آنجا که ممکن است باید به انتخاب منطقه کاربر احترام بگذارید.


CategoryUnix

  • منطقه (آخرین ویرایش ‎2011-05-06 15:26:52‎ توسط 149)