چرا گنو لینوکس رو دوست دارم: ساخت فایل آرشیو رادیوگیک

آپدیت اردیبهشت ۹۳: حالا که مشغول شماره ۴۰ هستیم این فایل فشار زیادی به سرور می یاره و در نتیجه غیرفعالش کردم.. برای دانلود همه شماره ها به آرشیو رادیو گیک روی گیت آی او مراجعه کنین.

یک درخواست اومده به این عنوان:

آرشیو رادیو گیک؟ خب احتمالا کاربرد زیادی نداره و فقط یکی دو نفر شاید یک بار بگیرنش… شاید هم به درد بخوره. من نمی دونم راستش.. به هرحال می تونه یک تجربه ساده و سریع لینوکسی باشه. همه فایل های رادیوگیک اینجا هستن و این شکلی:

webmaster@server:~/public_html/audio$ ls 
jadi.net_radio-geek_000-dragon-pirates.mp3         jadi-net_radio-geek_004_ashke-maahi-haa.mp3  
radio-geek_jadi.net_000-start.mp3                  jadi-net_radio-geek_001_singularity.mp3            
jadi-net_radio-geek_004_ashke-maahi-haa.ogg        shegeftzar.9.10.khoonasham.sample.story_low.mp3
jadi-net_radio-geek_002_space-and-beyond.mp3       radio24-23-November-2011.mp3                 
shegeftzar.9.10.khoonasham.sample.story.mp3        jadi-net_radio-geek_003_ghoole_bazare_makkare.mp3  
radio24-9-November-2011.mp3                        jadi-net_radio-geek_003_ghoole_bazare_makkare.ogg

در اصل هر فایلی که اینجا باشه و اولش با jadi-net_radio-geek شروع بشه مال رادیو است. پس می شه همه اش رو یکجا فشرده کرد:

webmaster@server:~$ cd ~/public_html/audio/ && tar cfz ../radio_geek_all.tar.gz jadi-net_radio-geek*mp3 

پس حالا فایلی دارم که فشرده همه نسخه های ام پی تری رادیو گیک است و در این مسیر قابل دسترسی:

http://jadi.net/radio_geek_all.tar.gz

فقط یک قدم دیگه می مونه که کارها رو اتوماتیک کنم. cron توی یونیکس ها این وظیفه رو داره. کافیه بزنم cron -e یعنی می خوام یک کرون جدید تعریف کنم و توش بنویسم:

# m h  dom mon dow   command
42	3	*	*	2	cd /home/jadi/public_html/audio/ && \
                                             tar cfz ../radio_geek_archive.tar.gz jadi-net_radio-geek*mp3

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

تنظیم کل اینکار کمتر از دو سه دقیقه طول می کشه (: برای همین می گیم لینوکس رو دوست داریم چون ایده ها رو به سادگی عملی می کنه: مثل یک جعبه ابزار دارای کلی ابزار مفید که با هم ترکیبشون می کنیم و یک ایده رو سریعا عملی می کنیم.

آپدیت اردیبهشت ۹۳: حالا که مشغول شماره ۴۰ هستیم این فایل فشار زیادی به سرور می یاره و در نتیجه غیرفعالش کردم.. برای دانلود همه شماره ها به آرشیو رادیو گیک روی گیت آی او مراجعه کنین.

بازیابی محیط گرافیکی لینوکس یا به طور خاص تر یونیتی اوبونتو

سوال در ایمیل:

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

چند تا پروژه مهم و بزرگ متاستفانه روو دسکتاپم هست. * میدونم مسخره هست که پروژه بزرگ رو بزنی رو دسکتاپ ولی این ماجراش فرق میکنه.

جواب ها چند مرحله هستن:

۱) پرسیدن سوال به شکل شخصی کار خوبی نیست. سوال ها باید در جمع پرسیده بشن. هم برای احترام به وقت و انرژی بقیه و هم برای گرفتن جواب کاملتر و هم برای ماندگار شدن جواب ها برای نفرات بعد و چیز یاد گرفتن بقیه (: اما همونطور که من همیشه فقط کاری که خوبه رو نمی کنم ، قبول هم می کنم که بقیه در شرایطی احساس کنن که بهتره یک کاری که می دونن خوب نیست رو بکنن. ما کی قول دادیم هر لحظه بر اساس اصول اخلاقی تصمیم بگیریم؟ (:

۲) ذخیره اطلاعات در دسکتاپ کار بدی نیست. دسکتاپ هم یک فولدر است دیگه (: توی ویندوز گاهی می گفتیم بده چون دسکتاپ ویژگی‌های کمی متفاوت از یک فولدر کاملا عادی داشت ولی توی لینوکس HOME هر آدم یک دایرکتوری است که دایرکتوری های توش فرق خاصی با هم ندارن. من هم اکثرا پروژه های در حال کارم روی دسکتاپم هستن.

۳) حواست باشه که تو اولین نفر در تاریخ نیستی که این کار رو کردی. حتما قبلا یکی دیگه کرده، به شکل خوبی توی یک فروم پرسیده و جواب گرفته و اون جواب برای تو هم کار می کنه. اگر هم واقعا کاری کردی که اولین نفر در تاریخی خیلی خیلی بهتره که خیلی جدی بگیریش، عمومی بنویسی و جوابی که بهش رسیدی رو هم اضافه کنی به نوشته ات تا بقیه بتونن توی جای پایی که ساختی راه برن. گنو/لینوکس یک جامعه زیباست. یک فرهنگ جمعی.

۴) راه حل! سه تا می تونه باشه: نصب یک محیط کار دیگه و لاگین کردن توی اون و راه انداختن علی الحساب کار، پاک کردن صورت مساله و شبیه کردن تنظیمات محیط گرافیکی اوبونتو به روز اول، کشف و حل مشکل.

