دستوری برای تغییر volume صدای سیستم

در میزکار Xfce می‌توان «کلیدی از صفحه‌کلید» را به عنوان میان‌بری (shortcut) برای «اجرای دستور خاصی» تعریف کرد، در اینصورت با فشردن آن کلید، آن دستور اجرا خواهد شد.

داستان از اینجا شروع شد که کلیدهای چندرسانه‌ای صفحه‌کلید من در Xfce کار نمی‌کرد و باید آنها را تنظیم می‌کردم، برای «کلیدهای تغییر volume صدا» نیازمند به دستور مشابهی بودم. دستور amixer اینکار را با انعطاف زیادی انجام می‌دهد، بطور ساده؛ Master نام کنترل صدای اصلی سیستم است و برای تغییر volume صدای اصلی سیستم از دستور زیر استفاده می‌شود:

$ amixer set Master VOLUME

به جای VOLUME مقدار مورد نظر را قرار دهید، VOLUME می‌تواند برحسب dB یا برحسب درصد باشد، اگر در انتهای آن از علامت مثبت یا منفی استفاده شده باشد، در اینصورت آن را با توجه به تنظیم جاری محاسبه می‌کند. بطور مثال اگر می‌خواهید بلندی صدا در حد وسط باشد، به جای VOLUME مقدار %50 را قرار دهید. اگر می‌خواهید ۱۰ درصد به بلندی صدا اضافه شود، به جای VOLUME مقدار +%10 را قرار دهید. من «کلید افزایش volume صدا» را به عنوان میان‌بری برای اجرای دستور زیر تعریف کردم:

$ amixer set Master 10%+

بنابراین با فشردن آن کلید، صدای اصلی سیستم به میزان ۱۰ درصد بلندتر خواهد شد. برای نمایش لیستی از کنترل‌های قابل قبول، از دستور زیر استفاده کنید و برای تغییر volume صدای کنترل مورد نظر، نام آن کنترل را به جای Master قرار دهید:

$ amixer scontrols

البته انعطاف دستور amixer بیشتر از این است، حتی می‌توانید volume کانال‌های راست و چپ و غیره را بطور دستی تنظیم کنید. دستور man amixer را برای توضیحات بیشتر صادر کنید.

نکته: برای استفاده از دستور amixer باید بسته alsa-utils بر روی سیستم نصب شده باشد.

اجرای دستورات از روی خروجی یک برنامه

بدون مقدمه، دستور زیر را وارد کنید:

$ echo -e "XXX=A\nYYY=B\nZZZ=C"

خروجی این دستور بصورت زیر خواهد بود:

XXX=A
YYY=B
ZZZ=C

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

$ ECHOUT=$(echo -e "XXX=A\nYYY=B\nZZZ=C")
$ eval declare $ECHOUT

دستور eval declare باعث می‌شود که توسط دستور eval محتویات موجود در متغیر ECHOUT با کمک دستور declare به عنوان متغیرهای محیطی تعریف شوند. از این پس به عنوان متغیرهای محیطی به کلیدها و مقادیر موجود در آن دسترسی خواهید داشت:

$ echo $XXX $YYY $ZZZ

کاربرد این روش در زمانی است که بخواهید از ابزارهایی همچون gtkdialog استفاده کنید. دستور gtkdialog برای ایجاد، طراحی و نمایش پنجره‌های GTK از طریق خط فرمان به کار می‌رود و نتایج ناشی از انتخاب‌های کاربر را به عنوان خروجی‌اش چاپ می‌کند، این خروجی را به همین روش می‌توانید در یک متغیر ذخیره کنید و سپس توسط دستور eval آنها را بطور مستقیم به عنوان متغیرهای محیطی تعریف کنید و در نهایت، توسط آن متغیرهای محیطی از انتخاب‌های کاربر با خبر شوید:

$ USERACT=$(gtkdialog --program MYDIALOG)
$ eval declare $USERACT
$ echo The user have selected $EXIT button.

بطور کلی، دستور eval یک دستور داخلی است که رشته‌های متنی را ارزیابی می‌کند و آنها را همانند دستوری در خط فرمان اجرا می‌کند، برای نوشتن اسکریپت (script) و سایر مواردی که دستورات لازم است بطور غیر مستقیم توسط کاربر مشخص شود:

$ RUNEXM=$(echo "cd; ls -l")
$ echo $RUNEXM
$ eval $RUNEXM

در خط اول، ابتدا متنی در متغیر RUNEXM ذخیره می‌شود.
سپس در خط دوم توسط دستور echo محتویات متغیر RUNEXM نمایش داده می‌شود.
اما در خط سوم توسط دستور eval محتویات متغیر RUNEXM ارزیابی و سپس اجرا می‌شود.

تکرار یک دستور به مقدار لازم!

