A diferença que você está observando não se deve, na verdade, ao fato de o espaço de troca não ser contabilizado. O "(excluído)" que o kernel às vezes anexa a /proc/*/exe
links é produzido por readlink
e está causando erros de análise em seu script awk, e você está efetivamente não contando processos cujos binários não estão mais presentes em seu total. / p>
Alguns kernels acrescentam a palavra "(deleted)" aos alvos do link simbólico /proc/*/exe
quando o executável original do processo não está mais disponível.
A razão pela qual seu comando está mostrando menos que o total é por causa disso. A saída de readlink
em tais links será algo como "/ caminho / para / bin (excluído)", o que causa um erro de análise em awk
quando a saída é substituída de volta na cadeia (não gosta da parênteses e espaços). Por exemplo, faça isso:
for a in /proc/*/exe ; do readlink $a ; done | grep deleted
E você verá algumas entradas com "(excluído)" anexadas. Se você analisar o uso de troca para essas entradas, o total delas corresponderia à discrepância que você vê, pois os erros awk
resultantes impedem que os totais sejam calculados e incluídos no total final.
Se você executar o comando original sem redirecionar o stderr para qualquer lugar, você provavelmente notará alguns erros de "constante de cadeia de fuga". Esses erros são resultado do acima e você não deveria tê-los ignorado.
Ignorando outras melhorias potenciais ao seu comando original, você poderia modificá-lo removendo o "(excluído)", assim (note |awk '{print $1}'
adicionado à readlink
output):
for proc in /proc/*; \
do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t''readlink $proc/exe|awk '{print $1}' ''" }'; \
done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'
Esse uso de awk
para corrigir a saída de readlink
pode ser interrompido se o nome contiver espaços - você pode usar sed
ou qualquer método que preferir.
Informações sobre bônus
A propósito, você poderia usar apenas smem -t
. A coluna "Trocar" exibe o que você deseja.
Quanto a calcular você mesmo, você também pode obter essas informações mais diretamente do campo VmSwap
em /proc/*/status
(o smaps requer algum suporte ao kernel e nem sempre está disponível) e evitar a necessidade de redirecionar a saída de erro usando um padrão de nome de arquivo adequado que evita os erros para começar:
for proc in /proc/[0-9]*; do \
awk '/VmSwap/ { print $2 "\t''readlink $proc/exe | awk '{ print $1 }'''" }' $proc/status; \
done | sort -n | awk '{ total += $1 ; print $0 } END { print total "\tTotal" }'
Se você não precisar do binário real e puder lidar com apenas o nome do processo, poderá obter tudo em status
:
for a in /proc/*/status ; do \
awk '/VmSwap|Name/ { printf $2 " " } END { print "" }' $a ; \
done | awk '{ total+=$2 ; print $0 } END { print "Total " total }'
E, finalmente, se basta ter os PIDs, basta fazer tudo com awk
:
awk '/VmSwap/ { total += $2; print $2 "\t" FILENAME } END { print total "\tTotal" }' /proc/*/status
Nota:
Agora, isso não quer dizer que não haja diferenças entre free
e smem
(sendo este último o mesmo que seu script). Existem muitos (veja, por exemplo, o link , que tem resultados mais do que suficientes na primeira página para responda suas perguntas sobre o uso da memória). Mas sem um teste adequado, sua situação específica não pode ser abordada.