in reply to An anomaly with Filesys::DfPortable, I need your eyes
df -k /usr/lib/perl5/5.40/x86_64-cygwin-threads /usr/share/perl5/5.4 +0 ls -ld /usr/lib/perl5/5.40/x86_64-cygwin-threads /usr/share/perl5/5.4 +0
Dave.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: An anomaly with Filesys::DfPortable, I need your eyes
by Fletch (Bishop) on Mar 10, 2026 at 05:30 UTC | |
Another check is to use abs_path from Cwd to check whether they're resolving to the same file perhaps. I use the following shell function:
The cake is a lie. | [reply] [d/l] [select] |
by Intrepid (Curate) on Mar 10, 2026 at 16:26 UTC | |
I ran your code (in Cygwin's shell), Fletch, thanks. My directories are absolute paths:
I tried an idea that occurred to me (and is indirectly suggested by Dave above). The 'nix command du:
I'd say that du is doing something different (and what I want) from what Filesys::DfPortable dfportable is doing. The above question from Dave is on target. The two dirs are on the same filesystem. I was naively believing that I'd get the sum of the usage of each directory tree, not of the entire filesystem containing the directory tree(s). A significant distinction, eh. Despite the use of the term Filesys. Ok, that warrants a duh. – Soren
| [reply] |
|
Re^2: An anomaly with Filesys::DfPortable, I need your eyes
by afoken (Chancellor) on Mar 10, 2026 at 09:18 UTC | |
On Unix (but not on Windows), lstat and stat on the directories can help. (Actually, this works for every file, but df only looks at mountpoints, i.e. directories.)
Running that on a recent debian in a VM shows:
Most stuff is on device 1795, the root filesystem of this VM. /proc is a completely different device (that of the virtual proc filesystem), and so are /run (105) and /sys (100). /var/run is a symlink stored on device 1795 (root filesystem), it points to /run, which is on device 105. Due to the way symlinks work, everything that appears to be in /var/run/ is really in /run. Changing lstat() to stat() allows the system to follow symlinks instead of working on them:
Alexander
-- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-) | [reply] [d/l] [select] |
by Intrepid (Curate) on Mar 12, 2026 at 19:49 UTC | |
Alexander, I want to acknowledge your very substantial reply, I've been busy with other things the last few days and didn't have time to do that. And still don't right now. So, I am going to edit this node when I have time to do your suggestions justice, rather than rush through it. Thanks for your thoughts. EDITOk, I've had a chance to look at Alexander's post, and download and run the code.Here's how the data looks from running your first script, on one of my Gnu/Linux systems. $ perl stat-and-friends.pl /: on device 2082 /bin: on device 2082 (symlink to usr/bin) /sbin: on device 2082 (symlink to usr/sbin) /lib: on device 2082 (symlink to usr/lib) /usr: on device 2082 /usr/bin: on device 2082 /usr/sbin: on device 2082 /usr/lib: on device 2082 /proc: on device 23 /sys: on device 22 /run: on device 25 /tmp: on device 2082 /var/run: on device 2082 (symlink to /run) /var/tmp: on device 2082 So. Interesting. This seems useful for getting a picture of how resources are being allocated to the various filesystems. I don't think I've ever actually used perl's stat or lstat in a program I've written. I'm going to have to remember that perl has these built-in functions and they could be useful. Thanks for waiting a long time for my reply, Alexander :-) – Soren
| [reply] |
by afoken (Chancellor) on Apr 01, 2026 at 23:01 UTC | |
stat and lstat can do another trick, 100% not my invention: Find out if a directory is a mountpoint or not. That trick - once you have seen it - is really obvious, but at least I never thought of it. I'll start slowly: If you look at a directory (on a Unix-like system), it always contains two subdirectory entries named "." and "..", representing the directory itself and its parent directory. Because they both start with a ".", they are hidden by default, but ls -a shows them. I'll also add the -l flag for more details and the -i flag to show inode numbers, and use head to limit the output to just the first few lines:
So, it seems the /usr/bin directory on this Debian VM uses inode 11099, and its parent directory uses inode 18. There is another little detail: "." and ".." are hard links. Their link count is larger than 1, and it must be: "/usr/bin/." is just another name (a hard link) for "/usr/bin", and "/usr/bin/.." is just another name for "/usr". Want to see it?
Compare the inode numbers: Inode 18 is "/usr/." a.k.a. "/usr/bin/..". And inode 11099 is "/usr/bin" a.k.a. "/usr/bin/.". The hard link count also matches. That should not be very surprising. (Having "." and ".." in a directory is not universal, Windows does not always have them.) There is also a stat command that can be invoked from the shell, that just calls the same API functions as stat() or lstat(). So let's look at the output of that tool:
The same boring details, in a different representation. How does it look for /usr?
Old news. How does "/" look like?
What about "/run"?
Already bored? Did you notice that the two Device numbers changed? That's no accident. That's the trick! The device field (first list element returned in perl, st_dev in struct stat in libc) contains the device number (major and minor device number) of the device containing the filesystem. "/", "/usr", and "/usr/bin" are all on device "7,3", which happens to be the root device of this VM. "/run" is on a tmpfs in RAM, using a different device number ("0,106"). So, to test if a directory is a mount point, you compare the device field of the directory with that one of its parent directory. If they are different, the directory is a mount point. But ... - that's not the entire truth:
The root directory is its own parent directory (same inode number 2 for both "." and ".."), so its device field and the one of its parent are always the same. But the root directory is by definition a mount point, where the root device is mounted. So the real condition for a moint point needs to be extended. A directory is a mount point if its device is different from the device of its parent directory, or if directoy and its parent have the same pair of device and inode numbers. There is a mountpoint tool for exactly this test. You can find a very minimal implementation (about 100 lines of commented C code) in busybox. And of course, you could simply use lstat() in perl. Alexander
-- Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-) | [reply] [d/l] [select] |