BASH, если оператор работает не так, как ожидалось

#linux #bash #process #ps

Вопрос:

Как говорится в заголовке, я пытаюсь воспроизвести только процесс, который старше 2600000 секунд, но он воспроизводит процессы с временами менее 2600000.

  while read pro; do
 set -- $pro

if [ $2 > 2600000 ]
 then
 echo $2 is bigger than 2600000
 echo "
PID :$1, Process owner :$3, procces begin time: $2 (Seconds ago)  
"
 fi
PIDS_OVER_A_MONTH =("PID:$2, Process owner:$2")



done < <(ps -eo pid,etimes,user )

 

Это мой вывод, как вы можете видеть, он отражает время выполнения, которое меньше 2600000 (не обращайте внимания на список PIDS_OVER…):

 PID :25271, Process owner :yonatanh, procces begin time: 2082286 (Seconds ago)  

2082286 is bigger than 2600000

PID :25275, Process owner :yonatanh, procces begin time: 2082286 (Seconds ago)  

2082284 is bigger than 2600000

PID :25299, Process owner :yonatanh, procces begin time: 2082284 (Seconds ago)  

7224 is bigger than 2600000

PID :29549, Process owner :it, procces begin time: 7224 (Seconds ago)  

6843 is bigger than 2600000

PID :30225, Process owner :yonatanh, procces begin time: 6843 (Seconds ago)  

2079327 is bigger than 2600000

PID :31324, Process owner :yonatanh, procces begin time: 2079327 (Seconds ago) 
 

Комментарии:

1. попробуйте $2 -gt 2600000 провести числовые сравнения

2. @markp-fuso я получаю строку ошибки 19: [: ИСТЕКЛО: ожидаемое целочисленное выражение

3. Кроме того, обратите внимание на пустой файл 2600000 в вашем текущем каталоге? Если вы хотите выполнить сравнение строк с > , вам необходимо избежать его, чтобы он не рассматривался как оператор перенаправления. [ $2 > 2600000 ] эквивалентно [ $2 ] > 2600000 .

4. Это чрезвычайно распространенная ошибка. Я твердо верю, что одно из простых решений этой ошибки- никогда не использовать [ . Ошибка кажется более очевидной , когда вы пишете ее как if test $2 > 2600000 , так как читателя не смущает неверное убеждение, что [ и ] являются частью грамматики.

Ответ №1:

Ты ведь сказал bash , верно? Вам нужна переносимость на другие анализаторы?

Я бы использовал bash .

 while read -r pid etimes user; do
  if (( etimes > 2600000 )); then
     echo "$etimes is bigger than 2600000"
     printf "nPID :%s, Process owner :%s, proccess begin time: %s (Seconds ago)  nn" "$pid" "$user" "$etimes"
     PIDS_OVER_A_MONTH =("PID:$pid, Process owner:$user")
  fi
done < <(ps -eo pid,etimes,user ) 
 

Числовой контекст (( )) делает это довольно ясным.

Ответ №2:

Пара рекомендуемых изменений:

  • используется -gt для числовых сравнений
  • добавьте --no-headers , чтобы подавить строку ps заголовка
  • считывание ps значений непосредственно в переменные

Стягиваем все это вместе:

 while read -r pid elapsed owner
do
    if [ "${elapsed}" -gt 2600000 ]
    then
        echo "${elapsed} is bigger than 2600000"
        printf "nPID : ${pid}, Process owner : ${owner}, procces begin time : ${elapsed} (Seconds ago)nn"
    fi
    PIDS_OVER_A_MONTH =("PID:${pid}, Process owner:${owner}")
done < <(ps --no-headers -eo pid,etimes,user )