Come posso scoprire la memoria fisica totale (RAM) della mia macchina Linux adatta per essere analizzata da uno script di shell?


123

Sto digitando uno script di shell per scoprire la memoria fisica totale in alcune scatole di RHEL linux.

Prima di tutto voglio sottolineare che mi interessa la memoria fisica totale riconosciuta dal kernel, non solo la memoria disponibile . Pertanto, per favore, evita le risposte che suggeriscono di leggere / proc / meminfo o di usare i comandi free , top o sar - In tutti questi casi, i loro valori di " memoria totale " significano quelli di " memoria disponibile ".

Il primo pensiero è stato leggere i messaggi del kernel di avvio:

Memory: 61861540k/63438844k available (2577k kernel code, 1042516k reserved, 1305k data, 212k init)

Ma in alcune macchine Linux, a causa dell'uso del software PowerPath di EMC2 e dei suoi messaggi di avvio inondati all'avvio del kernel, quell'utile messaggio di avvio del kernel non è disponibile, nemmeno nel file / var / log / dmesg .

La seconda opzione era il comando dmidecode (sono avvisato del possibile disallineamento della RAM riconosciuta dal kernel e della RAM reale a causa delle limitazioni di alcuni kernel e architetture meno recenti). L'opzione --memory semplifica lo script ma mi sono reso conto che le versioni precedenti di quel comando non hanno l' opzione --memory .

La mia ultima possibilità è stata il comando getconf . Riporta la dimensione della pagina di memoria, ma non il numero totale di pagine fisiche - la variabile di sistema _PHYS_PAGES sembra essere le pagine fisiche disponibili, non le pagine fisiche totali.

# getconf -a | PAGINE grep
PAGINA 4096
_AVPHYS_PAGES 1049978
_PHYS_PAGES 15466409

La mia domanda: esiste un altro modo per ottenere la quantità totale di memoria fisica, adatta per essere analizzata da uno script di shell?


3
Questo dovrebbe essere migrato su Linux e unix
Kolob Canyon

Risposte:


56

Se sei interessato alla RAM fisica, usa il comando dmidecode. Ti fornisce molte più informazioni oltre a questo, ma a seconda del tuo caso d'uso, potresti anche voler sapere se l'8G nel sistema proviene da stick 2x4GB o stick 4x2GB.


19
Ne avevo bisogno di recente e ho un semplice comando per ottenere la dimensione totale della memoria di tutti i moduli di memoria su un sistema: dmidecode -t 17 | grep "Dimensioni. * MB" | awk '{s + = $ 2} END {print s / 1024}'
Jonesinator

6
Diversamente dalle altre risposte, dmidecode richiede i privilegi di root .
chus

1
Mi dà questo errore # dmidecode 3.0 / sys / firmware / dmi / tables / smbios_entry_point: Autorizzazione negata Scansione / dev / mem per punto di ingresso. / dev / mem: autorizzazione negata
VVB

128

Hai provato cat /proc/meminfo? Puoi quindi awk o grep quello che vuoi, MemTotal es

awk '/MemTotal/ {print $2}' /proc/meminfo

o

cat /proc/meminfo | grep MemTotal

8
Ma MemTotal non è la memoria fisica totale - vedere la pagina man di proc (5)
Chris Stratton

2
@ChrisStratton: puoi essere più esplicito? Per la maggior parte degli intenti e degli scopi pratici, questa risposta può essere sufficiente.
Dan Dascalescu

13
awk '/MemTotal/ {print $2}' /proc/meminfo Meno tubi, meglio è.
masta

3
Alternativa altamente supponente: evita awk, quando puoi. Regex / PCRE è un linguaggio di corrispondenza dei modelli molto più universale (cioè puoi usarlo anche in Python o Perl). Se impari awk, tutto ciò che hai già è awk. Se ti appoggi a grep + PCRE d'altra parte ... grep -oP '^MemTotal:\s+\K.*' /proc/meminfo
Gabriel Totusek