زمانیکه می‌خواهید یک دستور را بر طبق میل خود (در هر لحظه) در bash تکرار کنید، از چه روشی استفاده می‌کنید؟
از حلقهٔ while ؟ اما حلقهٔ while یا for یا do در این مورد جوابگو نیست زیرا در این مورد، تعداد تکرار یک دستور از قبل مشخص نیست و در همان لحظه باید تصمیم بگیریم که آیا آن دستور دوباره تکرار شود یا خیر! مثلا ممکن است ۴ بار یک دستور را تکرار کنیم اما در یک لحظه تصمیم بگیریم که آن را برای بار پنجم تکرار نکنیم یا ممکن است نظر ما عوض شود و آن دستور را تا ۲۰ بار تکرار کنیم!
راه کار چیست؟ دستور خاصی نمی‌خواهد، از کلیدهای Ctrl+O استفاده کنید. به عنوان مثال، دستور زیر را در محیط خط فرمان (کنسول یا Console) وارد کنید:

$ date

پس از اجرای دستور، کلید «جهت بالا» را فشار دهید تا دوباره دستور date ظاهر شود (از طریق history). سپس در همین لحظه، کلیدهای Ctrl+O را فشار دهید و :grin: همین است، هر چقدر می‌خواهید کلید Ctrl+O را فشار دهید و تکرار کنید.

نکته: این روش برای تکرار متناوب بعضی دستورها بسیار مناسب است، مانند دستور plog (در زمان برقراری اتصال به اینترنت)

ویرایش: با تشکر از یک دوست عزیز در قسمت نظرات، استفاده از دستور watch برای خواندن خروجی دستور plog مناسب‌تر است. پس اگر میزان تکرارشدن یک دستور تنها بخاطر خروجی آن نبود، در اینصورت استفاده از کلیدهای Ctrl+O مناسب است، بطور مثال: کپی از فایلهای با محتوای متغیر (دستور cp) برای نگهداشتن محتوای لحظهٔ مورد نظر و یا تکرار ارسال یک پیام به سایر کاربران (دستور write و wall).

استفاده از FIFO برای هدایت خروجی برنامه‌ها

این بار کمی سر به خط فرمان گنو/لینوکس بزنیم. احتمالاً برای شما پیش‌آمده که بخواهید خروجی برنامه‌ای را بصورت real-time از هر جائی که خواستید بتوانید بخوانید. برای این منظور باید با فایل‌های FIFO کار کنیم. فایل‌های FIFO یک فایل معمولی نیستند، از فایل‌های FIFO برای لوله‌کردن خروجی یک برنامه به عنوان ورودی در جای دیگر، استفاده می‌شود.

با یک مثال شروع می‌کنم:

$ mkfifo named-pipe
$ top > named-pipe

این دو دستور، به ترتیب یک فایل از نوع FIFO به نام named-pipe ایجاد می‌کند، سپس برنامهٔ top را که دارای خروجی real-time است را اجرا می‌کند و خروجی آن را به درون فایل named-pipe هدایت می‌کند. پس از اجرا این دستورات، خط فرمان باید قفل شده باشد. پس شما باید یک پنجرهٔ Terminal یا Console دیگری را باز کنید و دستور زیر را در آن وارد کنید:

$ cat named-pipe

اشتباه نکنید، آن چیزی که مشاهده می‌کنید، خود برنامهٔ top نیست! بلکه تنها خروجی آن است، پس اگر کلید q را فشار دهید، از آن خارج نمی‌شوید، تنها شما در حال دیدن خروجی real-time برنامهٔ top هستید. برای پایان می‌توانید کلیدهای Ctrl+C را بفشارید. با انجام اینکار، هم دستور cat و هم برنامهٔ top هر دو با هم متوقف می‌شوند. در انتها، می‌توانید فایل named-pipe را که ایجاد کرده بودید، پاک کنید:

$ rm named-pipe

نکته: همانطور که مشاهده کردید، با استفاده از فایل‌های FIFO (لوله‌های نامگذاری‌شده) می‌توانید به راحتی، خروجی برنامه‌های خط فرمان را هدایت کنید و به اشتراک بگذارید حتی بصورت real-time…

تغییر وضوح ترمینال‌های مجازی

در توزیع‌های گنو/لینوکس مفهومی به نام «ترمینال مجازی» وجود دارد. برای دسترسی به هر ترمینال مجازی، از ترکیب کلیدهای Ctrl+Alt+Fn استفاده می‌شود که Fn می‌تواند یکی از کلیدهای F1 یا F2 یا F3 یا … باشد. بعنوان مثال برای دسترسی به اولین ترمینال مجازی، کلیدهای Ctrl+Alt+F1 را فشار می‌دهیم. هفتمین ترمینال مجازی همان محیط رومیزی (KDE یا GNOME یا غیره) است. پس برای بازگشت به محیط رومیزی، کلیدهای Ctrl+Alt+F7 را فشار می‌دهیم. وضوح ترمینال‌های مجازی بطور پیش‌فرض کم است، وقتی می‌گویم وضوح آنها کم است؛ منظورم این است که اگر وضوح آنها را بیشتر کنیم، نوشته‌های بیشتری در ترمینال‌های مجازی دیده خواهد شد و بعبارتی،  فونت نوشته‌ها کوچکتر شده و تعداد بیشتری از خطوط و کلمات نمایش داده می‌شود.