اما چجوری

در لینوکس همه چیز فایله. تازه اونهم فایل های متنی قابل ادیت. فایل های تنظیمات عمومی معمولا توی etc/ قرار دارن و تنظیمات شخصی هر کس توی فولدر خونگی اش در دایرکتوری هایی که اسمشون با یک نقطه شروع می شه ( مثلا compiz-1. ) اگر این فایل ها رو پاک کنی (از رو اسم باید تشخیص بدی کدوم ها مفید هستن) اون برنامه ای که تنظیماتش پاک شده مثل روز اول می شه.

اما چجوری به این فایل ها دسترسی پیدا کنی؟ از طریق کامند لاین که مثل بالا زدن کاپوت ماشینه. برای اینکار کافیه Ctrl و Alt رو فشار بدی و یکی از دگمه‌های اف.فلان رو بزنی. مثلا Ctrl+Alt+F3 یک کامند لاین بهت می ده که می تونی توش لاگین کنی. یا مثلا اف۴ یا اف۶ یک کامند لاین دیگه. انگار همزمان پشت پنج شش تا کامپیوتر نشستی و بینشون سوییچ می کنی. این یکی از خصوصیات خیلی منحصر به فرد لینوکس بود از روز اول. در سیستم های مختلف زدن کنترل+آلت+اف۱ یا کنترل+آلت+اف۷ ممکنه کارهای جالبری بکنه (مثلا باز کردن اون یک یوزری که به محیط گرافیکی وصله). به هرحال همه اف ها رو امتحان کن و ببین چی می شه.

از محیط گرافیکی که وارد شدی توی خونه خودت هستی. پاک کردن دایرکتوری های تنظیمات یونیتی ممکنه کمک خوبی باشه:

cd
rm -rf .compiz-1
rm -rf .config/compiz-1/

و خب مشخصه که اگر کار خاصی کرده باشی باید اونها رو هم پاک کنی. مثلا اگر توی گنوم شل تم نصب کرده باشی باید اونم پاک کنی. اگر بالایی کار نکرده می تونی تنظیمات بیشتری رو پاک کنی:

cd 
rm -rf .gnome .gnome2 .gconf .gconfd .metacity .compiz-1 .config/compiz-1 .config/dconf

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

 gconftool-2 --recursive-unset /apps/compiz-1
 unity --reset
 unity --reset-icons
 gsettings reset com.canonical.Unity.Launcher favorites

راه دیگه اینه که کامپیوتر رو به اینترنت وصل کنی (از توی همون کامند لاین که می تونه به سادگی وصل کردن کابل اترنت باشه) و یک دسکتاپ جدید نصب کنی:

sudo apt-get install lubuntu-desktop

وبعد لاگین کردن توی این دسکتاپ. در ضمن توی هون کامند لاین همه فایل های روی دسکتاپ از اینجا قابل دسترسی هستن:

cd Desktop
ls

