1
#!/bin/sh
ALTER="1153"
NAME="aio"

for i in $(ps -eo pid,etime,comm | \
  awk -v alt="$ALTER" -v name="$NAME" '$2~/[^0-alt]-/ && $3~/name/{print$1} ');
do
  echo $i
done
4
  • Please clarify what you intend this to do. $2 ~ /[^0-1153]/ would not make sense. That would match if the etime contains a character other than 0,1,5 or 3. Oct 7 '15 at 8:47
  • I tried to print out the PID's of all aio programs older than 1153 days
    – JuM
    Oct 7 '15 at 8:54
  • 1153 days? What is the system uptime?
    – Costas
    Oct 7 '15 at 9:28
  • 11:36:45 up 1155 days, 18:20 awesome right? :D
    – JuM
    Oct 7 '15 at 9:34
3

There is no need to use awk:

for pr in $(pgrep $NAME); do 
    elapse=$(ps -o etime= -p $pr)
    [ "${elapse%-*}" -gt "$ALTER" ] && echo $pr
done

or according Stéphane Chazelas' comment

ps -C $NAME -o pid=,etime= | awk '$2 + 0 > a && /-/ {print $1}' a="$ALTER"
6
  • "etimes" does not work for me.
    – JuM
    Oct 7 '15 at 9:33
  • 2
    There is no need to call the [, echo and ps commands several times in sequence where the whole thing can be done with one invocation of ps and awk running concurrently. Oct 7 '15 at 10:13
  • Thank you so much it finally worked! but I don't get the {elapse%-*} part. Could you explain it to me?
    – JuM
    Oct 7 '15 at 10:46
  • {elapse%-*} removes part of elapse variable from - upto the end
    – Costas
    Oct 7 '15 at 11:05
  • oh okay makes sense. Do you know what I have to change if I want to run it in csh? It says a variable is illegal. And after a few tests I know that it is one after the "for".
    – JuM
    Oct 7 '15 at 11:23
2

Use this:

awk -v alt="$ALTER" -v name="$NAME" '
   $2 ~ /-/ && $2 >= alt && $3 ~ name{print $1}' file
  • $2 ~ /-/: checks that the number of days is included.
  • $2 >= alt: checks that the number of days in etime is greater than $ALTER.
  • $3 ~ name: searches for the value of name ($NAME) in the 3rd field.

Another pure bash solution:

ps -eo pid,etime,comm | while read p e n; do
  if [[ $n =~ $NAME ]] && [[ $e =~ \- ]] && [ "${e%%-*}" -gt "$ALTER" ]; then 
    echo $p
  fi
done
  • while read p e n stores the pid, the etime and the name of the command in the variables $p, $e and $n.
    • [[ $n =~ $NAME ]]: checks if the command has $NAME in it
    • [[ $e =~ \- ]]: checks if the etime has a dash (-) in it (means the process runs more than a day)
    • [ "${e%%-*}" -ge "$ALTER" ]: checks if the day counter of etime is greather or equal than the value in $ALTER
  • If all of the above is met, print the pid: echo $p
4
  • No I want that the age should be more than the value of the variable (that's why I use the negation) the problem is I always get the error report that 1-$alt is an invalid range end. If I add the age myself so 1153 instead of the variable the script works just fine. The Script works if I remove the variables and just add the values myself but I want it to work with the variables
    – JuM
    Oct 7 '15 at 8:40
  • Then just use $2>alt, instead of $2<alt. Then the second field should be greater than the value in $ALTER
    – chaos
    Oct 7 '15 at 8:50
  • Now I get following error report: awk: $2<alt-/ && $3~/aio/{print$1} awk: ^ syntax error awk: $2<alt-/ && $3~/aio/{print$1} awk: ^ syntax error (the / after $alt- is marked and the {
    – JuM
    Oct 7 '15 at 8:58
  • If I add a / before the $2 there is no more error report but the PID's dont get print out
    – JuM
    Oct 7 '15 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.