मुझे कुछ ज़ोंबी जैसी प्रक्रियाओं के साथ एक निश्चित सर्वर पर समस्या है जिसे हर समय और फिर मारने की आवश्यकता है। मैं उन लोगों की सबसे अच्छी पहचान कैसे कर सकता हूं जो एक घंटे से अधिक समय तक चल रहे हैं?आप एक निश्चित आयु से अधिक की सभी लिनक्स प्रक्रियाओं को कैसे मारते हैं?
उत्तर
वे सिर्फ मारे जाने के लिए की जरूरत है:
if [[ "$(uname)" = "Linux" ]];then killall --older-than 1h someprocessname;fi
आप को देखने के लिए यह क्या चाहते हैं मिलान
if [[ "$(uname)" = "Linux" ]];then killall -i --older-than 1h someprocessname;fi
-i
झंडा प्रत्येक प्रक्रिया मैच के लिए हाँ के साथ संकेत देगा/कोई।
अच्छी टिप। मैं बाद में स्विच की तुलना में --ल्डर पर ठोकर खाई, लेकिन -i यह जानने के लिए उपयोगी बनाता है कि कौन जानता है। – yukondude
'if [[" $ (uname) "=" Linux "]] का बिंदु क्या है? प्रासंगिक भाग सिर्फ 'killall' कमांड नहीं है? (ऐसा लगता है कि आसपास के 'अगर' खंड को इस उत्तर को थोड़ा और प्रत्यक्ष बनाने के लिए हटाया जा सकता है) – rinogo
@ringo कुछ प्रणालियों (जैसे सोलारिस) पर, killall एक पूरी तरह से अलग आदेश है।सोलारिस पर, यह सभी आदेशों को समाप्त करता है। – ctc
पीएस का उपयोग करना सही तरीका है। मैंने पहले ही कुछ ऐसा ही किया है लेकिन स्रोत को आसान नहीं है। आम तौर पर - पीएस के पास यह बताने का विकल्प होता है कि कौन से फ़ील्ड दिखाना है और किस प्रकार से सॉर्ट करना है। आप समय चलकर आउटपुट को सॉर्ट कर सकते हैं, जिस प्रक्रिया को आप चाहते हैं उसे grep करें और फिर इसे मार दें।
HTH
एक दिन से अधिक उम्र कुछ भी के लिए,
ps aux
आप इस सवाल का जवाब दे देंगे, लेकिन यह दिन परिशुद्धता जो के रूप में उपयोगी नहीं हो सकता है के लिए नीचे चला जाता है।
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7200 308 ? Ss Jun22 0:02 init [5]
root 2 0.0 0.0 0 0 ? S Jun22 0:02 [migration/0]
root 3 0.0 0.0 0 0 ? SN Jun22 0:18 [ksoftirqd/0]
root 4 0.0 0.0 0 0 ? S Jun22 0:00 [watchdog/0]
आप लिनक्स या/proc फाइल सिस्टम के साथ एक और प्रणाली पर हैं, तो इस उदाहरण में, आप केवल उस प्रक्रिया 1 22 जून के बाद से चल रहा है देख सकते हैं, लेकिन समय का कोई संकेत नहीं है कि यह शुरू किया गया था।
stat /proc/<pid>
आपको एक और सटीक उत्तर देगा।
ohm ~$ stat /proc/1
File: `/proc/1'
Size: 0 Blocks: 0 IO Block: 4096 directory
Device: 3h/3d Inode: 65538 Links: 5
Access: (0555/dr-xr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2008-06-22 15:37:44.347627750 -0700
Modify: 2008-06-22 15:37:44.347627750 -0700
Change: 2008-06-22 15:37:44.347627750 -0700
ऐसा लगता है कि 'ps' और 'stat' मेरे लिए अलग-अलग परिणाम दिखा रहा है। 'पीएस' से पता चलता है कि प्रक्रिया 1 दिन पहले शुरू हुई थी और स्टेट शो जो आज शुरू हुआ था। क्यूं कर? – pl1nk
ध्यान दें कि 'ps' आउटपुट में' TIME' कॉलम किसी प्रक्रिया के वास्तविक रन टाइम को नहीं दिखाता है। यह प्रक्रिया के संचित CPU समय को दिखाता है - जिस समय सीपीयू ने प्रक्रिया के साथ काम किया था। –
धन्यवाद, स्टेट/proc/
एक जवाब है कि मेरे लिए काम करता मिला::
चेतावनी: इस खोजने के लिए और लंबे प्रक्रियाओं चल मार डालेगा उदाहरण के लिए, यहाँ प्रक्रिया 1 के लिए एक सटीक टाइमस्टैम्प, जो ps केवल Jun22 रूप से पता चलता है
ps -eo uid,pid,etime | egrep '^ *user-id' | egrep ' ([0-9]+-)?([0-9]{2}:?){3}' | awk '{print $2}' | xargs -I{} kill {}
(कहाँ उपयोगकर्ता के आईडी लंबे समय से चल प्रक्रियाओं के साथ एक विशिष्ट उपयोगकर्ता की आईडी है।)
दूसरी नियमित अभिव्यक्ति उस समय से मेल खाती है जिसमें एक वैकल्पिक दिन का आंकड़ा होता है, उसके बाद एक घंटे, मिनट और दूसरा घटक होता है, और कम से कम एक घंटे की लंबाई होती है।
उम्म, क्या आप प्रक्रिया को मार रहे हैं? मुझे उम्मीद है कि लोगों को यह एहसास होगा कि यह कोड न सिर्फ खोजता है, बल्कि मारता है, या वे परेशान हो सकते हैं। –
@ बटलबूटस अच्छा बिंदु। हां, सवाल का पूरा कारण पुरानी प्रक्रियाओं को ढूंढना और उन्हें मारना था, लेकिन स्पष्ट रूप से स्पष्ट रूप से इसका उल्लेख नहीं किया गया है। दूसरों के लिए ध्यान दें: जब तक आप उपयोगकर्ताओं से नाराज कॉल का आनंद न लें तब तक लाइन के आखिरी छोटे हिस्से को अनदेखा करें। – yukondude
wtf! कृपया प्रश्न का शीर्षक बदलें। सौभाग्य से मैं प्रक्रिया का मालिक नहीं है! –
इस तरह आप दस सबसे पुराने प्रक्रियाओं की सूची प्राप्त कर सकते हैं:
ps -elf | sort -r -k12 | head -n 10
अच्छी चीजें, इसके लिए धन्यवाद। –
असल में जो आपको 10 नवीनतम प्रक्रियाएं देता है क्योंकि डिफ़ॉल्ट रूप से यह STIME दिखाता है जो प्रोग्राम शुरू हुआ था। यदि यह ईटीआईएमई दिखा रहा था जो कार्यक्रम शुरू होने के बाद से समाप्त हो गया है तो यह सही होगा। –
एक ps -aef
है। यह आपको वह समय दिखाएगा जिस पर प्रक्रिया शुरू हुई थी। फिर date
कमांड का उपयोग वर्तमान समय ढूंढें। प्रक्रिया की उम्र खोजने के लिए दोनों के बीच के अंतर की गणना करें।
दुर्भाग्य से यहां समय आउटपुट पार्स करना मुश्किल है। यह शॉर्ट-रनिंग प्रक्रियाओं के लिए "एचएच: एमएम" हो सकता है, या "एमएनडीडी" (संभवतः स्थानीयकृत!) या यहां तक कि केवल बहुत लंबी चल रही प्रक्रियाओं के लिए वर्ष हो सकता है। –
पर्ल के प्रोक :: ProcessTable चाल करना होगा: sudo apt-get install libproc-processtable-perl
यहाँ के साथ http://search.cpan.org/dist/Proc-ProcessTable/
आप डेबियन में स्थापित कर सकते हैं या ubuntu एक एक लाइनर है:
perl -MProc::ProcessTable -Mstrict -w -e 'my $anHourAgo = time-60*60; my $t = new Proc::ProcessTable;foreach my $p (@{$t->table}) { if ($p->start() < $anHourAgo) { print $p->pid, "\n" } }'
या, अधिक स्वरूपित, इसे प्रक्रिया नामक फ़ाइल में डालें।pl:
#!/usr/bin/perl -w
use strict;
use Proc::ProcessTable;
my $anHourAgo = time-60*60;
my $t = new Proc::ProcessTable;
foreach my $p (@{$t->table}) {
if ($p->start() < $anHourAgo) {
print $p->pid, "\n";
}
}
तो चलाने perl process.pl
यह आपको अधिक बहुमुखी प्रतिभा और प्रारंभ समय पर 1-दूसरे संकल्प देता है।
मैं स्वीकार किए जाते हैं जवाब देने के लिए समान है, लेकिन कुछ अलग ढंग से के बाद से मैं इस प्रक्रिया नाम के आधार पर और 100 से अधिक सेकंड
kill $(ps -o pid,bsdtime -p $(pgrep bad_process) | awk '{ if ($RN > 1 && $2 > 100) { print $1; }}')
stat -t /proc/<pid> | awk '{print $14}'
पाने के लिए चल रहा है बुरा प्रक्रिया के आधार पर मिलान करना चाहते हैं कुछ किया युग के बाद से सेकंड में प्रक्रिया का प्रारंभ समय। प्रक्रिया की वर्तमान उम्र प्राप्त करने के लिए वर्तमान समय (date +%s
) के साथ तुलना करें।
प्रक्रिया शुरू होने के बाद से हम सेकंड्स प्राप्त करने के लिए दो आदेशों में शामिल हो सकते हैं: "echo' stat -t/proc/
यह हमेशा नहीं होगा सही हो - कम से कम लिनक्स 2.6 सिस्टम के लिए नहीं। मेरे पास एक प्रक्रिया है जो 9:49 बजे शुरू हुई लेकिन स्टेट-टी (और स्टेट) दिखाती है कि यह 13:14 बजे शुरू हुआ। –
@ डीपीके: कभी-कभी आपके पास मुख्य प्रक्रिया होती है और कुछ कांटे चलते हैं। मुख्य प्रक्रिया 9:49 होनी चाहिए, लेकिन बाल प्रक्रिया में कोई और हालिया समय हो सकता है। यह एक प्रक्रिया के धागे पर लागू होता है। – higuita
मामले में किसी को भी सी में इस की जरूरत है, तो आप readproc.h और libproc उपयोग कर सकते हैं:
#include <proc/readproc.h>
#include <proc/sysinfo.h>
float
pid_age(pid_t pid)
{
proc_t proc_info;
int seconds_since_boot = uptime(0,0);
if (!get_proc_stats(pid, &proc_info)) {
return 0.0;
}
// readproc.h comment lies about what proc_t.start_time is. It's
// actually expressed in Hertz ticks since boot
int seconds_since_1970 = time(NULL);
int time_of_boot = seconds_since_1970 - seconds_since_boot;
long t = seconds_since_boot - (unsigned long)(proc_info.start_time/Hertz);
int delta = t;
float days = ((float) delta/(float)(60*60*24));
return days;
}
आप bc
उपयोग कर सकते हैं भीड़ के जवाब में दो आदेशों में शामिल होने और कितने सेकंड ellapsed के बाद से प्रक्रिया आरंभ करने के लिए:
echo `date +%s` - `stat -t /proc/<pid> | awk '{print $14}'` | bc
संपादित करें:
बोरियत से बाहर लंबा प्रक्रियाओं को चलाने के लिए इंतजार कर रहे हैं, जबकि , यह क्या नगण्य कुछ मिनट के बाद बाहर आ गया है:
#file: sincetime
#!/bin/bash
init=`stat -t /proc/$1 | awk '{print $14}'`
curr=`date +%s`
seconds=`echo $curr - $init| bc`
name=`cat /proc/$1/cmdline`
echo $name $seconds
आप अपने रास्ते पर इस डाल दिया और इसे इस तरह कॉल करते हैं: sincetime
यह प्रक्रिया के बाद से cmdline और सेकंड को प्रिंट करेगा। आप भी अपने रास्ते में इस डाल सकते हैं:
#file: greptime
#!/bin/bash
pidlist=`ps ax | grep -i -E $1 | grep -v grep | awk '{print $1}' | grep -v PID | xargs echo`
for pid in $pidlist; do
sincetime $pid
done
और अगर आप से चलाएँ:
greptime <pattern>
जहां पैटर्न एक स्ट्रिंग या विस्तारित नियमित अभिव्यक्ति है, यह सभी प्रक्रियाओं बाहर प्रिंट होगा इस पैटर्न से मेल खाते और सेकंड शुरू होने के बाद से सेकंड। :)
जोडी सी और अन्य ने इंगित किया है कि killall -i
का उपयोग किया जा सकता है, यदि आप प्रक्रिया के नाम को मारने के लिए उपयोग करना चाहते हैं तो ठीक है। लेकिन अगर आप pgrep -f
के समान पैरामीटर से मारना चाहते हैं, तो आपको शुद्ध बैश और /proc
फाइल सिस्टम का उपयोग करके निम्न की तरह कुछ उपयोग करने की आवश्यकता है।
#!/bin/sh
max_age=120 # (seconds)
naughty="$(pgrep -f offlineimap)"
if [[ -n "$naughty" ]]; then # naughty is running
age_in_seconds=$(echo "$(date +%s) - $(stat -c %X /proc/$naughty)" | bc)
if [[ "$age_in_seconds" -ge "$max_age" ]]; then # naughty is too old!
kill -s 9 "$naughty"
fi
fi
इससे आपको यह जानने और पूरी प्रक्रिया को नाम का उपयोग कर max_age
सेकंड से अधिक उम्र के प्रक्रियाएं समाप्त करने देता है; अर्थात।, /usr/bin/python2 offlineimap
नाम की प्रक्रिया को "ऑफ़लाइनमैप" के संदर्भ में मार दिया जा सकता है, जबकि यहां प्रस्तुत killall
समाधान केवल स्ट्रिंग "पायथन 2" पर काम करेंगे।
भर में आया somewhere..thought यह सरल और उपयोगी
आप crontab सीधे में आदेश का उपयोग कर सकते हैं,
* * * * * ps -lf | grep "user" | perl -ane '($h,$m,$s) = split /:/,$F
+[13]; kill 9, $F[3] if ($h > 1);'
या, हम खोल स्क्रिप्ट के रूप में यह लिख सकते हैं,
#!/bin/sh
# longprockill.sh
ps -lf | grep "user" | perl -ane '($h,$m,$s) = split /:/,$F[13]; kill
+ 9, $F[3] if ($h > 1);'
और इसे क्रॉन्टाब को कॉल करें,
* * * * * longprockill.sh
लिनक्स में 'killall -i --older-1h someprocessname' – sanmai
का उपयोग करें या मेरा उत्तर देखें जो 'pgrep' का उपयोग करता है और इस प्रकार 'killall' से अधिक लचीला है। – g33kz0r