how to find Linux module path - linux

in the linux, lsmod lists a lot of modules. but how can we find where those module loaded from.
for some modules,linux command "modprobe -l" shows a path but some are not.
edited
i also tried "find" and "locate". both of them lists all kind of versions
locate fake
/svf/SVDrv/kernel/linux/.fake.ko.cmd
/svf/SVDrv/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv/kernel/linux/.fake.o.cmd
/svf/SVDrv/kernel/linux/fake.ko
/svf/SVDrv/kernel/linux/fake.mod.o
/svf/SVDrv/kernel/linux/fake.o
/svf/SVDrv.03.11.2014.16.00/kernel/linux/.fake.ko.cmd
/svf/SVDrv.03.11.2014.16.00/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv.03.11.2014.16.00/kernel/linux/.fake.o.cmd
/svf/SVDrv.03.11.2014.16.00/kernel/linux/fake.ko
/svf/SVDrv.03.11.2014.16.00/kernel/linux/fake.mod.o
/svf/SVDrv.03.11.2014.16.00/kernel/linux/fake.o
/svf/SVDrv.04.29.2014.17.39/kernel/linux/.fake.ko.cmd
/svf/SVDrv.04.29.2014.17.39/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv.04.29.2014.17.39/kernel/linux/.fake.o.cmd
/svf/SVDrv.04.29.2014.17.39/kernel/linux/fake.ko
/svf/SVDrv.04.29.2014.17.39/kernel/linux/fake.mod.o
/svf/SVDrv.04.29.2014.17.39/kernel/linux/fake.o
/svf/SVDrv.05.05.2014.11.25/kernel/linux/.fake.ko.cmd
/svf/SVDrv.05.05.2014.11.25/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv.05.05.2014.11.25/kernel/linux/.fake.o.cmd
/svf/SVDrv.05.05.2014.11.25/kernel/linux/fake.ko
/svf/SVDrv.05.05.2014.11.25/kernel/linux/fake.mod.o
/svf/SVDrv.05.05.2014.11.25/kernel/linux/fake.o
/svf/SVDrv.05.05.2014.17.43/kernel/linux/.fake.ko.cmd
/svf/SVDrv.05.05.2014.17.43/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv.05.05.2014.17.43/kernel/linux/.fake.o.cmd
/svf/SVDrv.05.05.2014.17.43/kernel/linux/fake.ko
/svf/SVDrv.05.05.2014.17.43/kernel/linux/fake.mod.o
/svf/SVDrv.05.05.2014.17.43/kernel/linux/fake.o
/svf/SVDrv.05.07.2014.14.59/kernel/linux/.fake.ko.cmd
/svf/SVDrv.05.07.2014.14.59/kernel/linux/.fake.mod.o.cmd
/svf/SVDrv.05.07.2014.14.59/kernel/linux/.fake.o.cmd
/svf/SVDrv.05.07.2014.14.59/kernel/linux/fake.ko
/svf/SVDrv.05.07.2014.14.59/kernel/linux/fake.mod.o
/svf/SVDrv.05.07.2014.14.59/kernel/linux/fake.o

Sorry if the answer comes a bit late but I just stumbled across this particular question myself today...
To minimize manual labor here is my listing of the paths curretly loaded modules are loaded from:
awk '{ print $1 }' /proc/modules | xargs modinfo -n | sort
I needed this to create a minimal kernel image containg only the modules i really need.
Unfortunately lsmod only displays the name field which does not alwys match the modules# file name (e.g phy-am335x-control.ko and phy_am335x_control).
I hope this helps.

