The most commonly used command to query the contents of directories is ls. Run without any arguments, it just shows the contents of the present working directory:
root:/var/run> ls
abrt chronyd.pid faillock libvirt mdadm
alsactl.pid console fsck libvirtd.pid mount
atd.pid crond.pid gdm lock mysqld
auditd.pid cron.reboot gssproxy.pid log netreport
autofs.fifo-misc cups gssproxy.sock lvm NetworkManager
autofs.fifo-net dbus hplip lvmetad.pid openvpn
autofs.pid dhclient-wlo1.pid httpd mariadb plymouth
autofs-running dmeventd-client initramfs mcelog-client ppp
avahi-daemon dmeventd-server libgpod mcelog.pid […]
We can also give it one or more directories as arguments so that it lists their contents:
root:/var/run> ls /var/run /var/local
/var/local/:
rsync2nfs.exc
.
/var/run:
abrt chronyd.pid faillock libvirt mdadm
alsactl.pid console fsck libvirtd.pid mount
atd.pid crond.pid gdm lock mysqld
auditd.pid cron.reboot gssproxy.pid log netreport
autofs.fifo-misc cups gssproxy.sock lvm NetworkManager
autofs.fifo-net dbus hplip lvmetad.pid openvpn
autofs.pid dhclient-wlo1.pid httpd mariadb plymouth
autofs-running dmeventd-client initramfs mcelog-client ppp
avahi-daemon dmeventd-server libgpod mcelog.pid […]
Some of the less common options would be:
marc:/usr/bin> ls -l --
blocksize=k /usr/bin → size can be k, k or g but it’ll be rounded up!
total 285712K
-rwxr-xr-x. 1 root root 41K May 14 14:06 [
-rwxr-xr-x. 1 root root 12K Jan 20 2015 411toppm
lrwxrwxrwx. 1 root root 1K Dec 22 2014 4pane > 4Pane
-rwxr-xr-x. 1 root root 2818K Dec 22 2014 4Pane
-rwxr-xr-x. 1 root root 29K Aug 31 2014 a52dec
-rwxr-xr-x. 1 root root 52K Jul 17 09:04 ab
-rwxr-xr-x. 1 root root 11K Jul 1 07:00 abrtactionanalyzebacktrace
.
marc:/usr/bin> ls -lh → better to use “h” for human readable size
total 280M
-rwxr-xr-x. 1 root root 41K May 14 14:06 [
-rwxr-xr-x. 1 root root 12K Jan 20 2015 411toppm
lrwxrwxrwx. 1 root root 5 Dec 22 2014 4pane > 4Pane
-rwxr-xr-x. 1 root root 2.8M Dec 22 2014 4Pane
-rwxr-xr-x. 1 root root 29K Aug 31 2014 a52dec
-rwxr-xr-x. 1 root root 52K Jul 17 09:04 ab
-rwxr-xr-x. 1 root root 11K Jul 1 07:00 abrtactionanalyzebacktrace
-rwxr-xr-x. 1 root root 11K Jul 1 07:00 abrtactionanalyzec
.
marc:/> ls --
format=across
bin boot dev etc home lib lib64 lost+found media mnt nfs opt oracle proc root
run sbin sl7ora112 srv sys tmp usr var win7
.
marc:/> ls --
format=commas
bin, boot, dev, etc, home, lib, lib64, lost+found, media, mnt, nfs, opt, oracle, proc, root,
run, sbin, sl7ora112, srv, sys, tmp, usr, var, win7
.
marc:/> ls -l --
timestyle=’+%d%M%Y %H:%M:%S’ → same format as date command
total 48
lrwxrwxrwx. 1 root root 7 18332014 12:33:17 bin > usr/bin
dr-xr-xr-x. 5 root root 4096 28082015 09:08:59 boot
drwxr-xr-x. 23 root root 3800 06242015 11:24:07 dev
drwxr-xr-x. 151 root root 8192 07072015 14:07:38 etc
drwxr-xr-x. 6 root root 52 24252015 21:25:20 home
lrwxrwxrwx. 1 root root 7 18332014 12:33:17 lib > usr/lib
lrwxrwxrwx. 1 root root 9 18332014 12:33:17 lib64 > usr/lib64
drwx------
. 2 root root 6 03292014 20:29:57 lost+found
drwxr-xr-x. 2 root root 6 18332014 12:33:17 media
drwxr-xr-x. 2 root root 6 18332014 12:33:17 mnt
.
marc:/> ls -l -g -G → g means “show no owner” and G “no group”
total 48
lrwxrwxrwx. 1 7 Nov 18 2014 bin > usr/bin
dr-xr-xr-x. 5 4096 Sep 28 09:08 boot
drwxr-xr-x. 23 3800 Oct 6 11:24 dev
drwxr-xr-x. 151 8192 Oct 7 14:07 etc
drwxr-xr-x. 6 52 Sep 24 21:25 home
lrwxrwxrwx. 1 7 Nov 18 2014 lib > usr/lib
lrwxrwxrwx. 1 9 Nov 18 2014 lib64 > usr/lib64
drwx------
. 2 6 Dec 3 2014 lost+found
drwxr-xr-x. 2 6 Nov 18 2014 media
drwxr-xr-x. 2 6 Nov 18 2014 mnt
.
root:/var/run> ls -l --
ignore=[bz]* → ignore entries matching the regexp
total 12
drwxr-xr-x. 2 root root 100 Sep 26 17:29 abrt
-rw-------
. 1 root root 11 Sep 26 17:29 alsactl.pid
-rw-r--
r--
. 1 root root 5 Sep 26 17:29 atd.pid
-rw-r--
r--
. 1 root root 5 Sep 26 17:29 auditd.pid
drwxr-xr-x. 2 avahi avahi 80 Sep 26 17:29 avahidaemon
drwxr-xr-x. 2 root root 80 Sep 26 17:29 NetworkManager
.
root:/var/run> ls -l --
ignore=[bz]* -i → “i” shows the inode
total 12
28685 drwxr-xr-x. 2 root root 100 Sep 26 17:29 abrt
23817 -rw-------
. 1 root root 11 Sep 26 17:29 alsactl.pid
26044 -rw-r--
r--
. 1 root root 5 Sep 26 17:29 atd.pid
10201 -rw-r--
r--
. 1 root root 5 Sep 26 17:29 auditd.pid
23762 drwxr-xr-x. 2 avahi avahi 80 Sep 26 17:29 avahidaemon
23179 drwxr-xr-x. 2 root root 80 Sep 26 17:29 NetworkManager
.
root:/var/run> ls -l --
ignore=[bz]* -i -n → “n” shows numeric uid/gid
total 12
28685 drwxr-xr-x. 2 0 0 100 Sep 26 17:29 abrt
23817 -rw-------
. 1 0 0 11 Sep 26 17:29 alsactl.pid
26044 -rw-r--
r--
. 1 0 0 5 Sep 26 17:29 atd.pid
10201 -rw-r--
r--
. 1 0 0 5 Sep 26 17:29 auditd.pid
23762 drwxr-xr-x. 2 70 70 80 Sep 26 17:29 avahidaemon
23179 drwxr-xr-x. 2 0 0 80 Sep 26 17:29 NetworkManager
.
root:/var/run> ls -l --
ignore=[bz]* -p → “p” appends a slash to folders for clarity
total 12
drwxr-xr-x. 2 root root 100 Sep 26 17:29 abrt/
-rw-------
. 1 root root 11 Sep 26 17:29 alsactl.pid
-rw-r--
r--
. 1 root root 5 Sep 26 17:29 atd.pid
-rw-r--
r--
. 1 root root 5 Sep 26 17:29 auditd.pid
drwxr-xr-x. 2 avahi avahi 80 Sep 26 17:29 avahidaemon/
drwxr-xr-x. 2 root root 80 Sep 26 17:29 NetworkManager/
Another nice command to list directory structures and contents is tree:
root:/var/log> tree
.
├── anaconda
│ ├── anaconda.log
│ ├── ifcfg.log
│ ├── journal.log
│ ├── ksscript7d3jGA.log
│ ├── packaging.log
│ ├── program.log
│ └── storage.log
├── audit [error opening dir]
├── boot.log
├── btmp
├── btmp20151001
├── chrony
├── cluster
├── cups
│ ├── access_log
│ ├── page_log
├── intruder_alert.log
├── journal
│ └── 0473177a2c004ba7b87a9bb6ef882163
│ ├── system.journal
│ ├── user1000.journal
│ └── user1001.journal
├── lastlog
[…]
We can use it with a bunch of useful flags:
marc:/var/log> tree -a → shows all files including hidden ones
marc:/var/log> tree -d → shows only the directories
marc:/var/log> tree -f → shows the fullpath for each item
marc:/var/log> tree -L 5 → shows up to 5 levels of subdirectories
marc:/var/log> tree -P [abc]* → shows files/folders matching the given regexp
marc:/var/log> tree -I [abc]* → ignores the files/folders matching the given regexp
marc:/var/log> tree -u → shows the owner
marc:/var/log> tree -g → shows the group
marc:/var/log> tree -s → shows the size in bytes
marc:/var/log> tree -h → shows the size in human readable format
marc:/var/log> tree -du → shows the size of files and cumulative size of directories
marc:/var/log> tree -D → shows the last modification time
marc:/var/log> tree -Dc → shows the last change time
marc:/var/log> tree --
inodes → shows inode numbers
marc:/var/log> tree --
device → shows device numbers
We use du to display the disk utilisation. Without any flags, it will list all the sizes of all the files/directories beneath the present working directory. Most of the time that is not what we need and we usually give it as an argument the filesystem to report:
root:/> du -sh /var
2.5G /var
We used the “-s” to just get a grand total and the “-h” for human readable. Without the “-s” we might get a massive list with all the files & directories:
root:/var/log> du
27444 ./audit
0 ./chrony
0 ./cluster
40 ./cups
0 ./gdm
0 ./glusterfs
0 ./httpd
418140 ./journal/0473177a2c004ba7b87a9bb6ef882163
418144 ./journal
124 ./libvirt/qemu
124 ./libvirt
0 ./ppp
0 ./samba/old
0 ./samba
[…]
458036 .
We can specify what unit size we want to use (b, k, m)…
root> du -sb /var
1582141864 /var
.
root> du -sk /var
1574472 /var
.
root> du -sm /var
1538 /var
And we can exclude files/folders from the calculations with regexp…
root> du -sm --
exclude=”*.log” /var
1523 /var
We can also use du to count the number of inodes…
root:/> du -s --
inodes /var
13720 /var
Often we need to know the free space left in the different filesystems and we use df to do just that:
root:/> df → default format
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 8089464 0 8089464 0% /dev
tmpfs 8100988 41020 8059968 1% /dev/shm
tmpfs 8100988 1204 8099784 1% /run
tmpfs 8100988 0 8100988 0% /sys/fs/cgroup
/dev/mapper/vgroot 7948288 6376692 1571596 81% /
/dev/sdb1 4285612 53716 3991156 2% /tmp
/dev/sda1 487160 9800 477360 3% /boot/efi
/dev/mapper/vghome 31188092 5109112 26078980 17% /home
/dev/mapper/vgvar 3950592 2518644 1431948 64% /var
tmpfs 1620200 36 1620164 1% /run/user/1000
tmpfs 1620200 0 1620200 0% /run/user/0
.
root:/> df -h → human readable format
Filesystem Size Used Avail Use% Mounted on
devtmpfs 7.8G 0 7.8G 0% /dev
tmpfs 7.8G 41M 7.7G 1% /dev/shm
tmpfs 7.8G 1.2M 7.8G 1% /run
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/mapper/vgroot 7.6G 6.1G 1.5G 81% /
/dev/sdb1 4.1G 53M 3.9G 2% /tmp
/dev/sda1 476M 9.6M 467M 3% /boot/efi
/dev/mapper/vghome 30G 4.9G 25G 17% /home
/dev/mapper/vgvar 3.8G 2.5G 1.4G 64% /var
tmpfs 1.6G 36K 1.6G 1% /run/user/1000
tmpfs 1.6G 0 1.6G 0% /run/user/0
.
root:/> df -h -x tmpfs -x devtmpfs → exclude filesystem types tmpfs/devtmpfs
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vgroot 7.6G 6.1G 1.5G 81% /
/dev/sdb1 4.1G 53M 3.9G 2% /tmp
/dev/sda1 476M 9.6M 467M 3% /boot/efi
/dev/mapper/vghome 30G 4.9G 25G 17% /home
/dev/mapper/vgvar 3.8G 2.5G 1.4G 64% /var
.
root:/> df --
inodes -x tmpfs -x devtmpfs → show inodes utilisation
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vgroot 6466160 178893 6287267 3% /
/dev/sdb1 280560 105 280455 1% /tmp
/dev/sda1 0 0 0 /boot/efi
/dev/mapper/vgdatasl7ora112 1572864 13 1572851 1% /sl7ora112
/dev/mapper/vghome 31203328 55548 31147780 1% /home
/dev/mapper/vgvar 3960832 14430 3946402 1% /var
.
root:/> df -h -t xfs → show stats for just XFS filesystems (or ext3, ext4, vfat, etc)
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vgroot 7.6G 6.1G 1.5G 81% /
/dev/mapper/vghome 30G 4.9G 25G 17% /home
/dev/mapper/vgvar 3.8G 2.5G 1.4G 64% /var
Another very handy command is file which shows us what type of file we have:
root:/tmp> file *
2resolv.txt: ASCII text
bin.lst: ASCII text
bla: empty
evince11037: directory
hogsuspend: fifo (named pipe)
insync1000.sock: socket
kdemarc: directory
lost+found: directory
OSL_PIPE_1000_SingleOfficeIPC_795936f7971: socket
security_watchdog.odt: OpenDocument Text
security_watchdog.pdf: PDF document, version 1.4
ssh.pdf: PDF document, version 1.4
strace.log: ASCII text
trip: ELF 64bit LSB executable, x8664, version 1 (SYSV), dynamically
. linked, interpreter /lib64/ldlinuxx8664.so.2, for GNU/Linux
. 2.6.32, BuildID[sha1]=8e0dd6dfdc346d7041dbaa76fd7b, stripped
vmrcplugin: directory
vmwareroot: directory
yum_save_tx.20150925.1246.ahyIix.yumtx: ASCII text, with very long lines
If the file is a binary, we can find out what shared libraries it is linked to with ldd:
root:/tmp> ldd -v /usr/bin/tred
. linuxvdso.so.1 => (0x00007fff88def000)
. libcgraph.so.6 => /lib64/libcgraph.so.6 (0x00007f5c0a571000)
. libcdt.so.5 => /lib64/libcdt.so.5 (0x00007f5c0a36a000)
. libc.so.6 => /lib64/libc.so.6 (0x00007f5c09fac000)
. /lib64/ldlinuxx8664.so.2 (0x000055a9e35a1000)
. Version information:
. /usr/bin/tred:
. libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
. /lib64/libcgraph.so.6:
. libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.7) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.14) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
. /lib64/libcdt.so.5:
. libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
. libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
. /lib64/libc.so.6:
. ldlinuxx8664.so.2 (GLIBC_2.3) => /lib64/ldlinuxx8664.so.2
. ldlinuxx8664.so.2 (GLIBC_PRIVATE) => /lib64/ldlinuxx8664.so.2
If we need to dig out all the details of a certain file, usually from within a script, we can use stat:
marc:~> stat bin.lst
. File: ‘bin.lst’
. Size: 734 Blocks: 8 IO Block: 4096 regular file
Device: fd0ch/64780d Inode: 43552 Links: 1
Access: (0755/rwxrxrx) Uid: ( 1000/ marc) Gid: ( 1000/ marc)
Context: unconfined_u:object_r:user_home_t:s0
Access: 20151007-10:13:46.523433786 +0100
Modify: 20151007-10:13:34.391368582 +0100
Change: 20151007-10:13:34.466368985 +0100
Birth: -
The stat command is extremely useful within scripts as it allows us to extract any of the file properties and format the output in any way we need. First let’s list the properties and then we’ll see some examples:
The valid format sequences for files (without filesystem):
.
%a access rights in octal
%A access rights in human readable form
%b number of blocks allocated (see %B)
%B the size in bytes of each block reported by %b
%C SELinux security context string
%d device number in decimal
%D device number in hex
%f raw mode in hex
%F file type
%g group ID of owner
%G group name of owner
%h number of hard links
%i inode number
%m mount point
%n file name
%N quoted file name with dereference if symbolic link
%o optimal I/O transfer size hint
%s total size, in bytes
%t major device type in hex, for character/block device special files
%T minor device type in hex, for character/block device special files
%u user ID of owner
%U user name of owner
%w time of file birth, humanreadable; if unknown
%W time of file birth, seconds since Epoch; 0 if unknown
%x time of last access, humanreadable
%X time of last access, seconds since Epoch
%y time of last modification, humanreadable
%Y time of last modification, seconds since Epoch
%z time of last change, humanreadable
%Z time of last change, seconds since Epoch
Valid format sequences for file systems:
.
%a free blocks available to nonsuperuser
%b total data blocks in file system
%c total file nodes in file system
%d free file nodes in file system
%f free blocks in file system
%i file system ID in hex
%l maximum length of filenames
%n file name
%s block size (for faster transfers)
%S fundamental block size (for block counts)
%t file system type in hex
%T file system type in human readable form
Let’s see a couple of examples to get the idea of how to use it:
marc:~> stat --
format=”File: %n, inode: %i, User: %U, Group: %G, Perm: %A, Size: %s” bin.lst
File: bin.lst, inode: 43552, User: marc, Group: marc, Perm: rwxrxrx, Size: 734
.
marc:~> stat --
format=”Filesystem: %n, Free inodes: %d, Blocksize: %S” /home
Filesystem: /home, Free inodes: 64780, Blocksize: ?
Sooner or later we shall find ourselves in the position of not being able to unmount a filesystem because some process is using it. Or we will need to find who/what is using a certain file. When that happens we have fuser to save the day:
root:/tmp> fuser /run/libvirtd.pid → who’s accessing this file?
/run/libvirtd.pid: 1475
.
root:/tmp> fuser -ki /tmp/test.1 → kill process accessing file but prompt first
/tmp/test.1: 1203
Kill process 1203 ? (y/N) y
.
root:/tmp> fuser -muv /var → list PID & users using /var in verbose mode
. USER PID ACCESS COMMAND
/var: root kernel mount (root)/var
. root 669 F…m (root)systemdjournal
. root 1032 F…. (root)auditd
. root 1077 F…. (root)gssproxy
. root 1083 F…. (root)firewalld
. root 1103 f…m (root)abrtdumpjourn
. marc 1141 ….m (marc)vlc
. root 1482 ..c.. (root)atd
. root 1509 F…. (root)wpa_supplicant
. nobody 1684 F…. (nobody)dnsmasq
. colord 1816 F…. (colord)colord
. root 1873 F…. (root)packagekitd
[…]
.
root:/tmp> fuser -uv /dev/tty* → list processes using terminals
. USER PID ACCESS COMMAND
/dev/tty: root 31326 f…. (root)less
/dev/tty1: root 1584 F…. (root)Xorg.bin
/dev/tty6: root 1061 F…. (root)systemdlogind
.
root:/tmp> fuser -uv 44525/tcp → list processes using port/protocol
. USER PID ACCESS COMMAND
44525/tcp: marc 2090 F…. (marc)chrome
.
root:/tmp> fuser -uv 51000/udp → list processes using port/protocol
. USER PID ACCESS COMMAND
51000/udp: marc 2090 F…. (marc)chrome
Another tool we can use to find out what process has what file lock is lslocks:
root:/boot> lslocks
COMMAND PID TYPE SIZE MODE M START END PATH
tracker-miner-a 2449 POSIX 60.4M READ 0 1073741826 1073742335 /home/marc/.cache/tracker/meta.db
tracker-miner-a 2449 POSIX 32K READ 0 128 128 /home/marc/.cache/tracker/meta.db-shm
chrome 2883 POSIX 0B WRITE 0 0 0 /home/marc/.config/google-chrome/Default/…
abrtd 1403 POSIX 5B WRITE 0 0 0 /run/abrt/abrtd.pid
libvirtd 1522 POSIX 4B WRITE 0 0 0 /run/libvirtd.pid
tracker-store 2469 POSIX 60.4M READ 0 1073741826 1073742335 /home/marc/.cache/tracker/meta.db
tracker-store 2469 POSIX 32K READ 0 128 128 /home/marc/.cache/tracker/meta.db-shm
tracker-extract 2453 POSIX 60.4M READ 0 1073741826 1073742335 /home/marc/.cache/tracker/meta.db
tracker-extract 2453 POSIX 32K READ 0 128 128 /home/marc/.cache/tracker/meta.db-shm
tracker-miner-u 2461 POSIX 60.4M READ 0 1073741826 1073742335 /home/marc/.cache/tracker/meta.db
tracker-miner-u 2461 POSIX 32K READ 0 128 128 /home/marc/.cache/tracker/meta.db-shm
chrome 2883 POSIX 0B WRITE 0 0 0 /home/marc/.config/google-chrome/Default/…
mysqld 1657 POSIX 128K WRITE 0 0 0 /var/lib/mysql/lostpenguin/lp_commentmeta.ibd
mysqld 1657 POSIX 112K WRITE 0 0 0 /var/lib/mysql/lostpenguin/lp_links.ibd
[…]
The SIZE column shows the file size. The M column indicates whether the lock is mandatory (1) or not (0).
The START/END columns indicates the byte offset of the lock. We can show the blocker (if any) and change the formatting of the output easily with the “-o” flag:
root:/tmp> lslocks -o PATH,COMMAND,PID,TYPE,MODE,M,BLOCKER --
notruncate
PATH COMMAND PID TYPE MODE M BLOCKER
/run/libvirtd.pid libvirtd 1475 POSIX WRITE 0
/run/crond.pid crond 1483 FLOCK WRITE 0
/home/marc/.cache/tracker/meta.db trackerstore 2672 POSIX READ 0
/home/marc/.cache/tracker/meta.dbshm trackerstore 2672 POSIX READ 0
/home/marc/.cache/tracker/meta.db trackerminerf 2666 POSIX READ 0
/home/marc/.cache/tracker/meta.dbshm trackerminerf 2666 POSIX READ 0
/var/lib/ntop/macPrefix.db ntop 14611 FLOCK WRITE 0
/var/lib/ntop/fingerprint.db ntop 14611 FLOCK WRITE 0
/var/lib/ntop/hostSerials.db ntop 14611 FLOCK WRITE 0