Как преобразовать прошедшее время в стиле kubernetes в секунды, чтобы я мог провести некоторые сравнения

Я нашел существующие ответы неполными и не имеющими достаточно хороших примеров. Вот решение, на котором я остановился:

# an example checking if the pandas package is installed
if python -c 'import pkgutil; exit(not pkgutil.find_loader("pandas"))'; then
    echo 'pandas found'
else
    echo 'pandas not found'
fi

Суть этого примера на Github можно найти здесь:https://gist.github.com/shaypal5/d505af9953cd86f59c750fa600ee4ba6

0
13.08.2020, 00:26
3 ответа

Вам не нужно разветвлять внешний процесс только для того, чтобы получить затраченное время kubernetes в секундах. Приведенный ниже код GNU awk имеет определяемую пользователем функцию fx() , которая должна выполнять это преобразование, и с этого момента вы можете использовать ее для целей сравнения.

kubectl get pods -o wide |
awk '
BEGIN {
    a["d"] = 24*(\
    a["h"] = 60*(\
    a["m"] = 60*(\
    a["s"] = 1)));
  }
  {
    print fx($5); # kubernetes time elapsed in seconds 
  }
  function fx(ktym,    f,u,n,t,i) {
    n = split(ktym, f, /[dhms]/, u)
    t = 0
    for (i=1; i<n; i++) {
      t += f[i] * a[u[i]] 
    }
    return t
  }
'

Если вы хотите использовать пользовательскую функцию в bash, мы можем сделать следующее. У нас есть функция fx (), которой нужен один аргумент — время, прошедшее в формате kubernetes, и она будет выводить время в секундах.

fx() {
echo "$1" |
sed -Ee '
  s/[1-9][0-9]*[dhms]/&+ /g
  :a;s/[+]([^+].*)/\1+/;ta
  s/.$//
  :loop
    s/d/ 24h*/
    s/h/ 60m*/
    s/m/ 60s*/
    s/s//
  t loop
  s/.*/echo "&" | dc -e "?p"/e
'
}

Мы динамически генерируем код для утилиты Linux под названием dc или настольного калькулятора в RPN(Reverse Polish Notation ).

1
18.03.2021, 23:13

Потратил некоторое время на это, выяснил, что самый быстрый способ получить это — токенизировать время с помощью замены sed.

sed -e 's/\([smhd]\)/\1 /g' | awk '{ b=0; for(i=1; i<=NF; ++i) { s=substr($i,1,length($i)-1); u=substr($i,length($i)); if (u=="s") b+=s; else if (u=="m") b+=s*60; else if (u=="h") b+=s*60*60; else if (u=="d") b+=s*60*60*24; else u=""; } if (b>1) printf "%d", b}'

До сих пор я наблюдал, что в этой области используются только единицы d, h, m, s, даже для стручков, возраст которых > 100 дней.

Команда sed в основном разделяла каждую единицу пробелом.
Затем Awk перебирает поля и разделяет строку на единицу (u )и числовую строку (s ).
Сцепленные операторы if -elseif -else просто преобразуют значения в секунды на основе единиц измерения и добавляют их к промежуточному итогу времени в секундах.

Я поместил эту команду в скрипт «kube _истекло с _на _секунд» и планирую использовать другой awk снаружи и системную команду для запуска этого скрипта в этом поле.

kubectl get pods -o wide | awk '{ system("echo " $5 " | kube_elapased_to_seconds"); print $0 }'

Я открыт для предложений о том, как сделать эту команду более удобной для чтения или лучше взаимодействовать с другими, -не связанными со временем полями, такими как имя пода и статус, которые могут присутствовать.

1
18.03.2021, 23:13

convert the string into a numeric seconds so I can then compare if it is > 3600

3600 секунд — это час, так что вам просто нужно проверить, упоминается ли хотя бы один час в выводе:

echo 4d3h15m3s | grep -q '[dh]' && echo At least 3600 seconds

Для сопоставления с пятым полем в фактическом выводе используйте awk, но для этого необходимо, чтобы ни одно из предыдущих значений поля не содержало пробела

kubectl get pods -o wide | awk '{ exit ($5 ~ /[dh]/) ? 0 : 1 }' && echo At least 3600 seconds

Если вам нужны не -граничные сравнения, вам потребуется преобразовать спецификацию времени в количество секунд. Вот perlверсия

perl -e '
    %t=(d => 3600*24, h => 3600, m => 60, s => 1);    # Seconds per unit
    @a=split(/([dhms])/, shift);                      # Tokenise string argument
    for ($i = 0; $i < scalar @a; $i += 2) {
        $s += $a[$i] * $t{$a[$i+1]}                   # Add N lots of seconds-per-unit
    };
    print "$s\n"
' 4d3h15m3s
1
18.03.2021, 23:13

Теги

Похожие вопросы