5
@GabrielBurkholder c'è anche una visione opposta: awkè standardizzato da POSIX ma greple opzioni di -oe -Pnon lo sono! Il tuo esempio funzionerà bene con GNU grep(ma GNU dice ancora che l'implementazione PCRE è sperimentale) ma probabilmente non funzionerà con altre implementazioni.
pabouk

48

cat /proc/meminfo | grep MemTotalo gratis ti dà la quantità esatta di RAM del tuo server. Questa non è "memoria disponibile".

Immagino che il tuo problema si presenti quando hai una VM e vorresti calcolare l'intera quantità di memoria ospitata dall'hypervisor, ma in tal caso dovrai accedere all'hypervisor.

cat /proc/meminfo | grep MemTotal

è equivalente a

 getconf -a | grep PAGES | awk 'BEGIN {total = 1} {if (NR == 1 || NR == 3) total *=$NF} END {print total / 1024" kB"}'

5
Sulla mia scatola fisica con cat /proc/meminfo | grep MemTotalrapporti di memoria da 4 GB MemTotal: 3957032 kB, è un po 'meno di 4 GB. L'OP (e io) stiamo cercando qualcosa che riporti 4 GB.
TvE

1
Un modo più diretto per farlo è sologrep MemTotal /proc/meminfo
Dan Passaro

3
@TvE 3957032 kBè semplicemente etichettato male . Dovrebbe essere etichettato kiB, come indicato in questo post . Ciò significa che in realtà riporta 4.052.000.768 byte, che è leggermente superiore a 4 GB. Ciò è dovuto al fatto che le implementazioni di / proc / meminfo sono antecedenti alla notazione kiB.
Jeff G

4
@ JeffG Penso che tu abbia perso il punto che ToolmakerSteve stava facendo. Il valore previsto è 4 GB, non 4 GB, e TvE sta semplicemente citando erroneamente il valore. ToolmakerSteve ha ragione sul fatto che "4 GB" di RAM dovrebbe essere interpretato come "4 GiB" nel commento di TvE, e quindi questo è il valore con il quale stiamo confrontando. Hai ragione sul fatto che il valore è maggiore di 4 GB, così come è anche maggiore di 2 GB e 2 GB e inferiore a 6 GB e 6 GB, ma ciò che conta qui è come si confronta con 4 GB, quindi chi se ne frega di come si confronta con le altre misure? Quindi sì, la tua affermazione è corretta, ma è anche irrilevante.
Tim

1
@Tim Ho fornito solo informazioni che sono effettivamente accurate, con documentazione di supporto, che ha risposto alla domanda che è stata posta. Dato che per trovarlo è stata necessaria più di una semplice ricerca, penso che il fatto che /proc/meminforiporta i numeri in kiB sia una parte estremamente importante di questa discussione, indipendentemente dal fatto che @TvE intendesse porre una domanda diversa.
Jeff G,

19

Aggiungi le ultime 2 voci di /proc/meminfo, ti danno la memoria esatta presente sull'host.

Esempio:

DirectMap4k:       10240 kB
DirectMap2M:     4184064 kB

10240 + 4184064 = 4194304 kB = 4096 MB.


3
La migliore risposta qui, oltre all'uso di dmidecode, che richiede root. Ma DirectMap non è sempre esatto. Ho un server con 4 GB e dice: `DirectMap4k: 110200 kB DirectMap2M: 3993600 kB` Sono 4007 MB, non 4096 MB ...
TvE

NOTA: anche se il sistema operativo di TvE riporta in unità di 1024 byte, il suo totale di 4103800 x 1024 è inferiore a 4 GiB (che sarebbe 4194304 x 1024).
ToolmakerSteve

Inoltre, non disponibile su tutte le versioni di Linux. La mia scatola Centos5 (sì, lo so) non lo segnala.
Tom Quarendon

Per la cronaca, questi sono presenti solo su x86. Il motivo per cui funziona è che queste voci contano la quantità di memoria rappresentata da 4k, 2M, pagine 1G nel TLB, che deve coprire tutta la memoria accessibile dal kernel .
kevmitch

1
AGGIORNAMENTO: Questa somma varia leggermente quando mi sposto tra diverse versioni del kernel (linux-3.18.28, linux-4.13-rc6) sulla stessa macchina.
kevmitch

