linux终止超时的进程

目前服务器数据接口调用的地方较多,虽然将超时控制的很好了,但依然还是有超时的脚本占了进程,由于作了-eq这样的判断进程数的方法,超时进程的导致无法开启新进程,根据进程的执行时间可以判断是否为超时进程,并kill掉即可解决问题。

shell:

#!/bin/bash
function show_elapsed_time()
{
    user_hz=$(getconf CLK_TCK) #mostly it's 100 on x86/x86_64
    pid=$1
    jiffies=$(cat /proc/$pid/stat | cut -d" " -f22)
    sys_uptime=$(cat /proc/uptime | cut -d" " -f1)
    last_time=$(( ${sys_uptime%.*} - $jiffies/$user_hz ))
    #echo "the process $pid lasts for $last_time seconds."
    time_out=1800 #限制为 30 分钟
    if [ "$last_time" -ge "$time_out" ]
    then
        echo "the process $pid lasts for $last_time seconds."
        kill -9 $pid
    fi
}
#pgrep php 用于返回进程名包含 php 字符的进程ID列表
for pid in `pgrep php`
do
    #echo 'It is '$pid  
    show_elapsed_time $pid

done

//匹配筛选

#!/bin/bash
function show_elapsed_time()
{
    user_hz=$(getconf CLK_TCK) #mostly it's 100 on x86/x86_64
    pid=$1
    jiffies=$(cat /proc/$pid/stat | cut -d" " -f22)
    sys_uptime=$(cat /proc/uptime | cut -d" " -f1)
    last_time=$(( ${sys_uptime%.*} - $jiffies/$user_hz ))
    #echo "the process $pid lasts for $last_time seconds."
    time_out=180
    if [ "$last_time" -ge "$time_out" ]
    then
        echo "the process $pid lasts for $last_time seconds."
        kill -9 $pid
    fi
}

#for pid in `pgrep php`
for pid in `ps -ef| grep a.php | awk '{print $2}'`
do
    echo 'It is '$pid  
    show_elapsed_time $pid

done

扩展阅读:
Linux bash shell 逐行读取文本文件的三种方法

方法一,指定换行符读取:

#! /bin/bash  
   
IFS="  
"  
   
for LINE in `cat /etc/passwd`  
do  
        echo $LINE 
done

方法二,文件重定向给read处理:

#! /bin/bash  
   
cat /etc/passwd | while read LINE  
do
        echo $LINE 
done

方法三,用read读取文件重定向:

#! /bin/bash  
   
while read LINE
do
        echo $LINE 
done < /etc/passwd

Linux获取进程已经运行的时间
本来,ps本身也提供了选项来查询的,但是比较直观和形象(如 10:32这样的),不是用seconds为单位,并不方便在脚本中直接使用。ps中的关于进程时间的命令如下:

[root@AY140122175316610bdcZ shell]# ps -p 4260 -o pid,start_time,etime,comm
  PID START     ELAPSED COMMAND
 4260 Apr18 16-08:57:25 gnome-session

其中第三列的16-08:57:25就是进程运行的时间,为:16天8小时57分25秒。
根据一些/proc文件系统中的信息,查询进程运行时间脚本分享如下:

#!/bin/bash
function show_elapsed_time()
{
	user_hz=$(getconf CLK_TCK) #mostly it's 100 on x86/x86_64
	pid=$1
	jiffies=$(cat /proc/$pid/stat | cut -d" " -f22)
	sys_uptime=$(cat /proc/uptime | cut -d" " -f1)
	last_time=$(( ${sys_uptime%.*} - $jiffies/$user_hz ))
	echo "the process $pid lasts for $last_time seconds."
}
 
