第6章Linux进程
6.1 及第24章
Shell编程
LINUX启动
选择shell
? /etc/shells文件中列出了系统可以运行的shell的列
表
?/bin目录下有shell的执行程序
? /etc/passwd文件列出了每个用户的登录shell
改变shell
? #chsh –s /bin/ash
? #chsh –s /bin/bash
? #chsh –s /bin/csh
Bash的配置文件
?在用户登录时,Bash初始化的配置文件:
– /home/wangke/.bash_profile
?在每次进入Bash或生成subshell时执行的配置文
件:
– / home/wangke/.bashrc
– /home/wangke/ .bash_login
?在退出Bash时执行的配置文件:
– / home/wangke/.bashrc
Shell程序设计
?Shell的两层含义:
–指由Shell命令组成的Shell命令语言
–指该命令语言的解释程序
?流行的Shell:
– Bourne shell(UNIX System V使用,提示符$,程序
名是sh)
–C shell(BSD UNIX使用,提示符%,程序名是csh)
–Korn shell(结合了上面两者的优点)
– Bash(GNU Linux缺省Shell)
Shell程序设计
?Shell程序设计语言
–可以定义变量、关键字
–有各种控制结构:
?顺序结构
?分支结构if case
?循环结构while for until
–有语法结构
–可灵活地利用位置参数传递参数值
? UNIX/Linux程序员常常利用Shell语言,把
UNIX/Linux命令组合在一起,编写出功能很强但
代码简单的程序。
Shell程序的编写与运行
?一个最简单的Shell程序例子:
$cat file1
# count files in current directory
ls -l | wc –l
$
说明:用任何纯文本编辑器均可,建议文件名加.sh表明这是一个Shell程序文件。
?程序运行方法(4种)
第一种:$bash file1
第二种:$bash < file1
第三种:$chmod a+x file1
$./file1
第四种:$. file1
Shell程序设计
?Shell程序设计语言的变量
–环境变量
–位置参数变量
–用户自定义变量
环境变量
?与系统的工作环境有关的专用变量:
man 指令的搜寻路径
$MANPATH
每隔多少秒检查是否有新的信件
$MAILCHECK
时区
$TZ
执行上一个指令的返回值
$?
执行上一个背景指令的PID
$!
命令行参数个数
$#
Shell的所有参数
$*
Shell的PID
$$
辅助提示符,在命令结束前遇到换行时,在续行中使用的提示符,系统默认为“>”.如
$echo “first <CR>
> second”
$PS2
主提示符,表示shell等待输入命令。在特权用户下,主提示符默认为“#”
$PS1
终端类型
$TERM
存放用户邮件的邮箱文件名
$MAIL
执行命令时所搜寻的目录
$PATH
用户注册后的当前目录,cd命令的缺省参数,每个用户具有不同值
$HOME
查看环境变量
? #printenv
临时设置环境变量
? #env PATH=&PATH:/usr/wangk
位置参数变量
?Shel程序的命令参数由分割符分开,被从左到右依次赋
给位置参数$0, $1, $2……第一个命令参数为$1,第二个
命令参数为$2,……依次类推。$0表示命令名(shell程
序名)。
?示例程序
$cat postfile
echo The first: $1
echo The second: $2
echo The third: $3
echo The fourth: $4
echo The program name: $0
$
?执行过程及结果
$sh postfile first second third fourth
The first: first
The second: second
The third: third
The fourth: fourth
The program name: postfile
$
Shell程序的shift命令
?Shel程序的位置参数只能使用$1——$9,但Shell程序的
命令行中允许使用128个命令参数。这时就必须使用
shift命令来存取$9以上的参数。
?示例程序
$cat file.shift
echo Before shift, the parameters: $0,$1,$2,$3,$4,$5,$6,$7,$8,$9
echo No of parameters: $#
shift
echo After shift,the parameters: $0,$1,$2,$3,$4,$5,$6,$7,$8,$9
echo No of parameters: $#
$
Shell程序的shift语句
?执行过程及结果
$file.shift 1 2 3 4 5 6 7 8 9
Before shift, the parameters: file.shift,1,2,3,4,5,6,7,8,9
No of parameters: 9
After shift,the parameters: file.shift,2,3,4,5,6,7,8,9
echo No of parameters: 8
$
?shift命令重新命名所有的位置参数变量:$2成为
$1,$3成为$2等。每使用一次shift,都使所有的
位置参数依次向左移动一个位置,并使位置参数
的数量减1,直至减为0。$0不受Shift命令的影响。
用户自定义变量
?用户自定义变量语法:
定义方法:变量名=string
–变量名由字母或下划线打头,由字母、下划线、数字组成。
–=表示赋值运算符,两边不能有空格
引用方法:$变量名
?示例程序
$cat file
TIME=“Data and time: \c”
USERS=“No of users: \c”
HOST=“Personal stat: \c”
echo $TIME
date
echo $USERS
who | wc –l
echo $HOST
whoami
$
?执行过程及结果
$file
Data and time: mon Dec 16:00:00 CST
2003
No of users: 3
Personal stat: Wang Ke tty 01 Dec 15
08:00
wangk
$
Shell程序结构程序结构
如何指定使用哪一个Shell 来解释所写的Script呢?几种
基本的指定方式如下所述:
1. 如果Script的第一个非空白字符不是"#",则它会使用
Bourne Shell。
2. 如果Script的第一个非空白字符是"#"时,但不以"#!"开
头时,则它会使用C Shell。
3. 如果Script以“#!”开头,则“#!”後面所写的就是所使用
的Shell,而且要将整个路径名称指出来。例如:
#! /bin/bash
Shell程序结构程序结构
Script是以行为单位,Script会分解成一行一行来执行。
而每一行可以是命令、注解、或是流程控制指令等。如
果某一行尚未完成,可以在行末加上“\”,这个时候下一
行的内容就会接到这一行的後面,成为同一行。
当Script中出现“#”时,再它後面的同一行文字即为注解,
Shell 不会对其翻译。
Shell程序结构
?分支结构 ?循环结构
if 命令1
…
…
命令m
then 命令1
…
…
命令n
else 命令1
…
…
命令n
fi
for 变量名
[in 数值列表]
do
命令1
命令2
…
命令n
done
while
命令1
…
命令m
do
命令1
命令2
…
命令n
done
?if语句示例程序
$cat seekword
echo type a word and file name
read WORD FILE //读入参数值,相当于scanf
if grep $WORD $FILE //从文件$FILE 中查找字符串$WORD
then
echo the $WORD is a word of the $FILE
fi
$
?if语句示例程序
$cat username
# check the passwd file for login
NAME = ${1 – root} //给出缺省的位置参数:$1的值缺省为root
NULLNAME = /dev/null //用户自定义变量:/dev/null是系统的空文件
if grep $NAME /etc/passwd > $NULLNAME
then
echo $NAME is a passwd file
elif grep $NAME /etc/group > $NULLNAME
then
echo $NAME is a group file.
else
echo the $NAME is not a passwd file name either or a group file.
fi
$
?执行过程及结果
$username
root is a passwd file
$username wangk
wangk is a passwd file
$
?While循环示例程序
$cat md
# put a list of name into file
echo “type in each person’s name the a <CR>”
echo “type the list of name with <Ctrl-D>”
while
read name
do
echo $name >> namefile
done
echo namefile contains the follow names:
cat namefile
$
说明:因为< >是输入输出重定向符号,要把它们变成普通字符,
echo 语句必须加“”
?for循环示例程序
$cat movefile.file
# move file to another directory.
echo type a path
read DESTIPATH
for VARFILE
in file1 file2 file3
do
mv $VARFILE $DESTIPATH/$VARFILE
done
$
For语句的工作过程:
?如果命令中含有in 列表,则用in之后的数值顺序替换循环体列表中的“$
变量名”;
?如果for语句中省略了in列表,则用位置参数来替换循环体列表中的“$
变量名”;
?对每一个数值都执行do…done之间的命令列表。
6.2 Linux进程
? 6.2.1 进程
? 6.2.2 多进程
? 6.2.3 运行后台进程(& nohup cron crontab anacron
at atq atrm batch)
? 6.2.4 启动多个进程(at batch)
? 6.2.5 进程的控制(ps)
? 6.2.6 用户退出后继续运行的进程(nohup)
? 6.2.7 调整进程优先级(& nice renice)
? 6.2.8 终止进程(kill)
6.2.3 运行后台进程
?概念:前台后台
?运行后台进程的方法
–命令行末尾添加“&”符号
– nohup命令
–cron命令
– crontab命令
–anacron命令
–at命令(atq atrm命令)
– batch命令
Linux进程的状态
32
16
8
4
2
1
0
值
僵死态,表示进程结束但尚未消亡的一种状态。此时,进程已
经结束运行且释放大部分资源,但尚未释放PCB
TASK _ZOMBIE
不可中断等待态。处于等待队列中的进程,待资源有效时唤醒,
不可由其它进程通过信号(Signal)或定时中断唤醒后进入就绪队
列
TASK
_UNINTERRUPTABLE
说明进程状态
运行态。实际包含了执行态和就绪态两种状态
TASK_RUNNING
可中断等待态。处于等待队列中的进程,待资源有效时唤醒,
也可由其它进程通过信号(Signal)或定时中断唤醒后进入就绪队
列
TASK
_INTERRUPTABLE
独占态。处于独占态的进程位于等待队列中。如果有一组进程
都在等待某一事件,一旦事件发生,只有处于独占态的进程被
唤醒,其它处于可中断态和不可中断态的进程则继续等待。
TASK_EXCLUSIVE
交换态。页面被交换出内存的进程。2.4.X版本中已无此状态。
TASK_SWAPPING
暂停态,进程需要通过其它进程的信号才能唤醒。导致这种状
态的原因有二:或者是对收到SIGSTOP、SIGSTP、SIGTTIN、
SIGTTOU信号的反应;或者是受其它进程的ptrace系统调用而
暂时将CPU交给跟踪它的进程。比如处于调试跟踪的进程,每
执行到一个断点,就转入暂停态,等待新的输入信号。
TASK _STOPPED
Linux进程的标志(Flag)
进程被信号杀出
PF_SIGNALED
进程正被创建
PF_STARTING
进程开始关闭
PF_EXITING
该进程使用FPU(用于SMP)
PF_USEDFPU
Delayed trace(用于M68K)
PF_DTRACE
进程刚创建,但还没执行
PF_FORKNOEXEC
正在跟踪
PF_TRACESYS
说明进程标志
打印“对齐”警告信息
PF_ALIGNWARN
被ptrace系统调用跟踪
PF_PTRACED
Dumped core
PF_DUMPCORE
超级用户特权
PF_SUPERPRIV
Linux进程的状态转换
Lin
ux
的
软
中
断
信
号
ps命令
Ordered by real user ID
-U
Only running process
-r
Ordered by process ID
-p
full
-f
All except session leaders
-d
All processes
-A
All w/ tty except session leaders
-a
Ordered by command name
-C
All processes on this terminal
-T
Job control
-j
Ordered by real group ID
-G
? #ps --help
ps命令
进程睡眠,或处于SXBRK 状态的事件的地址(如果为空,则进程正在运行)
WCHAN
进程的控制终端
TTY
进程的累计执行时间
TIME
虚拟内存的大小
SZ
进程的内存地址
ADDR
命令名(在–f 选项下显示命令名及其参数)
CMD
父进程的PID
PPID
进程的ID
PID
与进程有关的标志
F
进程的状态
S
进程所有者的用户ID(在–f 选项下显示注册名)
UID
Nice值,用于优先级的计算
NI
进程的优先级
PRI
CPU的利用率
C
调整进程优先级
?在启动进程时指定优先级nice
?在进程运行时调整优先级renice
nice命令
?(优先)数值越大,优先权越低。
?除了root,其它用户只能自我降低优先权。
显示帮助信息
--help
在原有(优先)数值上+n
-n
显示版本号
--version
renice命令
? renice priority [[-p]pids] [[-g]pgrps] [[-u]users]
?除了root,其它用户只能自我降低优先权。
标志后面是进程组号,即按进程组好来改变进程的优先级
-g
标志后面是进程号,即按进程号来改变进程的优先级
-p
标志后面是用户名,即按用户名来改变进程的优先级
-u
kill命令
? kill [-s signal | -p] [-a] pid
? Kill –l [signal]
-l
PID
-p
-s
-9
nohup命令
?运行命令不受挂起和退出的影响。如果用户未用输出改
向,则标准输出和标准错误输出都被送到nohup.out。如
果当前目录中的nohup.out不可写,则输出改向到
$HOME/nohup.out
?可以将多个命令放入shell文件中,以实现后台运行多个命
令
#nohup sh file1
? P.125 #nohup dir > lsecho &
-l
PID
-p
-s
-9
配置cron
?cron可以定时地、周期地执行程序
? crond是cron的守护进程
?cron的主配置文件是/etc/crontab 文件
?cron的执行任务必须以crontab格式在一个文本文件中描述,该文
件通常由crontab命令生成
?用户定义的crontab被保存在/var/spool/cron/$USER文件中
? crond每分钟都去检查/etc/crontab文件、/etc/cron.d目录、
/var/spool/cron目录中的任何改变
?控制文件(/etc/cron.allow和/etc/cron.deny)被用来限制用户对cron
的使用。如果/etc/cron.allow文件存在,仅允许这个文件里列出的
用户使用cron。如果/etc/cron.deny这个文件存在,该文件列出的
用户都不能使用cron服务。当这个文件为空时,任何用户都可以
使用cron,这是默认配置。
?当运行cron时,先检查/etc/cron.allow文件是否存在,如果不存在,
再检查/etc/cron.deny文件是否存在。
crontab命令
? #crontab [-u user] file
? #crontab [-u user] file {-e | -l | -r}
Delete user’s crontab
-r
用指定的文件替代当前的crontab
file
Edit usr’s crontab
-e
Minute Hour Day Month Dayofweek Command
文件格式
List user’s crontab
-l
? #gedit crontest
0 8 * * * date>crontest
? #crontab crontest
at命令
?可以在shell提示符下输入at time
?可以在shell提示符下输入at –f script
?控制文件(/etc/at.allow和/etc/at.deny)被用来限制用户对at的使用。
如果/etc/at.allow文件存在,仅允许这个文件里列出的用户使用at。
如果/etc/at.deny这个文件存在,该文件列出的用户都不能使用at
服务。当这个文件为空时,任何用户都可以使用at,这是默认配
置。
?当运行at命令时,先检查/etc/at.allow文件是否存在,如果不存在,
再检查/etc/at.deny文件是否存在。不管这两个文件是不是存在,
root用户都可以执行at命令
at命令
? #at [-V] [-q x] [-f script] [-m] time [-l]
打印版本号
-V
指定可选队列的名称。队列可以是a-z或A-Z之间的任意字母。C队列是at的
默认值,而E队列是batch的默认值。队列的字母位置越高,运行CPU时间的
优先权越低。
-q
从队列中取消指定编号的作业
-r
作业完成后,即使没有输出,也将邮件送到用户
-m
从名为script的文件中读取要执行的作业任务,而不是从标准输入读取-f script
作业开始的时间。格式包括3个部分:时间、日期、增值。At可接受的时间
形式是HHMM或HH:MM,在时间后可加AM或PM,并在一天中指定的时间
运行作业;如果时间过去了,就在第二天执行。日期的格式为MMDDYY或
MM/DD/YY或DD.MM.YY。还可以这样给出时间:now+若干时间单位(可
以是分钟、小时、天、星期;还可以加today、tomorrow。
time
列出现在安排的作业,若是超级用户则列出所有作业
-l