17

Un altro comando utile: l'
vmstat -s | grep memory
output di esempio sulla mia macchina è:

  2050060 K total memory
  1092992 K used memory
   743072 K active memory
   177084 K inactive memory
   957068 K free memory
   385388 K buffer memory

un altro comando utile per ottenere informazioni sulla memoria è: l'
free
output di esempio è:

             total       used       free     shared    buffers     cached
Mem:       2050060    1093324     956736        108     385392     386812
-/+ buffers/cache:     321120    1728940
Swap:      2095100       2732    2092368

Un'osservazione qui è che il comando freefornisce anche informazioni sullo spazio di swap.
Il seguente collegamento potrebbe esserti utile:
http://www.linuxnix.com/find-ram-details-in-linuxunix/


1
Questa è una soluzione semplice e carina, se vuoi che il tuo output in megabyte sia più facile da vederevmstat -s -S M | grep ' memory'
Oliver Dungey

17
free -h | awk '/Mem\:/ { print $2 }' 

Ciò fornirà la memoria totale del sistema in un formato leggibile dall'uomo e scalerà automaticamente all'unità appropriata (es. Byte, KB, MB o GB).


Proprio quello che stavo cercando!
Tomas Gonzalez

10
dmidecode -t 17 | grep  Size:

L'aggiunta di tutti i valori sopra visualizzati dopo "Dimensione:" fornirà la dimensione fisica totale esatta di tutte le chiavette RAM nel server.


2

Memoria online totale

Calcola la memoria in linea totale utilizzando sys-fs.

totalmem=0;
for mem in /sys/devices/system/memory/memory*; do
  [[ "$(cat ${mem}/online)" == "1" ]] \
    && totalmem=$((totalmem+$((0x$(cat /sys/devices/system/memory/block_size_bytes)))));
done

#one-line code
totalmem=0; for mem in /sys/devices/system/memory/memory*; do [[ "$(cat ${mem}/online)" == "1" ]] && totalmem=$((totalmem+$((0x$(cat /sys/devices/system/memory/block_size_bytes))))); done

echo ${totalmem} bytes
echo $((totalmem/1024**3)) GB

Esempio di output per il sistema da 4 GB:

4294967296 bytes
4 GB

Spiegazione

/ sys / devices / system / memoria / block_size_bytes

Numero di byte in un blocco di memoria (valore esadecimale). L'uso di 0x davanti al valore assicura che sia gestito correttamente durante il calcolo.

/ Sys / devices / system / memoria / memoria *

Iterazione su tutti i blocchi di memoria disponibili per verificare che siano online e aggiungere la dimensione del blocco calcolato a totalmem, se lo sono.

[["$ (cat $ {mem} / online)" == "1"]] &&

Puoi modificarlo o rimuoverlo se preferisci un altro stato di memoria.


Controllerò la tua soluzione appena possibile.
Jdamian

Suggerimento bash: nel codice non è necessario utilizzare il carattere barra ( \) per continuare nella riga successiva - in realtà, è possibile utilizzare &&alla fine della riga per quello scopo.
Jdamian

1

Memoria totale in Mb:

x=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
echo $((x/1024))

o:

x=$(awk '/MemTotal/ {print $2}' /proc/meminfo) ; echo $((x/1024))

0

Questi sono i modi:

1. / proc / meminfo

MemTotal: 8152200 kB

MemFree: 760808 kB

Puoi scrivere un codice o uno script per analizzarlo.

2. Utilizzare sysconf utilizzando le macro seguenti

sysconf (_SC_PHYS_PAGES) * sysconf (_SC_PAGESIZE);

3. Utilizzando la chiamata di sistema sysinfo

int sysinfo (struct sysinfo * info);

struct sysinfo {.

   .

   unsigned long totalram;  /*Total memory size to use */

   unsigned long freeram;   /* Available memory size*/

   .

   . 

  }; 

cat / proc / meminfo funziona per me sul mio sistema embedded
webbertiger

-7

Trovo htopuno strumento utile.

sudo apt-get install htop

e poi

free -m

fornirà le informazioni di cui hai bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.