if [ $# -ge 1 ];then
	for pid in $@
	do
		show_elapsed_time $pid
	done
fi
 
while read pid
do
	show_elapsed_time $pid
done

执行过程和结果如下:

[root@AY140122175316610bdcZ shell]# ./get_process_time.sh 4260
the process #4260 lasts for 1415417 seconds.

linux根据进程名查询PID值

很多时候,我们都需要根据进程名查询进程PID值,笔者总结了多种方法解决:
1、pidof命令
用pidof指令很轻易的找到您所想要的程序内容
范例二:仅列出关于 root 的所有程序开启的 socket 档案

[root@AY140122175316610bdcZ shell]# lsof -u root -a -U
COMMAND     PID USER   FD   TYPE     DEVICE SIZE   NODE NAME
kmodule     793 root    4u  unix 0xd744b700        3549 socket
udevd       801 root    5u  unix 0xd744bb40        3561 socket
syslogd    1539 root    0u  unix 0xd75946e0        4870 /dev/log

# 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
# 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!
# -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^

范例三:请列出目前系统上面所有的被启动的周边设备

[root@AY140122175316610bdcZ shell]# lsof +d /dev
COMMAND     PID    USER   FD   TYPE     DEVICE SIZE NODE NAME
init          1    root   10u  FIFO       0,13      1834 /dev/initctl
kmodule     793    root    2u   CHR        1,3      2135 /dev/null
kmodule     793    root    3u   CHR        5,1      2134 /dev/console
udevd       801    root    2u   CHR        1,3      2135 /dev/null
syslogd    1539    root    0u  unix 0xd75946e0      4870 /dev/log xinetd     1589    root    1r   CHR        1,3      2135 /dev/null

#看吧!因为设备都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
范例四:秀出属于 root 的 bash 这支程序所开启的档案

[root@AY140122175316610bdcZ shell]# lsof -u root | grep bash
bash   26199 root  cwd   DIR   3,2   4096   159875 /root
bash   26199 root  rtd   DIR   3,1   4096        2 /
bash   26199 root  txt   REG   3,1 686520   294425 /bin/bash
bash   26199 root  mem   REG   3,1  83160    32932 /usr/lib/gconv/BIG5.so
bash   26199 root  mem   REG   3,1  46552   915764 /lib/libnss_files-2.3.5.so
#.....底下的数据就省略不写了.....

这个指令可以找出您想要知道的某个程序是否有启用哪些信息? 例如上头提到的范例四的执行结果呢!

[root@AY140122175316610bdcZ shell]# pidof [-sx] program_name

参数:
-s :仅列出一个 PID 而不列出所有的 PID
-x :同时列出该 program name 可能的 PPID 那个程序的 PID
范例:
范例一:列出目前系统上面 init 以及 syslogd 这两个程序的 PID

[root@AY140122175316610bdcZ shell]# pidof init syslogd

1 2546
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。
# 分别是 init 及 syslogd 这两支程序的 PID 啦。

范例二:找出 bash 即以 bash 为 PPID 的几个主要的 PID

[root@AY140122175316610bdcZ shell]# pidof -x bash
2961 2959 338

# 因为我的系统被我登入之后,我就会主动取得一个 bash 的程序,所以啰,
# 很自然就会拥有一个 PID 啊。只要我再以底下的方式,就可以取得我所想要的 PID 内容。

[root@AY140122175316610bdcZ shell]# ps aux | egrep '(2961|2959|338)'
dmtsai   338  0.0  0.1  6024 1536 pts/0    Ss   16:43   0:00 -bash
kiki    2961  0.0  0.1  6025 1526 pts/0    Ss   17:43   0:00 -bash
#.....以下省略......

很简单的用法吧,讲解的这个pidof 指令,并且配合 ps aux 与正规表示法, 就可以很轻易的找到您所想要的程序内容了呢。

2、pgrep命令
语 法

pgrep [必要参数] [选择参数]  [程序]      功 能   pgrep 命令:可以依照进程ID来浏览程序
类似命令: ps  kill  grep  killall  less  top   
  
参数必要参数
-f 显示完整程序
-l 显示源代码
-n 显示新程序
-o 显示旧程序
-v 与条件不符合的程序
-x 与条件符合的程序

选择参数
-p<进程号> 列出父进程为用户指定进程的进程信息
-t<终端> 指定终端下的所有程序
-u<用户> 指定用户的程序

范例

范例1:显示指定终端相联系的程序

[root@AY140122175316610bdcZ shell]# pgrep -t tty2
862
8236
8672
[root@AY140122175316610bdcZ shell]#

范例2:显示与某字符串相关的命令

[root@AY140122175316610bdcZ shell]# pgrep at //列出at字符串相关的程序
3
5
19
20
42
[root@AY140122175316610bdcZ shell]#

范例3:列出父进程为init进程的所有进程

[root@AY140122175316610bdcZ shell]# pgrep -P 1 //列出父进程为1的所有进程
314
317
672
[root@AY140122175316610bdcZ shell]#

范例4: 反向选择

[root@AY140122175316610bdcZ shell]# pgrep -v -P 1 //列出父进程不为1的进程
1
2
3
[root@AY140122175316610bdcZ shell]#

范例5:显示指定用户进程

[root@AY140122175316610bdcZ shell]# pgrep -u root
1
2
3
#显示结果省略

3、ps命令
查找进程httpd的PID:

ps -ef | grep "httpd" | grep -v "grep" | awk '{print $2}'