Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

du: Follow symlinks if symlink points to outside directories, don't follow otherwise

Tags:

bash

perl

I wonder whether there's some rather simple shell incantation to calculate the disk usage of a directory (using the du command) but with the following requirements: symlinks that point to files/subdirectories inside the directory should not be followed, but symlinks to outside files/subdirectories should. Or whether I need to do some scripting to accomplish this.

like image 653
Perl Ancar Avatar asked Jan 13 '19 13:01

Perl Ancar


People also ask

How do you follow a symbolic link?

In order to follow symbolic links, you must specify ls -L or provide a trailing slash. For example, ls -L /etc and ls /etc/ both display the files in the directory that the /etc symbolic link points to. Other shell commands that have differences due to symbolic links are du, find, pax, rm and tar.

Does du follow symlink?

The -L option tells du to process symbolic links by using the file or directory which the symbolic link references, rather than the link itself.

Can a symlink point to a directory?

In computing, a symbolic link (also symlink or soft link) is a file whose purpose is to point to a file or directory (called the "target") by specifying a path thereto. Symbolic links are supported by POSIX and by most Unix-like operating systems, such as FreeBSD, Linux, and macOS.

Can a symbolic link point to another symbolic link?

Yes. You can only stack so much symbolic links together before the kernel and/or application refuse to follow the chain.


1 Answers

Unless I have missed something in your question, du already does that when instructed to follow symlinks (-L).

I got two trees:

tree1/:

├── dir1
│   └── file
├── dirA -> ../tree2/dirA
└── link1 -> dir1

and tree2/:

.
└── dirA
    └── file

File is in both cases 1MB in size.

Now run du -shL on tree1/:

$ du -shL tree1
2.0M    tree1

While file can be seen three times in tree1/ when following symlinks:

$ find tree1 -follow -type f
tree1/dirA/file
tree1/link1/file
tree1/dir1/file

It only counted twice towards the total. Namely once from tree1/ and once linked in from tree2/dirA/ (or what I understood as you meaning from outside / not being sub-directories of tree1/).

It would also seem to make sense, because being links inside the same tree, they do not really consume additional disk space (beyond the symlink entry).


I've also grown the tree1 a bit to:

.
├── dir1
│   └── file
├── dir2
│   └── file -> ../dir1/file
├── dirA -> ../tree2/dirA
└── link1 -> dir1

And ran:

$ du -abcL .
1048576 ./dir2/file
1048636 ./dir2
1048576 ./dirA/file
1048636 ./dirA
60      ./link1
2097452 .
2097452 total

As you can see, links only count towards total / size of . with size of link entry (even though I admit 60 confuses me a but, I'd expect 4) and not (dereferenced) content of the file they point to.

Is this what you wanted or close enough?

like image 79
Ondrej K. Avatar answered Sep 19 '22 09:09

Ondrej K.