شاخه /proc در حقیقت یک سیستم فایل کاذب است. فایلها در /proc پردازشهای کرنل و سیستم درحال اجرای فعلی را بازتاب میدهند و شامل اطلاعات و آماری در باره آنها هستند.
bash$ cat /proc/devices Character devices: 1 mem 2 pty 3 ttyp 4 ttyS 5 cua 7 vcs 10 misc 14 sound 29 fb 36 netlink 128 ptm 136 pts 162 raw 254 pcmcia Block devices: 1 ramdisk 2 fd 3 ide0 9 md bash$ cat /proc/interrupts CPU0 0: 84505 XT-PIC timer 1: 3375 XT-PIC keyboard 2: 0 XT-PIC cascade 5: 1 XT-PIC soundblaster 8: 1 XT-PIC rtc 12: 4231 XT-PIC PS/2 Mouse 14: 109373 XT-PIC ide0 NMI: 0 ERR: 0 bash$ cat /proc/partitions major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq 3 0 3007872 hda 4472 22260 114520 94240 3551 18703 50384 549710 0 111550 644030 3 1 52416 hda1 27 395 844 960 4 2 14 180 0 800 1140 3 2 1 hda2 0 0 0 0 0 0 0 0 0 0 0 3 4 165280 hda4 10 0 20 210 0 0 0 0 0 210 210 ... bash$ cat /proc/loadavg 0.13 0.42 0.27 2/44 1119 bash$ cat /proc/apm 1.16 1.2 0x03 0x01 0xff 0x80 -1% -1 ? bash$ cat /proc/acpi/battery/BAT0/info present: yes design capacity: 43200 mWh last full capacity: 36640 mWh battery technology: rechargeable design voltage: 10800 mV design capacity warning: 1832 mWh design capacity low: 200 mWh capacity granularity 1: 1 mWh capacity granularity 2: 1 mWh model number: IBM-02K6897 serial number: 1133 battery type: LION OEM info: Panasonic bash$ fgrep Mem /proc/meminfo MemTotal: 515216 kB MemFree: 266248 kB
اسکریپتهای پوسته میتوانند دادهها را از برخی فایلهای /proc استخراج نمایند. [1]
FS=iso #آیا سیستم فایل ISO در کرنل نگهداری میشود؟ grep $FS /proc/filesystems #kernel_version=$( awk '{ print $3 }' /proc/version )CPU=$( awk '/model name/ {print $5}' < /proc/cpuinfo ) if [ "$CPU" = "Pentium(R)" ] then run_some_commands ... else run_other_commands ... fi cpu_speed=$( fgrep "cpu MHz" /proc/cpuinfo | awk '{print $4}' ) #سرعت عمل فعلی cpu روی ماشین شما(به MHz). در یک لپ تاپ #ممکن است موقع استفاده از باطری یا برق AC تغییر کند. #!/bin/bash # #به دست آوردن پارامترهای خط فرمان یک پردازش. OPTION=cmdline #شناسایی کردن PID. pid=$( echo $(pidof "$1") | awk '{ print $1 }' ) # echo echo "Process ID of (first instance of) "$1" = $pid" echo -n "Command-line arguments: " cat /proc/"$pid"/"$OPTION" | xargs -0 echo #خروجی را قالببندی میکند #(Han Holl برای این مرتب کردن متشکرم!) echo; echo #برای مثال: #+
devfile="/proc/bus/usb/devices" text="Spd" USB1="Spd=12" USB2="Spd=480" bus_speed=$(fgrep -m 1 "$text" $devfile | awk '{print $9}') # if [ "$bus_speed" = "$USB1" ] then echo "USB 1.1 port found." #انجام کاری متناسب برای USB 1.1 fi
حتی کنترل برخی دستگاههای جانبی با فرستادن فرمانها به شاخه /proc امکانپذیر است. root# echo on > /proc/acpi/ibm/lightاین دستور Thinklight را در بعضی مدلهای Thinkpad مارک IBM/Lenovo روشن میکند. (ممکن است در همه توزیعهای لینوکس کار نکند.)البته، هنگام نوشتن در /proc، احتیاط شرط عقل است.
شاخه /proc محتوی شاخههای فرعی با نامهای عددی غیرمعمولی است. هر یک از این نامها به ID پردازش یک پردازش در حال اجرا مربوط میشود. داخل هر کدام از این شاخههای فرعی تعدادی فایل وجود دارد که اطلاعات مفیدی در باره پردازش متناظر نگهداری میکنند. فایلهای stat و status آمار مربوط به پردازش در حال اجرا را نگهداری میکنند، فایل cmdline شناسههای خط فرمان را که پردازش با آنها فراخوانی گردیده حفظ میکند، و فایل exe یک پیوند نمادین به نام مسیر کامل فراخوانی پردازش است. چند فایل دیگر از این قبیل وجود دارد، اما به نظر میرسد از دیدگاه اسکریپتنویسی اینها جالبترین موارد هستند.
مثال 29-3. یافتن پردازش مرتبط با یک PID
#!/bin/bash # #نام مسیر کامل برای پردازش مرتبط با pid را به دست میآورد. ARGNO=1 #تعداد شناسههای مورد انتظار اسکریپت. E_WRONGARGS=65 E_BADPID=66 E_NOSUCHPROCESS=67 E_NOPERMISSION=68 PROCFILE=exe if [ $# -ne $ARGNO ] then echo "Usage: `basename $0` PID-number" >&2 # exit $E_WRONGARGS fi pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 ) #pid یعنی فیلد شماره 1 را در لیستگیری ps بررسی میکند. سپس #تضمین میکند پردازش واقعی باشد نه پردازش فراخوانی شده با #این اسکریپت، grep $1 انتهایی، این احتمال را فیلتر میکند. # # #نیز به طوری که Teemu Huovila اشاره نموده کار میکند. if [ -z "$pidno" ] #اگر بعد از فیلتر کردن، رشتهای با طول صفر نتیجه شود، then #+یعنی پردازشی با pid داده شده، در حال اجرا نیست. echo "No such process running." exit $E_NOSUCHPROCESS fi #به طور جایگزین: # # #پردازش متناظر pid مفروض در حال اجرا نیست. # # # #برای ساده کردن تمام فرایند از pidof استفاده کنید. if [ ! -r "/proc/$1/$PROCFILE" ] #کنترل مجوز خواندن. then echo "Process $1 running, but..." echo "Can't get read permission on /proc/$1/$PROCFILE." exit $E_NOPERMISSION #کاربر عادی به برخی از فایلها در /proc دسترسی ندارد. fi #دو تست انتهایی میتوانند با این مورد تعویض بشوند: # #0 یک سیگنال نیست، اما این تست میکند که #آیا ارسال یک سیگنال به پردازش مقدور است. #then echo "PID doesn't exist or you're not its owner" >&2 #exit $E_BADPID #fi exe_file=$( ls -l /proc/$1 | grep "exe" | awk '{ print $11 }' ) #یا exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' ) # #/proc/pid-number/exe یک پیوند نمادین به #+نام مسیر کامل فراخوانی پردازش است. if [ -e "$exe_file" ] #اگر /proc/pid-number/exe وجود دارد، then #+آنوقت پردازش متناظر آن موجود است. echo "Process #$1 invoked by $exe_file." else echo "No such process running." fi #این اسکریپت پیچیده *تقریباً* میتواند با یک سطر # #اما، این کار نخواهد کرد... #+زیرا فیلد پنجم ps برابر argv[0] پردازش است، #+نه مسیر فایل قابل اجرا. # #به هر حال یکی از موارد زیر کار میکند. # # #شرح و تفسیر اضافی نوشته Stephane Chazelas است. exit 0مثال 29-4. وضعیت اتصال آنلاین
#!/bin/bash #connect-stat.sh #توجه نمایید که این اسکریپت برای کار کردن با یک #+اتصال wireless شاید نیاز به ویرایش داشته باشد. PROCNAME=pppd # PROCFILENAME=status #فایلی که باید بررسی شود. NOTCONNECTED=85 INTERVAL=2 #روزآمد کردن در هر دوثانیه. pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME | awk '{ print $1 }' ) #پیدا کردن شماره پردازش pppd، برنامه کمکی ppp. #سطرهای پردازش تولید شده به وسیله خود جستجو، باید فیلتر بشوند. # #به هر حال، همانطور که Oleg Philon اشاره میکند، این رشته فرمان #+میتواند با استفاده از pidof به طور قابل ملاحظهای ساده بشود. # # #نتیجه اخلاقی: #+موقعی که رشته فرمان خیلی پیچیده میشود، یک راه میانبر پیدا کنید. if [ -z "$pidno" ] #اگر pid نیست، پس پردازش در حال اجرا نیست. then echo "Not connected." #exit $NOTCONNECTED else echo "Connected."; echo fi while [ true ] #حلقه بیپایان، اینجا اسکریپت میتواند بهینه شود. do if [ ! -e "/proc/$pidno/$PROCFILENAME" ] #در مدت زمانی که پردازش در حال اجرا است، فایل status وجود دارد. then echo "Disconnected." #exit $NOTCONNECTED fi netstat -s | grep "packets received" #تهیه برخی آمارهای اتصال. netstat -s | grep "packets delivered" sleep $INTERVAL echo; echo done exit 0 #به طوریکه معلوم است، این اسکریپت باید با Control-C خاتمه یابد. #تمرینها: #------------ #اسکریپت را طوری بهینه کنید که با زدن کلید q خارج بشود. #با روشهای دیگری اسکریپت را کاربر پسندتر کنید. #اسکریپت را برای کار کردن با اتصالهای wireless/DSL اصلاح کنید.
به طور کلی، نوشتن در فایلهای داخل /proc خطرناک است، چون این کار میتواند باعث خراب کردن سیستم فایل یا از کار افتادن ماشین بشود. یادداشتها
[1] | برخی فرمانهای سیستم، از قبیل procinfo، free، vmstat، lsdev، و uptime نیز این کار را انجام میدهند. |