ابتدا باید بدانید که چه وضوحی توسط سیستم شما پشتیبانی می‌شود. برای این منظور، باید بسته‌ی hwinfo را نصب کرده و دستور زیر را وارد کنید:

# hwinfo --framebuffer

خروجی دستور مذکور، لیست همه‌ی وضوح‌هایی است که سیستم شما پشتیبانی می‌کند، به عنوان مثال؛ قسمتی از خروجی این دستور برای سیستم من بصورت زیر است:

...
Mode 0x033d: 640x400 (+1280), 16 bits
Mode 0x033e: 640x400 (+2560), 24 bits
Mode 0x0345: 1600x1200 (+1600), 8 bits
Mode 0x0346: 1600x1200 (+3200), 16 bits
Mode 0x0347: 1400x1050 (+1400), 8 bits
Mode 0x0348: 1400x1050 (+2800), 16 bits
Mode 0x0349: 1400x1050 (+5600), 24 bits
Mode 0x034a: 1600x1200 (+6400), 24 bits
Mode 0x0352: 2048x1536 (+8192), 24 bits
Mode 0x0360: 1280x800 (+1280), 8 bits
Mode 0x0362: 768x480 (+768), 8 bits
Mode 0x0364: 1440x900 (+1440), 8 bits
Mode 0x0365: 1440x900 (+5760), 24 bits
Mode 0x0368: 1680x1050 (+1680), 8 bits
Mode 0x0369: 1680x1050 (+6720), 24 bits
Mode 0x037b: 1280x720 (+5120), 24 bits
...

بیایید آخرین خط از خطوط بالا را مرور کنیم تا بدانیم منظور از این خط چیست:

Mode 0x037b: 1280x720 (+5120), 24 bits

این خط مشخص می‌کند که سیستم من از وضوح 1280 در 720 (با کیفیت رنگ 24بیت) پشتیبانی می‌کند و عدد 0X037b یک شناسه برای دسترسی به این وضوح است. عدد 0X037b در مبنای ۱۶ بوده و باید آن را به عددی در مبنای ۱۰ تبدیل کنید. اگر روش تبدیل یک عدد از مبنای ۱۶ به مبنای ۱۰ را نمی‌دانید، بهتر است بسته‌ی iprint را نصب کنید. بعد از نصب این بسته، به کمک دستور i می‌توانید عمل تبدیل را انجام دهید. فرض کنید می‌خواهم وضوح ترمینال‌های مجازی را به 1280 در 720 تغییر بدهم و با توجه به خط بالا، عدد 0X037b شناسه‌ی دسترسی به این وضوح است؛ بنابراین باید عدد 0X037b را از مبنای ۱۶ به مبنای ۱۰ تبدیل کنم:

$ i 0X037b | cut -d ' ' -f 1

خروجی این دستور، عدد 891 است، در ادامه، باید فایل boot/grub/menu.lst/ را ویرایش کنم و عدد 891 تنها چیزی خواهد بود که در آن استفاده خواهم کرد. من فرض می‌کنم که شما با نحوه‌ی ویرایش فایل boot/grub/menu.lst/ آشنا هستید. فرض کنید که من گزینه‌ای در منوی گراب با عنوان Debian GNU/Linux دارم که از پارتیشن نهم (hd0,8) بوت می‌شود و می‌خواهم «وضوح ترمینال‌های مجازی» را برای این گزینه تغییر بدهم. بنابراین فایل boot/grub/menu.lst/ را برای ویرایش باز کرده و قسمتی که مشابه زیر باشد را پیدا می‌کنم:

title    Debian GNU/Linux
root    (hd0,8)
kernel    /boot/vmlinuz-2.6.26-1-686 root=/dev/sda9 ro quiet
initrd     /boot/initrd.img-2.6.26-1-686

هم‌اکنون در آخر خط سوم، باید vga=XXX را به لیست پارامترهای هسته (kernel) اضافه کنید و به جای XXX عددی را قرار دهید که قبلا بدست آورده بودیم. در اینجا من باید از عدد 891 استفاده کنم، پس پارامتر vga=891 را بصورت زیر به آخر خط سوم، اضافه خواهم کرد:

title    Debian GNU/Linux
root    (hd0,8)
kernel    /boot/vmlinuz-2.6.26-1-686 root=/dev/sda9 ro quiet vga=891
initrd    /boot/initrd.img-2.6.26-1-686

قسمت تغییر یافته را بصورت پررنگ مشخص کرده‌ام، تغییرات فایل boot/grub/menu.lst/ را ذخیره کنید و سیستم را مجددا از ابتدا راه‌اندازی کنید. از منوی بوت گراب، گزینه‌ای که تغییر داده‌اید را انتخاب کنید و خواهید دید که یک ترمینال مجازی با وضوح بالا چقدر دل‌نشین است :smile: هم‌اکنون فونت نوشته‌ها کوچکتر شده و می‌توانیم متن بیشتری را در ترمینال‌های مجازی بخوانیم و دستورات طولانی‌تری را در یک خط وارد کنیم.

دنبال‌کردن

هر نوشتهٔ تازه‌ای را در نامه‌دان خود دریافت نمایید.