Я нашел существующие ответы неполными и не имеющими достаточно хороших примеров. Вот решение, на котором я остановился:
# 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
Вам не нужно разветвлять внешний процесс только для того, чтобы получить затраченное время 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 ).
Потратил некоторое время на это, выяснил, что самый быстрый способ получить это — токенизировать время с помощью замены 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 }'
Я открыт для предложений о том, как сделать эту команду более удобной для чтения или лучше взаимодействовать с другими, -не связанными со временем полями, такими как имя пода и статус, которые могут присутствовать.
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