我有时会遇到这样的情况:由于某些原因(第一个实例未完全完成,同一进程的第二个实例启动),保存在 Cron 中的脚本/命令运行多次,并且在某个时间点这些进程会增加很多并显示系统挂起等。所以,我想要作为一种临时解决方案是检查是否有多个脚本/命令实例,例如,
ps -ef | pgrep -f 'DELETE OPERATION_CONTEXT'
或者直接杀掉该命令的所有进程
ps -ef | pkill -f 'DELETE OPERATION_CONTEXT'
但我想知道如何杀死除第一个进程之外的 pgrepped 命令的所有进程(这将使其中一个进程继续工作,并杀死所有其他重复进程)。
答案1
下面是 apache2 进程的示例,它将杀死除第一个进程之外的所有 PID
pgrep apache2 |awk 'NR >= 2' | xargs -n1 echo kill
如果上述命令的输出看起来不错,那么您可以删除echo
答案2
你可以试试这个:
ps -e --sort=start -o start,pid,cmd|grep <cmd>|egrep -v grep |sed 1d
这将为您提供以下格式化输出:
开始时间、PID、正在执行的命令
for i in `ps -e --sort=start -o start,pid,cmd|grep <cmd>|egrep -v grep |sed 1d`
do
kill -9 $i
done
首先将kill替换为echo,以确保它会杀死新闻。
答案3
例如,您可以通过以下方式执行此操作:
OLDEST_PID=$(pgrep -o 'DELETE OPERATION_CONTEXT')
test $OLDEST_PID && pgrep 'DELETE OPERATION_CONTEXT' | grep -vw $OLDEST_PID | xargs -r kill
第一行找到最旧的PID。第二行首先检查是否$OLDEST_PID
包含某些内容。如果是,它会列出所有匹配的进程,过滤掉$OLDEST_PID
并杀死它们(如果有的话)。
更好的方法是通过添加来避免重复的流程像这个问题一样将锁定文件添加到 cron 脚本。
答案4
如果您有 java cron 并且想在执行该 cron 之前进行检查,请尝试以下操作:System.out.println(“检查此 cron 的先前会话:”+cronname);
String proname=ManagementFactory.getRuntimeMXBean().getName();
String pid=proname.split("@")[0];
System.out.println("Current PID:"+pid);
Process proc = Runtime.getRuntime().exec(new String[]{"bash","-c"," ps aux | grep "+cronname+" | awk '{print $2}' "});
BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String s = null;
String killid="";
while ((s = stdInput.readLine()) != null ) {
if(s.equals(pid)==false)
{
killid=killid+s+" ";
}
}
System.out.println("Running PID'S except current:"+killid);
proc.waitFor();
Process proc1 = Runtime.getRuntime().exec(new String[]{"bash","-c","kill -9 "+killid});
proc1.waitFor();
System.out.println("Previous duplicate sessions closed for: "+cronname);
将 cronname 作为你的 cronname.jar 传递