本文为笔者曾经完成的操作系统作业,当时只道是寻常,如今毕业发现之前上学时做过那么多有趣的实验和作业,准备后续一并整理一下,纪念那段青春岁月的同时,也希望能给大家带来一些收获和帮助。下面我们一起来看下如何通过一段简短的shell程序实现进程的查看与杀死~
问题描述:
用户输入一个数字,能够给出系统中以该数字为pid的进程详情,将详情输出到文件output.txt中。
要求:
(1)使用 ps aux 命令得到进程的详细信息;
(2)如果没有以该数字为pid的进程,程序会提示“The process does not exist!”,并再次开始循环,让用户再次输入直到以输入的数字为pid的进程存在为止;
(3)有一个菜单提供给用户输入;
(4)包含kill一个进程的功能。
1. 设计思路
程序主要分为4个部分:函数show_details
输出用户指定进程的详细信息,函数kill_process
杀死用户指定的进程,函数menu
把选择菜单打印在屏幕上,主函数调用上述3个函数。
在show_details
函数中,最外层为循环语句。在循环语句中,首先使用read命令读取用户输入的数字,赋值给变量$pid1
,用flag=$(ps --no-heading $pid1| wc -l)
判断进程是否存在,若存在,flag
返回值为1,不存在返回值为0。若flag
值为0,则一直循环让用户再次输入;若flag
值为1,使用ps aux | awk -v n=$pid1 'NR==1 || $2==n{print}' > output
命令将进程的详细信息输出到文件output.txt中。
在kill_process
函数中,首先用ps aux
命令列出全部进程供用户查看,以便用户选择想要杀死的进程。然后使用read
命令读取用户输入的数字,赋值给变量$pid2
,使用kill -9 $pid2
杀死进程。
在menu
函数中,主要使用echo
语句输出菜单选项。因为菜单选项为0或1或2,均为一个字符,故使用read -n 1 option
命令读取用户输入的第一个字符作为用户的选择,赋值给变量option
。无须按回车,即开始执行下一条语句。
在主函数中,使用循环语句和case
语句完成菜单显示和用户选择。在循环中首先调用menu
函数输出菜单,然后进入case
语句:输入0代表退出,跳出循环;输入1代表得到进程的详细信息,调用函数show_details
;输入2代表杀死进程,调用函数kill_process
;其他输入均提示“Wrong option”。case
语句结束后,使用 read -n 1 line
实现了按任意键继续,从显示菜单开始循环的功能。
2. 参考代码
最终实现的shell程序get_process.sh
代码如下:
#! /bin/bash
#输出用户指定进程详细信息的函数
function show_details {
while [ 1 ]
do
echo -en "\n\tPlease enter a pid:"
#使用read命令读取用户输入的数字,赋值给变量pid1
read pid1
#用flag判断以pid1为pid的进程是否存在:存在则返回1;否则,返回0
flag=$(ps --no-heading $pid1| wc -l)
#当进程存在时:
if [ 1 == $flag ]
then
#使用ps aux命令获取进程的详细信息,输出到文件output.txt中
ps aux | awk -v n=$pid1 'NR==1 || $2==n{print}' > output
echo -e "\n\tThe details of the process is shown in output.txt"
#终止循环
break
#当进程不存在时:
else
#提示信息输入的进程pid不存在,再次从头循环
echo -e "\n\tThe process does not exist!\n"
fi
done
}
#杀死用户指定进程的函数
function kill_process {
#首先列出全部进程供用户查看,以便选择想杀死的进程
ps -aux
echo -e "\n\tAbove are details of all processes."
echo -en "\tPlease enter a pid:"
#使用read命令读取用户输入的数字,赋值给变量pid2
read pid2
kill -9 $pid2
}
#生成选择菜单的函数
function menu {
clear
echo
echo -e "\t\tMENU\n"
echo -e "\t1.Get detail of a process"
echo -e "\t2.Kill a process"
echo -e "\t0.Exit\n\n"
echo -en "\tEnter a number to stand for your option:"
#使用read -n 1 命令读取用户输入的第一个字符作为用户的选择,赋值给变量option
read -n 1 option
}
#主函数
while [ 1 ]
do
#首先显示菜单
menu
#然后用户开始选择
case $option in
#输入0,退出
0)
break ;;
#输入1,调用输出进程详细信息的函数
1)
show_details ;;
#输入2,调用杀死进程的函数
2)
kill_process ;;
#其他输入均提示用户输入错误
*)
clear
echo "Wrong option" ;;
esac
#按任意键继续,从头开始循环
echo -en "\n\n\tHit any key to continue..."
read -n 1 line
done
clear
3. 运行结果
3.1 开始菜单界面
按下回车键后显示菜单供用户选择,如下图:
3.2 检验得到进程详细信息的功能
-
系统中存在以输入数字为pid的进程:
输入1,会提示信息“Please enter a pid:”。然后输入2,按下回车,提示信息“The details of the process is shown in output.txt”。在“文件”中找到output.txt,打开可见pid为2的进程的详细信息,结果如下图。
-
系统中不存在以输入数字为pid的进程:
按任意键继续,重新回到菜单选择界面。输入1,在提示信息“Please enter a pid:”后输入100,按下回车,提示信息“The process does not exist!”,再次要求用户“Please enter a pid:”,结果如下图。
3.3 检验杀死进程的功能
在菜单选择界面输入2,程序输出系统中所有进程的详细信息,并提示信息“Above are details of all processes. Please enter a pid:”。然后输入2506,结果如下图。
3.4 检验对选择错误的处理
在菜单选择界面,如果输入了菜单中没有的选项,结果如下图。
3.5 检验退出的功能
在菜单选择界面,输入0,则程序终止,结果如下图。