You can use "locate" or "find" command on these modules to find where they are , for example
[root#localhost core_src]# lsmod
Module Size Used by
iptable_filter 2793 0
ipt_MASQUERADE 2466 1
iptable_nat 6158 1
vmware_balloon 7199 0
i2c_piix4 12608 0
i2c_core 31276 1 i2c_piix4
shpchp 33482 0
ext4 371331 2
mbcache 8144 1 ext4
jbd2 93312 1 ext4
sd_mod 39488 4
crc_t10dif 1541 1 sd_mod
sr_mod 16228 0
cdrom 39803 1 sr_mod
mptspi 17051 3
mptscsih 36828 1 mptspi
mptbase 94005 2 mptspi,mptscsih
scsi_transport_spi 26151 1 mptspi
pata_acpi 3701 0
ata_generic 3837 0
ata_piix 22846 0
dm_mirror 14101 0
dm_region_hash 12170 1 dm_mirror
dm_log 10122 2 dm_mirror,dm_region_hash
dm_mod 81692 2 dm_mirror,dm_log
[root#localhost core_src]# locate vmware_balloon
/lib/modules/2.6.32-279.el6.x86_64/kernel/drivers/misc/vmware_balloon.ko

Get the paths from the list of loaded modules. Without the need for awk.
while IFS= read -r line;
do modinfo -n "${line%% *}"
done < /proc/modules | sort

Related

Join of output from DF and LSBLK Linux commands via bash

I need to merge two outputs in Linux.
This:
lsblk -n -b --output KNAME,NAME,SIZE,MOUNTPOINT | grep -v "fd0" | grep -v "loop" | grep -v "sr0" | grep -v "hdc" | grep -v "cdrom"
In a result I have:
sda sda 53687091200
sda1 └─sda1 53684994048
dm-3 └─dockerVG-rootLV 53682896896 /
sdb sdb 2147483648000
sdb1 └─sdb1 2147482599424
dm-1 ├─hddVG-dockerLV 536866717696 /var/lib/docker
dm-2 └─hddVG-hddLV 1610612736000 /dockerhdd
sdc sdc 536870912000
sdc1 └─sdc1 536869863424
dm-0 └─ssdVG-ssdLV 536866717696 /dockerssd
And this:
df --exclude={tmpfs,devtmpfs,squashfs,overlay} | sed -e /^Filesystem/d | awk '{print $6 " " $1 " " $3 " " $4 " " $5}'
In a result I have:
/ /dev/mapper/dockerVG-rootLV 8110496 40591632 17%
/dockerssd /dev/mapper/ssdVG-ssdLV 214133656 274642488 44%
/dockerhdd /dev/mapper/hddVG-hddLV 83278236 1385191240 6%
/var/lib/docker /dev/mapper/hddVG-dockerLV 76046204 412729940 16%
So, I want to Join via these points /, /var/lib/docker, /dockerhdd, /dockerssd.
Important! I want to check this in another place, where we will have another mount points. Also I have to save structure of first output without sorting.
In a result I have to receive something like this:
sda sda 53687091200
sda1 └─sda1 53684994048
dm-3 └─dockerVG-rootLV 53682896896 / /dev/mapper/dockerVG-rootLV 8110496 40591632 17%
sdb sdb 2147483648000
sdb1 └─sdb1 2147482599424
dm-1 ├─hddVG-dockerLV 536866717696 /var/lib/docker /dev/mapper/hddVG-dockerLV 76046204 412729940 16%
dm-2 └─hddVG-hddLV 1610612736000 /dockerhdd /dev/mapper/hddVG-hddLV 83278236 1385191240 6%
sdc sdc 536870912000
sdc1 └─sdc1 536869863424
dm-0 └─ssdVG-ssdLV 536866717696 /dockerssd /dev/mapper/ssdVG-ssdLV 214133656 274642488 44%
Of course better to have one-liner, but if it is not possible, we can send output to separate files and join them. Could You please help me in this ?
Using awk:
awk '!/^\/&^fd0&^loop&^sr0&^hdc&^cdrom/ { print $0" "arr[$4] } /^Filesystem/ { mrk=1;next } mrk==1 && /^\// { arr[$1]=$0 }' <<< $(df --exclude={tmpfs,devtmpfs,squashfs,overlay};lsblk -n -b --output KNAME,NAME,SIZE,MOUNTPOINT)
Redirect the two commands back into awk, stripping out any grep and sed processing. We process the df command first and where we find a line beginning with "Filesystem" we set a marker (mrk) to 1 and move to the next line. We then create an array (arr) indexed with the mountpoint and containing the line returned from the df command. We move onto the lsblk command and search for the lines starting with the KNAMEs required. We print the line from the lsblk command and append the value in the arr array indexed by the mount point ($4)

Run program on boot with initramfs

I'm running uClinux on a SmartFusion2 as part of a University team building a small cube satellite. However, I'm not super experienced in Linux kernel, and this issue has had me stumped for a few days. I'm trying to get the SmartFusion to run a program on bootup. Currently, the only .uImage that does this is the test 'hello' file. I'm trying to recreate the process for another program, but am running into some difficulties.
in my hello directory I have the following files: hello.busybox, hello.kernel.M2S, help.txt, hello.uImage, Makefile, hello.initramfs, hello (directory)
in the hello subdirectory (projects/hello/hello):
hello (executable), hello.c, hello.gdb, hello.h, hello.o, Makefile
to try and get the uImage to boot and run a different program, I made a copy of my projects/hello/hello directory and renamed it 'goodbye', with a few minor changes int the .h and .c files for testing purposes. Now I'm trying to get the executable 'hello' in projects/hello/goodbye to run on boot.
My initramfs file originally looked like this:
# This is a very simple, default initramfs
dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
nod /dev/tty 0666 0 0 c 5 0
nod /dev/null 0600 0 0 c 1 3
nod /dev/mem 0600 0 0 c 1 1
nod /dev/kmem 0600 0 0 c 1 2
nod /dev/zero 0600 0 0 c 1 5
nod /dev/random 0600 0 0 c 1 8
nod /dev/urandom 0600 0 0 c 1 9
dir /dev/pts 0755 0 0
nod /dev/ptmx 0666 0 0 c 5 2
nod /dev/ttyS0 0666 0 0 c 4 64
nod /dev/ttyS1 0666 0 0 c 4 65
nod /dev/ttyS2 0666 0 0 c 4 66
nod /dev/ttyS3 0666 0 0 c 4 67
nod /dev/ttyS4 0666 0 0 c 4 68
nod /dev/ttyS5 0666 0 0 c 4 69
dir /bin 755 0 0
dir /proc 755 0 0
file /bin/hello ${INSTALL_ROOT}/projects/${SAMPLE}/hello/hello 755 0 0
slink /bin/init hello 777 0 0
I changed the last two lines of the initramfs to read as follows:
file /bin/hello ${INSTALL_ROOT}/projects/${SAMPLE}/hello/goodbye 755 0 0
slink /bin/init hello 777 0 0
But when I try and boot the SmartFusion2 after remaking the uImage, I get this, witht the error at the bottom:
Starting kernel ...
Linux version 2.6.33-arm1 (ecenstudent#EE10308) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #38 Thu May 25 09:09:08 MDT 2017
CPU: ARMv7-M Processor [412fc231] revision 1 (ARMv7M)
CPU: NO data cache, 8K instruction cache
Machine: Microsemi M2S
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: m2s_platform=m2s-fg484-som console=ttyS0,115200 panic=10 ip=10.2.118.102:10.2.118.101:192.168.0.1::m2s-fg484-som:eth0:off ethaddr=3C:FB:96:05:00:53
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 64408k/64408k available, 1128k reserved, 0K highmem
Virtual kernel memory layout:
vector : 0x00000000 - 0x00001000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
vmalloc : 0x00000000 - 0xffffffff (4095 MB)
lowmem : 0xa0000000 - 0xa4000000 ( 64 MB)
modules : 0xa0000000 - 0x01000000 (1552 MB)
.init : 0xa0008000 - 0xa0012000 ( 40 kB)
.text : 0xa0074bc0 - 0xa0083000 ( 58 kB)
.data : 0xa0084000 - 0xa008cce0 ( 36 kB)
Hierarchical RCU implementation.
NR_IRQS:83
Calibrating delay loop... 132.30 BogoMIPS (lpj=661504)
Mount-cache hash table entries: 512
Switching to clocksource mss_timer2
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x40000000 (irq = 10) is a 16550A
console [ttyS0] enabled
serial8250.1: ttyS1 at MMIO 0x40010000 (irq = 11) is a 16550A
Freeing init memory: 40K
Kernel panic - not syncing: No init found. Try passing init= option to kernel.
Backtrace: no frame pointer
Rebooting in 10 seconds..
Can somebody help explain why this is happening and what I need to do to my initramfs to make it run the proper program on boot? Thanks!!
As it turns out, I was confused about how those two lines worked. When I finally figured it out, they looked like this:
file /bin/hello ${INSTALL_ROOT}/projects/${SAMPLE}/goodbye/hello 755 0 0
slink /bin/init hello 777 0 0
then it worked as desired, and I was able to implement it into other uImages.

raspberry does not play any sound (Raspbian)

I cannot get any sound out from my raspi.
I have another SD with XBian and XBMC running so HW problem is discarted.
this is my lsmod
pi#cacharro ~ $ lsmod
Module Size Used by
snd_bcm2835 16165 0
snd_soc_bcm2708_i2s 5474 0
regmap_mmio 2806 1 snd_soc_bcm2708_i2s
snd_soc_core 131268 1 snd_soc_bcm2708_i2s
regmap_spi 1897 1 snd_soc_core
snd_pcm 81593 2 snd_bcm2835,snd_soc_core
snd_page_alloc 5156 1 snd_pcm
regmap_i2c 1645 1 snd_soc_core
snd_compress 8076 1 snd_soc_core
snd_seq 53769 0
snd_timer 20133 2 snd_pcm,snd_seq
evdev 9419 2
snd_seq_device 6473 1 snd_seq
leds_gpio 2059 0
led_class 3688 1 leds_gpio
snd 61291 7
snd_bcm2835,snd_soc_core,snd_timer,snd_pcm,snd_seq,snd_seq_device,snd_compress
I tried speaker-test -t sine -f 600 , nothing sounds.
I tried with HDMI, with headphones and with both at the same time. Nothing.
alsa-utils is installed
I want to play midi using ZynSubAddFX.
Any clue ?? Any extra details that may be useful ??
I finally bought a 1.34€ USB sound card, is not an ideal solution but I got quality audio and mic line for the same price :)

How to get file creation date/time in Bash/Debian?

I'm using Bash on Debian GNU/Linux 6.0. Is it possible to get the file creation date/time? Not the modification date/time.
ls -lh a.txt and stat -c %y a.txt both only give the modification time.
Unfortunately your quest won't be possible in general, as there are only 3 distinct time values stored for each of your files as defined by the POSIX standard (see Base Definitions section 4.8 File Times Update)
Each file has three distinct associated timestamps: the time of last
data access, the time of last data modification, and the time the file
status last changed. These values are returned in the file
characteristics structure struct stat, as described in <sys/stat.h>.
EDIT: As mentioned in the comments below, depending on the filesystem used metadata may contain file creation date. Note however storage of information like that is non standard. Depending on it may lead to portability problems moving to another filesystem, in case the one actually used somehow stores it anyways.
ls -i file #output is for me 68551981
debugfs -R 'stat <68551981>' /dev/sda3 # /dev/sda3 is the disk on which the file exists
#results - crtime value
[root#loft9156 ~]# debugfs -R 'stat <68551981>' /dev/sda3
debugfs 1.41.12 (17-May-2010)
Inode: 68551981 Type: regular Mode: 0644 Flags: 0x80000
Generation: 769802755 Version: 0x00000000:00000001
User: 0 Group: 0 Size: 38973440
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 76128
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x526931d7:1697cce0 -- Thu Oct 24 16:42:31 2013
atime: 0x52691f4d:7694eda4 -- Thu Oct 24 15:23:25 2013
mtime: 0x526931d7:1697cce0 -- Thu Oct 24 16:42:31 2013
**crtime: 0x52691f4d:7694eda4 -- Thu Oct 24 15:23:25 2013**
Size of extra inode fields: 28
EXTENTS:
(0-511): 352633728-352634239, (512-1023): 352634368-352634879, (1024-2047): 288392192-288393215, (2048-4095): 355803136-355805183, (4096-6143): 357941248-357943295, (6144
-9514): 357961728-357965098
mikyra's answer is good. The fact just like what he said.
[jason#rh5 test]$ stat test.txt
File: `test.txt'
Size: 0 Blocks: 8 IO Block: 4096 regular empty file
Device: 802h/2050d Inode: 588720 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 500/ jason) Gid: ( 500/ jason)
Access: 2013-03-14 01:58:12.000000000 -0700
Modify: 2013-03-14 01:58:12.000000000 -0700
Change: 2013-03-14 01:58:12.000000000 -0700
if you want to verify, which file was created first, you can structure your file name by appending system date when you create a series of files.
Note that if you've got your filesystem mounted with noatime for performance reasons, then the atime will likely show the creation time. Given that noatime results in a massive performance boost (by removing a disk write for every time a file is read), it may be a sensible configuration option that also gives you the results you want.
Creation date/time is normally not stored. So no, you can't.
You can find creation time - aka birth time - using stat and also match using find.
We have these files showing last modified time:
$ ls -l --time-style=long-iso | sort -k6
total 692
-rwxrwx---+ 1 XXXX XXXX 249159 2013-05-31 14:47 Getting Started.pdf
-rwxrwx---+ 1 XXXX XXXX 275799 2013-12-30 21:12 TheScienceofGettingRich.pdf
-rwxrwx---+ 1 XXXX XXXX 25600 2015-05-07 18:52 Thumbs.db
-rwxrwx---+ 1 XXXX XXXX 148051 2015-05-07 18:55 AsAManThinketh.pdf
To find files created within a certain time frame using find as below.
Clearly, the filesystem knows about the birth time of a file:
$ find -newerBt '2014-06-13' ! -newerBt '2014-06-13 12:16:10' -ls
20547673299906851 148 -rwxrwx--- 1 XXXX XXXX 148051 May 7 18:55 ./AsAManThinketh.pdf
1407374883582246 244 -rwxrwx--- 1 XXXX XXXX 249159 May 31 2013 ./Getting\ Started.pdf
We can confirm this using stat:
$ stat -c "%w %n" * | sort
2014-06-13 12:16:03.873778400 +0100 AsAManThinketh.pdf
2014-06-13 12:16:04.006872500 +0100 Getting Started.pdf
2014-06-13 12:16:29.607075500 +0100 TheScienceofGettingRich.pdf
2015-05-07 18:32:26.938446200 +0100 Thumbs.db
stat man pages explains %w:
%w time of file birth, human-readable; - if unknown
ls -i menus.xml
94490 menus.xml
Here the number 94490 represents inode
Then do a:
df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg-root 4.0G 3.4G 408M 90% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/sda1 124M 27M 92M 23% /boot
/dev/mapper/vg-var 7.9G 1.1G 6.5G 15% /var
To find the mounting point of the root "/" filesystem, because the file menus.xml is on '/' that is '/dev/mapper/vg-root'
debugfs -R 'stat <94490>' /dev/mapper/vg-root
The output may be like the one below:
debugfs -R 'stat <94490>' /dev/mapper/vg-root
debugfs 1.41.12 (17-May-2010)
Inode: 94490 Type: regular Mode: 0644 Flags: 0x0
Generation: 2826123170 Version: 0x00000000
User: 0 Group: 0 Size: 4441
File ACL: 0 Directory ACL: 0
Links: 1 Blockcount: 16
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x5266e438 -- Wed Oct 23 09:46:48 2013
atime: 0x5266e47b -- Wed Oct 23 09:47:55 2013
mtime: 0x5266e438 -- Wed Oct 23 09:46:48 2013
Size of extra inode fields: 4
Extended attributes stored in inode body:
selinux = "unconfined_u:object_r:usr_t:s0\000" (31)
BLOCKS:
(0-1):375818-375819
TOTAL: 2
Where you can see the creation time:
ctime: 0x5266e438 -- Wed Oct 23 09:46:48 2013
stat -c %w a.txt
%w returns the file creation(birth) date if it is available, which is rare.
Here's the link
As #mikyra explained, creation date time is not stored anywhere.
All the methods above are nice, but if you want to quickly get only last modify date, you can type:
ls -lit /path
with -t option you list all file in /path odered by last modify date.
If you really want to achieve that you can use a file watcher like inotifywait.
You watch a directory and you save information about file creations in separate file outside that directory.
while true; do
change=$(inotifywait -e close_write,moved_to,create .)
change=${change#./ * }
if [ "$change" = ".*" ]; then ./scriptToStoreInfoAboutFile; fi
done
As no creation time is stored, you can build your own system based on inotify.
Cited from https://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/131347#131347 , the following shellscript would work to get creation time:
get_crtime() {
for target in "${#}"; do
inode=$(stat -c %i "${target}")
fs=$(df "${target}" | tail -1 | awk '{print $1}')
crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | grep -oP 'crtime.*--\s*\K.*')
printf "%s\t%s\n" "${target}" "${crtime}"
done
}
even better:
lsct ()
{
debugfs -R 'stat <'`ls -i "$1" | (read a b;echo -n $a)`'>' `df "$1" | (read a; read a b; echo "$a")` 2> /dev/null | grep --color=auto crtime | ( read a b c d;
echo $d )
}
lsct /etc
Wed Jul 20 19:25:48 2016
Another trick to add to your arsenal is the following:
$ grep -r "Copyright" /<path-to-source-files>/src
Generally speaking, if one changes a file they should claim credit in the “Copyright”. Examine the results for dates, file names, contributors and contact email.
example grep result:
/<path>/src/someobject.h: * Copyright 2007-2012 <creator's name> <creator's email>(at)<some URL>>

How to find user memory usage in linux

How i can see memory usage by user in linux centos 6
For example:
USER USAGE
root 40370
admin 247372
user2 30570
user3 967373
This one-liner worked for me on at least four different Linux systems with different distros and versions. It also worked on FreeBSD 10.
ps hax -o rss,user | awk '{a[$2]+=$1;}END{for(i in a)print i" "int(a[i]/1024+0.5);}' | sort -rnk2
About the implementation, there are no shell loop constructs here; this uses an associative array in awk to do the grouping & summation.
Here's sample output from one of my servers that is running a decent sized MySQL, Tomcat, and Apache. Figures are in MB.
mysql 1566
joshua 1186
tomcat 353
root 28
wwwrun 12
vbox 1
messagebus 1
avahi 1
statd 0
nagios 0
Caveat: like most similar solutions, this is only considering the resident set (RSS), so it doesn't count any shared memory segments.
EDIT: A more human-readable version.
echo "USER RSS PROCS" ; echo "-------------------- -------- -----" ; ps hax -o rss,user | awk '{rss[$2]+=$1;procs[$2]+=1;}END{for(user in rss) printf "%-20s %8.0f %5.0f\n", user, rss[user]/1024, procs[user];}' | sort -rnk2
And the output:
USER RSS PROCS
-------------------- -------- -----
mysql 1521 1
joshua 1120 28
tomcat 379 1
root 19 107
wwwrun 10 10
vbox 1 3
statd 1 1
nagios 1 1
messagebus 1 1
avahi 1 1
Per-user memory usage in percent using standard tools:
for _user in $(ps haux | awk '{print $1}' | sort -u)
do
ps haux | awk -v user=${_user} '$1 ~ user { sum += $4} END { print user, sum; }'
done
or for more precision:
TOTAL=$(free | awk '/Mem:/ { print $2 }')
for _user in $(ps haux | awk '{print $1}' | sort -u)
do
ps hux -U ${_user} | awk -v user=${_user} -v total=$TOTAL '{ sum += $6 } END { printf "%s %.2f\n", user, sum / total * 100; }'
done
The first version just sums up the memory percentage for each process as reported by ps. The second version sums up the memory in bytes instead and calculates the total percentage afterwards, thus leading to a higher precision.
If your system supports, try to install and use smem:
smem -u
User Count Swap USS PSS RSS
gdm 1 0 308 323 820
nobody 1 0 912 932 2240
root 76 0 969016 1010829 1347768
or
smem -u -t -k
User Count Swap USS PSS RSS
gdm 1 0 308.0K 323.0K 820.0K
nobody 1 0 892.0K 912.0K 2.2M
root 76 0 937.6M 978.5M 1.3G
ameskaas 46 0 1.2G 1.2G 1.5G
124 0 2.1G 2.2G 2.8G
In Ubuntu, smem can be installed by typing
sudo apt install smem
This will return the total ram usage by users in GBs, reverse sorted
sudo ps --no-headers -eo user,rss | awk '{arr[$1]+=$2}; END {for (i in arr) {print i,arr[i]/1024/1024}}' | sort -nk2 -r
You can use the following Python script to find per-user memory usage using only sys and os module.
import sys
import os
# Get list of all users present in the system
allUsers = os.popen('cut -d: -f1 /etc/passwd').read().split('\n')[:-1]
for users in allUsers:
# Check if the home directory exists for the user
if os.path.exists('/home/' + str(users)):
# Print the current usage of the user
print(os.system('du -sh /home/' + str(users)))

Resources