Использование awk для сбора информации об использовании сети из одной строки в двух файлах, считываемых в разное время - PullRequest
1 голос
/ 28 апреля 2019

Проще говоря, я пытаюсь создать сценарий genmon, который отслеживает передачу по сети, используя awk в 1-строчной строке, чтобы уменьшить загрузку ЦП.

То, к чему я стремлюсь, это то, что я хотел быЭтот скрипт обновляется каждые 0,25 секунды.

В настоящее время у меня есть 4-строчный скрипт:

PTXRX=( $(awk 'FNR==1' "/sys/class/net/${1}/statistics/tx_bytes" "/sys/class/net/${1}/statistics/rx_bytes") )
sleep 0.125
CTXRX=( $(awk 'FNR==1' "/sys/class/net/${1}/statistics/tx_bytes" "/sys/class/net/${1}/statistics/rx_bytes") )
awk -v ptx=${PTXRX[0]} -v prx=${PTXRX[1]} -v ctx=${CTXRX[0]} -v crx=${CTXRX[1]} 'BEGIN {printf "tx: %.2f KiB/s\nrx: %.2f KiB/s", (ctx-ptx)/512, (crx-prx)/512 }'

0.125, поскольку плагину требуется время для отображения обновления, поэтому мы 'повторное приближение в два раза и удвоение значения (что не слишком далеко).

пример данных: (данные ожидаются в файлах)

tx_bytes: 284425478
rx_bytes: 3450790917

sleep 0.125

tx_bytes: 284426024
rx_bytes: 3450790917

Проблема в том, что этоиспользует от 10 до 20% моего процессора ...
Как я могу уменьшить это до одной команды awk и повысить производительность ??

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

tx: 0.00 KiB/s
rx: 0.00 KiB/s

1 Ответ

2 голосов
/ 28 апреля 2019

Попробуйте это:

IFS= read -r ptx < "/sys/class/net/${1}/statistics/tx_bytes"
IFS= read -r prx < "/sys/class/net/${1}/statistics/rx_bytes"
sleep 0.125
IFS= read -r ctx < "/sys/class/net/${1}/statistics/tx_bytes"
IFS= read -r crx < "/sys/class/net/${1}/statistics/rx_bytes"
awk -v ptx="$ptx" -v prx="$prx" -v ctx="$ctx" -v crx="$crx" 'BEGIN {printf "tx: %.2f KiB/s\nrx: %.2f KiB/s\n", (ctx-ptx)/512, (crx-prx)/512 }'

Если это не поможет, вы не сможете решить проблему с производительностью в этом сегменте кода, и вам придется пересматривать свой подход к циклу и вызову команд каждые 0,125 с.

Если вы используете bash, вы можете заменить оставшийся вызов awk на:

printf 'tx: %.2f KiB/s\nrx: %.2f KiB/s\n' $(( (ctx-ptx)/512 )) $(( (crx-prx)/512 ))

но это все равно не будет иметь существенного значения.

Последнее, что вы можете попробовать, МОЖЕТ выжать немного лучшую производительность (или даже хуже, но вы можете попробовать):

IFS= read -r ptx < "/sys/class/net/${1}/statistics/tx_bytes"
IFS= read -r prx < "/sys/class/net/${1}/statistics/rx_bytes"
sleep 0.125
awk -v ptx="$ptx" -v prx="$prx" -v tx_bytes="/sys/class/net/${1}/statistics/tx_bytes" -v rx_bytes="/sys/class/net/${1}/statistics/rx_bytes" 'BEGIN{
    getline ctx < tx_bytes
    getline crx < rx_bytes
    printf "tx: %.2f KiB/s\nrx: %.2f KiB/s\n", (ctx-ptx)/512, (crx-prx)/512
}'
...