a couple of months ago, some semi-famous video game vlogger i’ve never heard of decided to get up on the linux soap box and rally his followers to ditch windows.
this was one of those viral-level, meme-type event things, and the result was a literal flood of screenshots of ‘riced’ desktops. and while each of those arch-newbie screeners was different than the last, they all had one common element: a terminal running neofetch
.
this article is not going to be about neofetch
specifically, but rather about the concepts and commands under neofetch
‘s hood. we’re not going to rebuild this command, or go over it line-by-line. instead, we’re going to look at the basic tools we can use to inspect our linux system. by the end, we should be able to learn everything we want to about our linux-like system using standard, built-in commands and files. no neofetch
required.

inspecting our os with uname
uname
stands for ‘unix name’ and, not surprisingly, it’s job is to give us the name of our operating system. but it also does a lot more. let’s start with the name:
$ uname -o GNU/Linux
the -o
switch here tells uname
to tell us about the ‘operating system’. the response is simple, but accurate: GNU/Linux.
if we want to get some basic information on our system’s ‘processor’, we use the -p
switch.
$ uname -p x86_64
getting the exact kernel version we’re running is accomplished with -r
.
$ uname -r 6.12.10-76061203-generic
files with more useful os information
the data from
the os-release
file
the /etc/os-release
file contains a lot of data about our system. this file is part of the systemd
standard and has been around since 2012, so if you’re running a moderately modern linux-like operating system with systemd
, it will be there.
let’s look at an example of its contents:
NAME="Pop!_OS" VERSION="22.04 LTS" ID=pop ID_LIKE="ubuntu debian" PRETTY_NAME="Pop!_OS 22.04 LTS" VERSION_ID="22.04" HOME_URL="https://pop.system76.com" SUPPORT_URL="https://support.system76.com" BUG_REPORT_URL="https://github.com/pop-os/pop/issues" PRIVACY_POLICY_URL="https://system76.com/privacy" VERSION_CODENAME=jammy UBUNTU_CODENAME=jammy LOGO=distributor-logo-pop-os
from this file, we can see that the user here is running pop_os 22.04. that’s some useful information!
the lsb-release
file
an alternative to the os-release
file is /etc/lsb-release
. the ‘lsb’ here stands for ‘linux standard base’ which was an attempt made many years ago to unify and standardize all sorts of things across the various linux distros. stuff like the filesystem hierarchy, library versions, run levels and the like.
like most attempts at unification and standardization, it fell apart and lsb hasn’t been a going concern for over ten years now. however, there’s still a lot of lsb stuff lingering around in modern distros, and it’s useful.
let’s look at some sample output of /etc/lsb-release
:
DISTRIB_ID=Pop DISTRIB_RELEASE=22.04 DISTRIB_CODENAME=jammy DISTRIB_DESCRIPTION="Pop!_OS 22.04 LTS"
exactly the sort of data we want.
our system may also include the binary lsb_release
(mileage may vary). if it does, we can run it like so:
$ lsb_release -a No LSB modules are available. Distributor ID: Pop Description: Pop!_OS 22.04 LTS Release: 22.04 Codename: jammy