(: دوستانی که می خوان بگن «دیدین لینوکس خراب شد» زود بگن تا من برم سراغ پست بعدی که مقایسه انواع سیستم عامل با انواع خودرو است (: از حالا بگم که ویندوز ایکس پی پرایده!

نکته آخر: همیشه قبل از کپی و پیست کردن هر دستوری توی سیستم عاملتون وقت کوتاهی بذارین و یاد بگیرین که این دستور چیکار می کنه (: اینجوری هم لینوکس یاد می گیرین هم کنترل کامپیوتر و زندگی تون رو نمی دین دست یک آدم ناشناس توی اینترنت که ممکنه هر جور مریضی ای داشته باشه (:

زیرنویس فارسی ویدئوی تست بکدل در فیلم های هالیوود

چند مطلب قبل در مورد تست بکدل و بررسی فیلم های اسکار نوشتم. دیروز فرصتی شد که زیرنویس این ویدئو رو فارسی کنم. اگر خواستین توی یوتوب ویدئو رو با زیر نویس (به زبان هایی که موجوده)‌ ببنید کافیه روی CC کلیک کنید و مثل تصویر زیر، زبان مورد نظر یا تنظیماتش رو انتخاب کنین:

در صورت علاقمندی به دیدن این ویدئوی ده دقیقه به اینجا سر بزنین یا همینجا مشاهده اش کنین:

پ.ن. برای ترجمه از سرویس بسیار راحت و خوش دست www.universalsubtitles.org استفاده کردم

چرا گنو/لینوکس رو دوست دارم: یک ستونه کردن یک پی دی اف تصویری دو ستونه

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

من می خوام اینها یک ستونه باشن. کار هم نشد نداره… بخصوص وقتی ابزار خوب دارین. قدم اول اینکه هر پی دی اف رو به یکسری عکس های مستقل با کیفیت خوب تبدیل کنم. می‌زنم:

$ convert -verbose -colorspace GRAY -interlace none -density 150 1.pdf 1.png

مشخصه: تغییر بده -حرف زیاد بزن -خاکستری -کیفیت ۱۵۰ فایل یک.پی‌دی‌اف رو روی فایل‌هایی به اسم ۱.پی‌ان‌جی.

نتیجه؟ بعد از رسیدن دمای سی پی یو به ۸۵ سانتی‌گراد، به چیزی شبیه این می‌رسیم:

کلی فایل دارم که دو ستونه هستن. حالا من یک چیزی می‌خوام که هر عکس رو به دو ستون مختلف تبدیل کنه. بازم جادوی convert. اینبار مثلا برای به دست آوردن سمت چپ صفحه بیست و پنج جلد یک اینطوری کار می کنیم:

$ convert 1-25.png -crop 1240×17540+0+0 +repage 1-25b.png

یعنی تغییر بده -فلان صفحه رو -ببر از گوشه سمت چپ بالا به عرض ۱۲۴۰ پیکسل (نصف عرض تصویر) و ارتفاع 1754 و نتیجه رو بریز توی فایلی با همون اسم که کنارش یک b است. در ضمن یک repage هم اضافه داره که باعث می شه موقع نوشتن تصویر جدید،‌ بیخیال این بشیم که قبلا این تصویر چه ابعادی داشته و کلا یک تصویر جدید با این اطلاعات جدید بسازیم.

برای سمت راست هم:

$ convert 1-25.png -crop 1240×1754+1240+0 +repage 1-25a.png

که خب مثل قبلی است ولی می گه از وسط عرض شروع کنه به بریدن که در نتیجه خروجی می شه ستون سمت راست (اسمش رو می ذاریم a).

حالا که با یک صفحه تونستم اینکار رو بکنم، باید با همه صفحات بتونم. کافیه دستور find که می تونه یکسری فایل رو بهم بده رو تست کنم:

$ find . -name “1-*” -exec convert \{\} -crop 1240×1754+0+0 +repage \{\}b.png \;

دستور فایند همه فایل های توی این شاخه که اسمشون شبیه اسم کتاب من هست رو پیدا می کنه و بعد در بخش exec اونها رو یکی یکی می ده به دستوری که بالا داشتیم (کانورت). حالا عین همین رو بعد از جدا کردن فایل های تازه وارد، برای صفحات سمت راست هم اجرا می کنم:

$ find . -name “1-*” -exec convert \{\} -crop 1240×1754+1240+0 +repage \{\}a.png \;

و بعد می رسم به مجموعه ای فایل‌ها که به ترتیب حروف الفبا،‌ صفحات کتاب هستن:

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

$ convert 1*png jeld1.pdf

اوه شکست موقت خوردیم! ترتیب صفحات قاطی پاتی شده. من دقیق نمی‌دونم باید چیکار کنم پس یک راه کثیف سریع که بلدم رو استفاده می کنم! می دونم دستور دایرکتوری گیری یک سوییچ داره به اسم v که به ترتیب معقول مثل آدم سورت می کنه (پس بیخود نبود که از اسم a و b برای ستون راست و چپ استفاده کردیم ;) ). حالا ls رو با v به همراه سوییچ 1 که هر فایل رو در یک خط نشون می ده می زنم و خروجی رو می دم به xargs echo که کل اینها رو پشت هم نشون بده. می شه این:

می دونم کثیفه ولی یکبار در تاریخ می شه تحملش کرد و تازه جا داره دوستان پیشنهادات بهتر بدن! حالا کافیه این تیکه رو کپی پیست کنم جلوی یک دستور کانورت و آخرش هم اسم فایل خروجی رو بدم.. داریم:

$ convert 1-0.pnga.png 1-0.pngb.png 1-1.pnga.png 1-1.pngb.png 1-2.pnga.png 1-2.pngb.png 1-3.pnga.png 1-3.pngb.png 1-4.pnga.png 1-4.pngb.png 1-5.pnga.png 1-5.pngb.png 1-6.pnga.png 1-6.pngb.png 1-7.pnga.png 1-7.pngb.png 1-8.pnga.png 1-8.pngb.png 1-9.pnga.png 1-9.pngb.png 1-10.pnga.png 1-10.pngb.png 1-11.pnga.png 1-11.pngb.png 1-12.pnga.png 1-12.pngb.png 1-13.pnga.png 1-13.pngb.png 1-14.pnga.png 1-14.pngb.png 1-15.pnga.png 1-15.pngb.png 1-16.pnga.png 1-16.pngb.png 1-17.pnga.png 1-17.pngb.png 1-18.pnga.png 1-18.pngb.png 1-19.pnga.png 1-19.pngb.png 1-20.pnga.png 1-20.pngb.png 1-21.pnga.png 1-21.pngb.png 1-22.pnga.png 1-22.pngb.png 1-23.pnga.png 1-23.pngb.png 1-24.pnga.png 1-24.pngb.png 1-25.pnga.png 1-25.pngb.png 1-26.pnga.png 1-26.pngb.png 1-27.pnga.png 1-27.pngb.png 1-28.pnga.png 1-28.pngb.png 1-29.pnga.png 1-29.pngb.png 1-30.pnga.png 1-30.pngb.png 1-31.pnga.png 1-31.pngb.png 1-32.pnga.png 1-32.pngb.png 1-33.pnga.png 1-33.pngb.png 1-34.pnga.png 1-34.pngb.png 1-35.pnga.png 1-35.pngb.png 1-36.pnga.png 1-36.pngb.png 1-37.pnga.png 1-37.pngb.png 1-38.pnga.png 1-38.pngb.png 1-39.pnga.png 1-39.pngb.png 1-40.pnga.png 1-40.pngb.png 1-41.pnga.png 1-41.pngb.png 1-42.pnga.png 1-42.pngb.png 1-43.pnga.png 1-43.pngb.png 1-44.pnga.png 1-44.pngb.png 1-45.pnga.png 1-45.pngb.png 1-46.pnga.png 1-46.pngb.png 1-47.pnga.png 1-47.pngb.png 1-48.pnga.png 1-48.pngb.png 1-49.pnga.png 1-49.pngb.png 1-50.pnga.png 1-50.pngb.png 1-51.pnga.png 1-51.pngb.png 1-52.pnga.png 1-52.pngb.png 1-53.pnga.png 1-53.pngb.png 1-54.pnga.png 1-54.pngb.png 1-55.pnga.png 1-55.pngb.png 1-56.pnga.png 1-56.pngb.png 1-57.pnga.png 1-57.pngb.png 1-58.pnga.png 1-58.pngb.png 1-59.pnga.png 1-59.pngb.png 1-60.pnga.png 1-60.pngb.png 1-61.pnga.png 1-61.pngb.png 1-62.pnga.png 1-62.pngb.png 1-63.pnga.png 1-63.pngb.png 1-64.pnga.png 1-64.pngb.png 1-65.pnga.png 1-65.pngb.png 1-66.pnga.png 1-66.pngb.png 1-67.pnga.png 1-67.pngb.png 1-68.pnga.png 1-68.pngb.png 1-69.pnga.png 1-69.pngb.png 1-70.pnga.png 1-70.pngb.png 1-71.pnga.png 1-71.pngb.png 1-72.pnga.png 1-72.pngb.png 1-73.pnga.png 1-73.pngb.png 1-74.pnga.png 1-74.pngb.png 1-75.pnga.png 1-75.pngb.png 1-76.pnga.png 1-76.pngb.png 1-77.pnga.png 1-77.pngb.png 1-78.pnga.png 1-78.pngb.png 1-79.pnga.png 1-79.pngb.png 1-80.pnga.png 1-80.pngb.png 1-81.pnga.png 1-81.pngb.png 1-82.pnga.png 1-82.pngb.png 1-83.pnga.png 1-83.pngb.png 1-84.pnga.png 1-84.pngb.png 1-85.pnga.png 1-85.pngb.png 1-86.pnga.png 1-86.pngb.png 1-87.pnga.png 1-87.pngb.png 1-88.pnga.png 1-88.pngb.png 1-89.pnga.png 1-89.pngb.png 1-90.pnga.png 1-90.pngb.png 1-91.pnga.png 1-91.pngb.png 1-92.pnga.png 1-92.pngb.png 1-93.pnga.png 1-93.pngb.png 1-94.pnga.png 1-94.pngb.png 1-95.pnga.png 1-95.pngb.png 1-96.pnga.png 1-96.pngb.png 1-97.pnga.png 1-97.pngb.png 1-98.pnga.png 1-98.pngb.png 1-99.pnga.png 1-99.pngb.png 1-100.pnga.png 1-100.pngb.png 1-101.pnga.png 1-101.pngb.png 1-102.pnga.png 1-102.pngb.png 1-103.pnga.png 1-103.pngb.png 1-104.pnga.png 1-104.pngb.png 1-105.pnga.png 1-105.pngb.png 1-106.pnga.png 1-106.pngb.png 1-107.pnga.png 1-107.pngb.png 1-108.pnga.png 1-108.pngb.png 1-109.pnga.png 1-109.pngb.png 1-110.pnga.png 1-110.pngb.png 1-111.pnga.png 1-111.pngb.png 1-112.pnga.png 1-112.pngb.png 1-113.pnga.png 1-113.pngb.png 1-114.pnga.png 1-114.pngb.png 1-115.pnga.png 1-115.pngb.png 1-116.pnga.png 1-116.pngb.png 1-117.pnga.png 1-117.pngb.png 1-118.pnga.png 1-118.pngb.png 1-119.pnga.png 1-119.pngb.png 1-120.pnga.png 1-120.pngb.png 1-121.pnga.png 1-121.pngb.png 1-122.pnga.png 1-122.pngb.png 1-123.pnga.png 1-123.pngb.png 1-124.pnga.png 1-124.pngb.png 1-125.pnga.png 1-125.pngb.png 1-126.pnga.png 1-126.pngb.png 1-127.pnga.png 1-127.pngb.png 1-128.pnga.png 1-128.pngb.png 1-129.pnga.png 1-129.pngb.png 1-130.pnga.png 1-130.pngb.png 1-131.pnga.png 1-131.pngb.png 1-132.pnga.png 1-132.pngb.png 1-133.pnga.png 1-133.pngb.png 1-134.pnga.png 1-134.pngb.png 1-135.pnga.png 1-135.pngb.png 1-136.pnga.png 1-136.pngb.png 1-137.pnga.png 1-137.pngb.png 1-138.pnga.png 1-138.pngb.png 1-139.pnga.png 1-139.pngb.png 1-140.pnga.png 1-140.pngb.png 1-141.pnga.png 1-141.pngb.png 1-142.pnga.png 1-142.pngb.png 1-143.pnga.png 1-143.pngb.png 1-144.pnga.png 1-144.pngb.png 1-145.pnga.png 1-145.pngb.png 1-146.pnga.png 1-146.pngb.png jeld1.pdf

و حالا بعد از نیم ساعت کار یک کتاب دارم که جوری است که راحت می تونم بخونمش (:

صاحب ابزار خوب بودن فوق العاده نیست؟

توضیح لازم

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

کتاب داستان پداگوژیکی است، که تا مدت محدودی برای دانلود می ذارمشون اینجا: جلد یک و جلد دو

چطوری اسکریپت نویسی بش یا هر چیز دیگه یاد بگیریم؟

دراگو توی مطلب مربوط به نوشتن یک اسکریپت بش پرسیده:

چطور میتونم توی اسکریپت نوشتن واسه bash مسلط بشم؟

اول باید بگم که آدم‌ها از شیوه‌های مختلف چیز یاد می‌گیرین. بعضی‌ها تئوری، بعضی‌ها با نگاه کردن و تکرار و بعضی‌ها با عمل. من جزو گروه آخری هستم. شما ممکنه توی گروه دیگه یا جایی بین گروه‌ها باشین.

من به شکل کلی چیزها رو عمیق یاد نمی‌گیرم. حداقل عمیق شروعشون نمی‌کنم. در ضمن چیزی رو توی خلاء هم یاد نمی‌گیرم. همینه که از ریاضی فراری بودم همیشه ولی مثلا فیزیک رو بیشتر دوست داشتم. من باید یک سوال واقعی برای حل کردن داشته باشم و بعد برم به سراغ جمع کردن ابزار لازم.

قدم اول پیشنهادی من برای خودم، خوندن Tutorial است. خوندن راهنماهای سریع و مقدماتی. مثلا اگر بخوام بش رو یاد بگیرم، یک گوگل برای Bash Tutorial می کنم و بعد هفت هشت تا از صفحه‌هایی که به نظرم خوب بیان رو با میدل۰کلیک کردن باز می‌کنم. اونوقت توی همه اونها یک چرخ می‌زنم و یکی دو تا شون رو برای خوندن انتخاب می‌کنم. منطقا دنبال چیزهایی هستم که خیلی کوتاه نباشن ولی خیلی خیلی هم بلند نباشن و بشه یک بعد از ظهر یا چند ساعته خوندشون. اونوقت تند و تند می‌خونم.

نمی‌دونم چرا به هرکی اینو می‌گم می‌خنده:

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

(((: درسته. من معمولا چیزی که نیاز به کلاس و اینها داشته باشه نمی‌نویسم. استفاده می‌کنم ولی خودم نمی‌نویسم چون کلا اسکریپت‌های کوچیک بیشترین چیزی است که دنبالشم.

من اینها رو توی این راهنماهایی که پیدا کردم یاد می گیرم و بعد سرچ می‌کنم. مثلا اگر بخوام کل فایل‌های توی یک دایرکتوری که ممکنه توشون فاصله هم داشته باشن رو یکی یکی پروسس کنم، گوگل می کنم دنبال bash script loop files in directory space in filename (: دقیقا. اون مطلبی که قبلا نوشته بودم با نتیجه اولین جستجویی است که اینجا اومده.

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

در آخرش سه تا نکته رو اضافه می کنم:

  • توی این مقاله هی گفتم «من». مال یادآوری این بود که این روش منه. هر کس به شیوه ای متفاوت یاد می گیره و این بدترین نکته در کل نظام آموزشی است که انتظار دارن همه یک جور یاد بگیرن. شما باید روش خودتون رو کشف کنین.
  • روش من سرعتش بسیار زیاده و برای من پر از لذت اما عمق نداره. اگر می خواین مثلا متخصص پرل باشین، لازمه بعد از خوندن توتریال‌ها و نوشتن برنامه‌ها و اینها برین سراغ کتاب های واقعی، کد واقعی نگاه کنین و …
  • در نهایت اگر دوست داشتین نگاهی به این پادکست هم بندازین: چگونه برنامه نویس بشیم.

چرا گنو/لینوکس رو دوست دارم: انتقال کلی کتاب به پوشه هم نامشون

یک دوست ایمیل زده که:

۱۲۰۰ تا کتاب دارم که همه در یک دایرکتوری هستن. می خوام یک دایرکتوری برای هر یک کتاب ساخته بشه و کتاب بره توی دایرکتوری خودش. یعنی می خوام ۱۲۰۰ تا دایرکتوری بسازم و هر کتاب رو کپی کنم سر جاش.

چراش رو من نمی دونم… ولی چجوری اش رو می دونم: گنو/لینوکس پر از ابزارهای ریز است که هر کدوم برای کار خودشون بهترین هستن و ترکیب اینها باعث می شه بشه تقریبا هر چیزی ساخت. کل کار رو می شه توی یک خط انجام داد اما پیچیدگی با احتمال استفاده شدن فاصله در نام فایل بیشتر می شه. حتما روش های ساده تر هم هست اما من اینطوری نوشتم:

jadi@freebasse:/tmp/books$ cat ../p.sh
#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in books/*
do
  mkdir "$f"_dir
  mv "$f" "$f"_dir/
  echo "$f"
done
IFS=$SAVEIFS

یک حلقه for است که همه فایل ها رو یکی یکی می ندازه وسط دایره. هر کی وسط باشه اول یک فولدر براش ساخته می شه با _dir و بعد یک mv روش اجرا می شه و خلاص. اون IFS متغیری است که توی بش تعریف می کنه جدا کننده فیلدها از هم باید چی باشه. معمولا اسپیس است اما چون اینجا ممکنه اسم فایل توش اسپیس داشته باشه، کردیمش «سرخط».

نکته: دوستم بعد از گرفتن این گفت که کامپیوتر ویندوزی است (: کماکان راحته. کافیه یک اوبونتو یا هر توزیع لینوکس دیگه دانلود کنید، روی یو اس بی نصبش کنین و لایو بوت کنین و این کارها رو انجام بدین و دوباره بوت کنین و برگردین توی ویندوز عزیز. مثل همیشه: بک آپ فراموش نشه!

آپدیت: دوست خوبم مهدی بیگی توی کامنت ها این شیوه راحت تر و بهتر رو پیشنهاد داده:


find -type f -exec mkdir '{}'.tmp \; -exec mv '{}' '{}'.tmp \; -exec mv '{}'.tmp '{}' \;

که فقط یک دستور است. دستور find می تونه چیزهای مختلف رو پیدا کنه و اینجا با سوییچ f دنبال فایل می گرده. بعد روی تک تک اون فایل ها چیزی که جلوی سوییچ exec هست رو اجرا می کنه و هر بار به جای {} یکی از فایل های پیدا شده رو می ذاره. در نهایت هم اسلش سمی کالن می گه چیزی که جلوی سوییچ exec بوده تموم شده.

چرا به گنو/لینوکس عشق می ورزم: خاطرات یک هکر

می‌دونین که من سفر کاری خیلی زیاد می رم . در یکی از از سفرها قرار شد یک دستگاه رو با یک دستگاه دیگه عوض کنن ولی یک سوال مهم باقی موند:

جادی عزیز، ما یک دیتابیس از ۳۰۰ هزار کاربر داریم که هش شده‌اند. حالا قرار است این افراد به یک سیستم جدید منتقل شوند اما لازم است پسوردهای آنان را داشته باشیم. شرکت سازنده نرم افزار اول و شرکت نویسنده نرم افزار جدید گفته‌اند که امکان کشف اینکه یک هش چه چیزی بوده وجود ندارد. شما راه حلی می‌شناسید؟

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

9370333**** ea9bf866d98db73eb0909fa9c1cc1b11
9370050**** fcbfab2f4cda26061ed9e3ee96a4fd61
9370750**** 6a130f1dc6f0c829f874e92e5458dced
9370001**** 9ad97add7f3d9f29cd262159d4540c96

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

خب حالا راه حل ما چیه؟ یک راه که بهش «بروت فورث» می‌گن اینه که یکی یکی هر چیز ممکن رو هش کنیم. یعنی اول ۱ رو هش کنیم ببنیم به اون چیزی که اونجا هست می‌رسیم یا نه. بعد ۲ رو هش کنیم. بعد ۱۲ رو بعد ۱۱ رو و خلاصه هر چیز ممکن رو. اینکار یک نیروی کور است و بسیار وقت گیر. اما یک راه هوشمندانه تر هم داریم که بهش می‌گن رنگین کمان / rainbow. تکنیک رنگین کمان اینه که تمام کارهای بالا رو بکنیم (یعنی مثلا اگر اکثر افراد در موبایل از پسوردهای عددی استفاده می کنن از ۰ تا ۹۹۹۹۹ رو هش کنیم و رمز و هش اون رو بریزیم توی یک دیتابیس) و بعد یکی یکی هش ها رو توی دیتابیس سرچ کنیم و پسورد رو نشون بدیم… خب آماده‌اید؟

برای ایجاد همه پسوردهای ۰۰۰۰۰ تا ۹۹۹۹۹ و هش کردن اونها این برنامه پایتون رو نوشتم. مطمئنا می‌تونه بهتر هم نوشته بشه ولی این کار من رو راه انداخت:

#!/usr/bin/python

import MySQLdb

db = MySQLdb.connect("localhost","jadi","password","break" )

# prepare a cursor object using cursor() method
cursor = db.cursor()


for i in range(0, 10000):
    pre = '';
    if i < 10:
        pre += '0';
    if i < 100:
        pre += '0';
    if i < 1000:
        pre += '0';
    num = "%s%s" % (pre, i);
    print num;
    # execute SQL query using execute() method.
    cursor.execute("insert into rainbox values ('%s', md5('%s'));"%(num,num));

# Fetch a single row using fetchone() method.
#data = cursor.fetchone()

# disconnect from server
db.close()

همین برنامه رو برای پسوردهای ۰۰۰۰۰ تا ۹۹۹۹۹ و ۰۰۰ تا ۹۹۹ و ۰۰ تا ۹۹ و ۰ تا ۹ هم کم و زیاد کردم و رنگین کمانی شامل ۱۱۱۱۱۰ پسورد و هش اون ساختم:

mysql> select count(*) from rainbox;
+----------+
| count(*) |
+----------+
|   111110 |
+----------+
1 row in set (0.07 sec)

بعد کلیدی روی هش تعریف کردم که سرچ سریعتر بشه:

mysql> ALTER TABLE rainbox ADD primary index (hash);

حالا وقت شکستن رمزها است. فایلی دارم به اسم users.csv که این شکلی است (چهار رقم آخر تلفن ها رو ستاره کردم که پرایوسی آدم‌ها حفظ بشه):

9370333**** ea9bf866d98db73eb0909fa9c1cc1b11
9370050**** fcbfab2f4cda26061ed9e3ee96a4fd61
9370750**** 6a130f1dc6f0c829f874e92e5458dced
9370001**** 9ad97add7f3d9f29cd262159d4540c96

کافیه این رو با لایبری csv پایتون بخونم، و بعد هش هر خط رو از دیتابیسم کوئری بزنم و اگر جواب داشت توی خروجی تلفن و هش و پسورد شکسته شده رو بنویسم و اگر هم جواب این هش توی دیتابیس من نبود، جلوش بنویسم later تا بعدا از یک جای دیگه پیداش کنم.

#!/usr/bin/python

import MySQLdb
import csv

db = MySQLdb.connect("localhost","jadi","password","break" )

# prepare a cursor object using cursor() method
cursor = db.cursor()

spamReader = csv.reader(open('users.csv', 'rb'), delimiter=' ', quotechar='|')
for row in spamReader:
    tofind = row[1];
    try:
        cursor.execute("select pass from rainbox where hash = '%s'"%tofind);
        data = cursor.fetchone()[0];
        print row[0], tofind, data;
    except: #this hash was not in db
        print row[0], tofind, "later" 

# disconnect from server
db.close()

برنامه بالا رو اجرا می‌کنم و زمان می‌گیرم:

jadi@jubun:~/w$ wc -l users.csv && time python break.py > out.txt
316590 users.csv

real    0m57.226s
user    0m25.362s
sys 0m4.856s

واو! سیصد و شونزده هزار پسورد رو توی کمتر از یک دقیقه شکستیم (: یک نگاه به فایل آوت.تکست می‌گه:

jadi@jubun:~/w$ head out.txt 
93703334*** ea9bf866d98db73eb0909fa9c1cc1b11 7523
93700508*** fcbfab2f4cda26061ed9e3ee96a4fd61 8510
93707500*** 6a130f1dc6f0c829f874e92e5458dced 7496
93700013*** 9ad97add7f3d9f29cd262159d4540c96 9538
93700177*** c902514ac30b6e23dbb0c3dc80ec7d4a later
93700858*** ee676ed9ce5bd51b4452ddfbdf962ef7 later
93707848*** 8c249675aea6c3cbd91661bbae767ff1 1986

ظاهرا پسوردهای چهار رقمی مد هستن (: ظاهرا تعداد later ها هم کم نیست. بذارین یک نگاه هم به اونها بندازیم:

jadi@jubun:~/w$ grep later out.txt | wc -l 
1558

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

jadi@jubun:~/w$ grep later out.txt  > later.txt && \
                                cut later.txt -f2 -d' ' | uniq -u | wc -l 
5536

نتیجه طبیعی نیست... یعنی از شش هزار نفر فقط پونصد ششصد نفر پسورد تکراری داشتن؟ هر کسی که یک مقاله در مورد رفتار پسوردی آدم‌ها خونده باشه می دونه که این عدد غیر واقعی است.. مشکل! قبل از استفاده از دستور یونیک، باید داده‌ها رو مرتب کرد. پس یک سورت بین دستور اضافه می کنم:

jadi@jubun:~/w$ cut later.txt -f2 -d' ' | sort | uniq -u | wc -l 
767

هها! نگفته بودم؟ کل این شش هزار نفر باقیمونده، فقط از ۷۶۷ پسورد استفاده کردن. این ۷۶۷ پسورد رو می‌ریزیم توی یک فایل مجزا برای کشف کردنشون در پست بعدی.

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

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

Found: md5("zaka") = 00a3b206c4ad2cae515e28745423093a

و zaka رو یک جایی ذخیره کنه. کافیه این کار رو برای همه هش‌هایی که هنوز کشف نشدن ادامه بدیم. مشخصه که هنوز یکسری کشف نشده خواهند موند ولی بذارین ببینیم به چی می رسیم. این مرحله به خاطر فرستادن درخواست به اینترنت کندتر است و یک راه حل خوبه اینه که فایل hard.txt و برنامه رو روی یک سرور وی پی اس آپلود کنیم و اونجا اجراش کنیم. همین کار رو می کنم و برنامه پایتون رو هم اینجوری می‌نویسم که یکی یکی هش ها رو برداره، به اون سایت بفرسته و توی خروجی اچ تی ام ال که بر می گرده، خطی که پسورد رو نشون می ده رو جدا کنه. اگر این هش اونجا هم نبود می نویسیم too difficult و از خیرش می گذریم (: بریم ببینیم چی می شه:

#!/usr/bin/python

import urllib
import csv
import re

spamReader = csv.reader(open('hard.txt', 'rb'), delimiter=' ', quotechar='|')
for row in spamReader:
    try:
        # This is here for copy/pasters....
        # Originally by Jadi at jadi.net
        params = urllib.urlencode({'term':row[0], 'crackbtn': 'Crack that hash baby!'})
        f = urllib.urlopen("http://md5crack.com/crackmd5.php", params)
        page = f.read()
        password = re.search('Found: md5\("(.*)"\) = %s' % row[0], page)
        print row[0], password.group(1)
    except: 
        print "too difficult"

و برای اجرا می‌زنیم:

user@remotehost:/tmp$nohup python onlinebreak.py > easy.txt & 

که خروجی پسوردهای شکسته شده رو بریزه توی easy.txt و حتی اگر من هم قطع شدم کار رو در پشت زمینه ادامه بده. تقریبا بعد از یازده دقیقه کار، همه پسوردها با این بانک اطلاعاتی هم چک می‌شن. بعد از اضافه کردن این‌ها به موارد شکسته شده قبلی توی دیتابیس خودمون، یک نگاه می‌ندازیم ببینیم چند تا از پسوردها هنوز باقی موندن.

jadi@jubun:~/w$ time python break.py > out.txt &&  grep later out.txt | wc -l 

real    0m58.863s
user    0m27.706s
sys 0m5.756s
1558

عالی (: حالا دیگه فقط ۱۵۵۸ نفر داریم که پسوردشون کشف نشده. از سیصد هزار نفری که اول داشتیم، پیشرفت عالیی است (: این هزار و پونصد نفر که پسوردهای غیرمعمول گذاشتن هم می‌تونن زنگ بزنن به پشتیبانی و بگن از امروز پسوردشون کار نمی کنه و اونها براشون ریست می کنن (:

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

jadi@jubun:~/w$ cut out.txt -f3 -d' ' | sort | uniq -c | sort -b -n -r | head
 192019 1234
  11780 2222
  10532 123
   9734 1111
   7547 5555
   5293 12345
   4512 4444
   4473 0000
   2568 3333
   2192 444

و این شما و این پر استفاده‌ترین پسوردهای این سیصد هزار نفر. جالبه که ۶۰٪ از کاربران پسوردشون رو گذاشتن ۱۲۳۴۵. فوق العاده نیست؟

کتاب فارسی رایگان وردپرس

سایت کسب و کار اینترنتی، با گذاشتن کلی وقت یک کتاب خوب درست کرده در مورد وردپرس و در یک کار خوب، اون رو به شکل رایگان برای دانلود سایتش گذاشته.

برای دانلود کتاب رایگان وبلاگنویسی آسان با وردپرس اینجا رو کلیک کنید

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

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