29.2. /proc. Comtrol DeviceMaster Software Development Kit
Reklama
Reklama
Advanced Bash-Scripting Guide echo -n "$g$e2$d$c$d$c$a$g$n$g$e$n$g$e2$d$c$c$b$c$cis$n$cis$d \
$n$g$e2$d$c$d$c$a$g$n$g$e$n$g$a$d$c$b$a$b$c" > /dev/dsp
# dsp = Digital Signal Processor exit # A "bonny" example of an elegant shell script!
29.2.
/proc
The
/proc
directory is actually a pseudo-filesystem. The files in
/proc
mirror currently running system and
kernel processes and contain information and statistics about them.
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
...
Chapter 29. /dev and /proc 463
Advanced Bash-Scripting Guide 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
Shell scripts may extract data from certain of the files in
/proc
. [121]
FS=iso # ISO filesystem support in kernel?
grep $FS /proc/filesystems # iso9660 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}' )
# Current operating speed (in MHz) of the cpu on your machine.
# On a laptop this may vary, depending on use of battery
#+ or AC power.
Chapter 29. /dev and /proc 464
Advanced Bash-Scripting Guide
#!/bin/bash
# get-commandline.sh
# Get the command-line parameters of a process.
OPTION=cmdline
# Identify PID.
pid=$( echo $(pidof "$1") | awk '{ print $1 }' )
# Get only first ^^^^^^^^^^^^^^^^^^ of multiple instances.
echo echo "Process ID of (first instance of) "$1" = $pid" echo -n "Command-line arguments: " cat /proc/"$pid"/"$OPTION" | xargs -0 echo
# Formats output: ^^^^^^^^^^^^^^^
# (Thanks, Han Holl, for the fixup!) echo; echo
# For example:
# sh get-commandline.sh xterm
+ devfile="/proc/bus/usb/devices" text="Spd"
USB1="Spd=12"
USB2="Spd=480" bus_speed=$(fgrep -m 1 "$text" $devfile | awk '{print $9}')
# ^^^^ Stop after first match.
if [ "$bus_speed" = "$USB1" ] then
echo "USB 1.1 port found."
# Do something appropriate for USB 1.1.
fi
It is even possible to control certain peripherals with commands sent to the
/proc
directory.
root#
echo on > /proc/acpi/ibm/light
This turns on the Thinklight in certain models of IBM/Lenovo Thinkpads. (May not work on all Linux distros.)
Of course, caution is advised when writing to
/proc
.
The
/proc
directory contains subdirectories with unusual numerical names. Every one of these names maps
files that hold useful information about the corresponding process. The
stat
and
status
files keep running statistics on the process, the
cmdline
file holds the command-line arguments the process was invoked with, and the
exe
file is a symbolic link to the complete path name of the invoking process. There are a few more such files, but these seem to be the most interesting from a scripting standpoint.
Example 29-3. Finding the process associated with a PID
Chapter 29. /dev and /proc 465
Advanced Bash-Scripting Guide
#!/bin/bash
# pid-identifier.sh:
# Gives complete path name to process associated with pid.
ARGNO=1 # Number of arguments the script expects.
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 # Error message >stderr.
exit $E_WRONGARGS fi pidno=$( ps ax | grep $1 | awk '{ print $1 }' | grep $1 )
# Checks for pid in "ps" listing, field #1.
# Then makes sure it is the actual process, not the process invoked by this script.
# The last "grep $1" filters out this possibility.
#
# pidno=$( ps ax | awk '{ print $1 }' | grep $1 )
# also works, as Teemu Huovila, points out.
if [ -z "$pidno" ] # If, after all the filtering, the result is a zero-length string, then #+ no running process corresponds to the pid given.
echo "No such process running."
exit $E_NOSUCHPROCESS fi
# Alternatively:
# if ! ps $1 > /dev/null 2>&1
# then # no running process corresponds to the pid given.
# echo "No such process running."
# exit $E_NOSUCHPROCESS
# fi
# To simplify the entire process, use "pidof".
if [ ! -r "/proc/$1/$PROCFILE" ] # Check for read permission.
then
echo "Process $1 running, but..."
echo "Can't get read permission on /proc/$1/$PROCFILE."
exit $E_NOPERMISSION # Ordinary user can't access some files in /proc.
fi
# The last two tests may be replaced by:
# if ! kill -0 $1 > /dev/null 2>&1 # '0' is not a signal, but
# this will test whether it is possible
# to send a signal to the process.
# 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 }' )
# Or exe_file=$( ls -l /proc/$1/exe | awk '{print $11}' )
#
# /proc/pid-number/exe is a symbolic link
Chapter 29. /dev and /proc 466
Advanced Bash-Scripting Guide
#+ to the complete path name of the invoking process.
if [ -e "$exe_file" ] # If /proc/pid-number/exe exists, then #+ then the corresponding process exists.
echo "Process #$1 invoked by $exe_file." else
echo "No such process running." fi
# This elaborate script can *almost* be replaced by
# ps ax | grep $1 | awk '{ print $5 }'
# However, this will not work...
#+ because the fifth field of 'ps' is argv[0] of the process,
#+ not the executable file path.
#
# However, either of the following would work.
# find /proc/$1/exe -printf '%l\n'
# lsof -aFn -p $1 -d txt | sed -ne 's/^n//p'
# Additional commentary by Stephane Chazelas.
exit 0
Example 29-4. On-line connect status
#!/bin/bash
# connect-stat.sh
# Note that this script may need modification
#+ to work with a wireless connection.
PROCNAME=pppd # ppp daemon
PROCFILENAME=status # Where to look.
NOTCONNECTED=85
INTERVAL=2 # Update every 2 seconds.
pidno=$( ps ax | grep -v "ps ax" | grep -v grep | grep $PROCNAME | awk '{ print $1 }' )
# Finding the process number of 'pppd', the 'ppp daemon'.
# Have to filter out the process lines generated by the search itself.
#
# However, as Oleg Philon points out,
#+ this could have been considerably simplified by using "pidof".
# pidno=$( pidof $PROCNAME )
#
# Moral of the story:
#+ When a command sequence gets too complex, look for a shortcut.
if [ -z "$pidno" ] # If no pid, then process is not running.
then
echo "Not connected."
# exit $NOTCONNECTED else
echo "Connected."; echo fi while [ true ] # Endless loop, script can be improved here.
do
Chapter 29. /dev and /proc 467
Advanced Bash-Scripting Guide
if [ ! -e "/proc/$pidno/$PROCFILENAME" ]
# While process running, then "status" file exists.
then
echo "Disconnected."
# exit $NOTCONNECTED
fi netstat -s | grep "packets received" # Get some connect statistics.
netstat -s | grep "packets delivered"
sleep $INTERVAL
echo; echo done exit 0
# As it stands, this script must be terminated with a Control-C.
# Exercises:
# ---------
# Improve the script so it exits on a "q" keystroke.
# Make the script more user-friendly in other ways.
# Fix the script to work with wireless/DSL connections.
In general, it is dangerous to write to the files in
/proc
, as this can corrupt the filesystem or crash the machine.
Chapter 29. /dev and /proc 468
Pobierz
Reklama