learning about memory with free
memory is complicated stuff. the traditional way to find out about free and used memory was to look in the /proc/meminfo
file, but it’s an absolute mess in there.
if you want to stick with tradition, you can use grep
to get just the ‘good bits’ from /proc/meminfo
. something like this:
$ cat /proc/meminfo | grep -i "MemTotal\|MemFree" MemTotal: 45141040 kB MemFree: 6225932 kB
the alternative is to use the free
command, which reports on ‘free’ memory:
$ free -h total used free shared buff/cache available Mem: 43Gi 11Gi 6.0Gi 396Mi 25Gi 27Gi Swap: 19Gi 6.5Gi 13Gi
here we have passed the -h
switch, which stands for ‘human readable’, ie megabytes and gigabytes instead of just raw kb.
there are two rows in the standard output: ‘Mem’ for physical, installed memory, and ‘Swap’ for swap space. if you don’t have a ‘Swap’ row, you should probably fix that. we’ll focus on physical memory.
the two columns we’re probably the most interested in are ‘total’ (the total amount of installed memory) and ‘free’.
‘free’ is calculated by adding the ‘used’ memory and the ‘buffer/cache’ memory and subtracting it from the total. this means that ‘used’ plus ‘buffer/cache’ plus ‘free’ adds up to our total memory:
$ free | grep 'Mem' | awk '{print $2 " = "$3" + "$4" + "$6}' 45141040 = 12235120 + 6080968 + 26824952 $ expr 12235120 + 6080968 + 26824952 45141040
and it does.
inspecting our hardware with lshw
the command lshw
‘s long name is ‘hardware listener’, but everybody just says ‘list hardware’ instead because that’s what it does: it lists all our machine’s hardware.
let’s run it with the -short
argument:
lshw -short
the output of this is a short description of every piece of hardware in our box. everything from our motherboard to our mouse to our cd burner, if we’re old enough to still have such a thing. if we want to, we can apply a little grep
to filter for the information we need. for instance, to get just our processor and cdrom drive we could do:
$ sudo lshw -short | grep -i "processor\|cdrom" /0/4 processor Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz /0/100/1d/1/1/3/0.0.0 /dev/cdrom disk DVDRAM GP65NB60
if we run lshw -short
and look a the top line of the output, we see that the columns have these headings:
H/W path Device Class Description ======================================================
if we want to do a more detailed exploration of our hardware, we will use the value under ‘Class’. so, for instance, for our cpu, the class is ‘processor’.
to inspect the hardware class, we use the -C
switch and the class name like so:
$ lshw -C processor *-cpu product: Intel(R) Core(TM) i7-4820K CPU @ 3.70GHz vendor: Intel Corp. physical id: 1 bus info: cpu@0 version: 6.62.4 size: 1200MHz capacity: 3900MHz width: 64 bits capabilities: fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp x86-64 constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d cpufreq configuration: microcode=1070
that’s a lot of information about our cpu.
we can do this with any class that lshw
lists. for instance, if we want info on our video card, we can query the class ‘display’ (with a little bit of grep
to cut out the noise)
$ lshw -C display | grep "product\|vendor" product: GP104 [GeForce GTX 1070] vendor: NVIDIA Corporation
getting info about hard disks with df
we can get some basic, but useful information about our hard drives using the df
command. ‘df’ here stands for ‘disk free’ because most people use it to find out how much free space they have, but it does more than that. let’s look at some truncated sample output:
$ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 4.4G 2.5M 4.4G 1% /run /dev/sda1 1.8T 791G 946G 46% / 192.168.1.70:/volume1/music 3.6T 457G 3.2T 13% /mnt/music
in this example we’ve run df
with the -h
switch to use ‘human readable’ units.
from this we can see that there is one 1.8 terabyte hard drive mounted on the root partition and it’s 46% full. there’s also a network drive mounted on mnt/music
.
for most purposes, this level of detail is sufficient. however, if we want a bit more, we can use lsblk
to list all our ‘block devices’.
lsblk
the output of this command will show drives (including things like our cdrom) and their partitions. it will also show every single snap we have installed as a device.
if we want to know the filesystems of our drives, we can pass the --fs
switch
lsblk --fs
finding our screen resolution
if we want to get our current screen resolutions and all possible supported resolutions, we can use xrandr
.
as that ‘x’ at the beginning of the name implies, xrandr
is an xwindow tool. if we are using wayland, instead, we’ll need to find an alternate solution such as wlr-randr
running xrander
gives us the following output:
$ xrandr Screen 0: minimum 8 x 8, current 2560 x 1440, maximum 32767 x 32767 DVI-D-0 disconnected (normal left inverted right x axis y axis) HDMI-0 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 697mm x 392mm 3840x2160 60.00 + 59.94 50.00 30.00 29.97 25.00 23.98 2560x1440 59.95* 1920x1080 60.00 59.94 50.00 29.97 23.98 1680x1050 59.95 1600x900 60.00 1440x900 59.89 1280x1024 75.02 60.02 1280x800 59.81 1280x720 60.00 59.94 50.00 1152x864 75.00 1024x768 75.03 70.07 60.00 800x600 75.00 72.19 60.32 56.25 720x576 50.00 720x480 59.94 640x480 75.00 72.81 59.94
here we can see that our current resolution is 2560×1440. there’s also a lengthy output of supported resolutions.
deducing our desktop environment
lots of people use graphical desktop environments in linux, so finding out what’s being run is probably important. we can get that information from the $XDG_CURRENT_DESKTOP
environmental variable:
$ echo $XDG_CURRENT_DESKTOP pop:GNOME
once we know what desktop environment is being run, we can call it directly to get the version number:
$ gnome-shell --version GNOME Shell 42.9
for kde, we would use:
plasmashell --version
other desktop environments will have their own commands that accept the --version
argument.
getting the current shell
the default shell of the current user is stored in the $SHELL
environmental variable. we can access it like this:
$ echo $SHELL /usr/bin/fish
if we want to retrieve the version of the shell, we can use $SHELL
as an executable and pass the --version
argument
$ $SHELL --version fish, version 3.7.1
if we need to get the shell for a user other than the one we are logged in as, we can always retrieve it from the /etc/passwd
file:
$ cat /etc/passwd | grep ghorwood ghorwood:x:1000:1000:grant horwood:/home/ghorwood:/usr/bin/fish
finding up time with uptime
it’s a ridiculous point of pride for some linux users that they never have to reboot their machines. we can find out how long our box has been up and running with the uptime
command:
$ uptime -p up 2 weeks, 4 days, 18 hours
eighteen days isn’t bad.
Conclusion
neofetch is a useful and fun tool, but learning how it finds data about our machine gives us a better understanding of our operating system.
co-founder of fruitbat studios. cli-first linux snob, metric evangelist, unrepentant longhair. all the music i like is objectively horrible. he/him.