Reason of a directory size being zero - linux

Was doing some copy operation on a linux machine to the director /misc. and it did not perform well. After digging came to know that size of /misc is 0.
Logs:
[root#gd911-linux-host1 misc]# ls -lrt
total 0
[root#gd911-linux-host1 misc]#
But created a directory myself which empty only & checked its size, showing 4 bytes.
Logs:
[root#gd911-linux-host1 random]# du -sk
4 .
[root#gd911-linux-host1 random]#
Please let me know what is the reason of this.

Both commands are functioning 100% correctly. When you create a directory, for example:
mkdir -p misc
The directory is empty. If you use ls to list the files in the directory, it reports as expected:
$ ls -lrt misc
total 0
Because there are 0 files in the directory. Now when you look at du the disk usage taken by the directory itself, it correctly notes the size of the file (inode, links, etc.) that represents the directory on disk. Example:
$ du -sk misc
4 misc
Rest assured both are working correctly on your system. ls reporting the number of files contained within the directory, and du reporting the actual size that the directory itself takes on disk.

Stricto sensu, a directory cannot be completely empty (on Linux and POSIX systems). It is required to have the two entries for . (the directory itself) and .. (the parent directory). Use ls -als to list all entries in some directory. See ls(1) & stat(1). If using * be aware of globbing by the shell (the shell's globbing for * is skipping file names starting with ., see glob(7))
In particular opendir(3) & readdir(3) will give at least these two . & .. entries (except on failure).
Hence, a directory is always taking some place for those two mandatory entries and for additional metadata (i.e. inode).
Your /misc might have not been filled by previous cp commands perhaps for lack of permissions. Be sure that its owner is appropriate (the one used by cp commands). Check with stat /misc or with ls -ald /misc. Then chmod u+rwx /misc at least (see chmod(1); you could use as root the chown(1) command to change ownership).

Related

Odd behaviour of pwd with symlinks in terminal tabs

If I create a symlink through
ln -s /path/to/linked/dir current/path/link_name
and change the directory to current/path/link_name via
cd link_name
then I can check where I am using pwd-command. The output will be
current/path/link_name
But if I use some terminal emulator, such as terminator, konsole or others, I can split the tab or create a new tab in the same directory. The output of the pwd-command in the newly created tab will be
/path/to/linked/dir
In many cases, this is not convenient. Does anybody know how to change this behaviour in some terminal emulator(s)?
P.S. I also noticed that the output of ls typed from /current/path/link_name is the same as the output of ls typed from /path/to/linked/dir.
You can't. The reason is that you lose the information on how did you get there after the system call has executed. Some terminal emulators and mainly the bash(1) shell try to remember this, and implement pwd as an internal command, to cope with this scenarios. But in general if you try
/bin/pwd
You'll discover that all the information about how did you get to that final directory was lost in the course of time.
Ask yourself how can the /bin/pwd work and how can it determine the directory you are on, and you'll answer yourself the question:
The system maintains a current directory (the pwd command inherits this from its parent shell) in the system data for each process, but to save resources, it only stores the inode number of the directory that is actually your current directory (not actually, it maintains a reference to the in-core inode structure). It doesn't store the path you used to locate it, and it stores that info only to be able to get a starting point when you ask for a relative path when opening a file. The problem is the same as determining which directory a multiple linked file belongs to... no parent directory is stored for a file, as it can be in multiple directories linking to it all at the same time... this is also true for directories, but they have an .. entry inside themselves that links to their parents (their true parents, as one directory is now allowed to belong to different directories by means on normal links, this is forbidden by system, and ensured by the mkdir(2) system call) The pwd(1) commands uses precisely these links to find the parent directory (and then find the current dir in the parent directory, by searching for the inode number of the current directory on it), until this algorithm leads to the same inode (the root directory has this special characteristic, its .. entry points again to itself) so it stops going up. pwd can only work because it is following directories, and never files.
Terminator 1.90 does what you want. In an example session:
$ cd -- "$(mktemp --directory)"
$ mkdir a
$ ln -s a b
$ cd b
Press Ctrl-Shift-e (or o, or t). At this point I'm still in b.

How I can hide original directory of linked folders in terminal while i use ”ls -la”

I often use ls -la command for view hidden files in terminal.
But I'm uncomfortable with the fact that it shows and links to directories of linked folders.
Can I hide this?
The -L option may be what you are looking for, although this also changes what metadata is shown. Without -L, you get permissions, size, etc for the symlink. With -L, the symlink's name alone is shown, but with the permissions, size, etc of the target.
ls -la /usr/bin/ | awk 'BEGIN{FS="->"}{print $1}'
then you can alias it , so don't have to type all of that every time

The output of ls with -aF option is not clear

When I try the command ls with -aF option inside any directory whether it's empty or not, I always got the following:
./ ../
so what does the output mean when I have these two options together with ls command?
When you use ls, you are reading a directory file, not actually looking in a directory. Every directory listing contains an entry for the present/current directory, as well as its parent directory, just as you would expect to also see listings for sub/child directories in any directory listing.
The -A option for ls merely tells ls to display ALL files, which includes the entries of ./ & ../ for present and parent. Note that these dots are merely a shorthand that the shell (bash) uses to represent file paths for those files. In other words, what "./" really means is say ~/Desktop if you were currently in the Desktop directory doing an ls. And "../" would mean "~/" which is just another symbolic shorthand to represent your user home directory, which is probably something like /Users/your_username on macOS (OS X), or /usr/your_username for various Linux distributions. Note that those paths could also be written with the forward slash appended at the end and would mean the same thing (e.g., /Users/your_username/ is the same as /Users/your_username because they are both references to other directories (directory files).
Use the -a option for ls if you don't want to see ./ & ../, but still want to see (other) hidden files.
Using the -F option causes ls to display appended characters to the file types based on the file type. This is why directories are displayed with the forward slash appended at the end, and executables are displayed as executable* (with the asterisk appended), and regular files have no appendage (e.g., .txt, .png, .dmg).

How to access file start with period '.' in shell

Special characters can be distinguished using backslash character \ . However, I want to treat full period as a normal character to operate on hidden folders. For example:
ls -lh .
It will list the current directory. However, I want to list all the hidden folders. I want it to be usable with du -h, so I know the disk space the hidden folders consumed.
Files and directories whose names start with . are "hidden" only in the sense that (a) ls ignores them by default and (b) wildcard expansion excludes them. In both cases, you can see dot files if you refer to them explicitly. * expands to all non-dot files; .* expands to all dot files.
(Other tools and commands may also treat them as hidden; for example, GUI file managers like Nautilus typically don't show dot files by default, but there's often an option to show them.)
ls -a overrides the special treatment of files whose names start with .. ls -A lists "hidden" files and folders, but excludes . (this directory) and .. (the parent directory); some versions of ls might not support -A.
The du command, as far as I know, doesn't treat dot files as hidden. du -h should show the entire directory tree starting at the current directory. (Try it in a small directory tree to make sure yours behaves this way.)
EDIT :
I've confirmed that at least the GNU coreutils version of du doesn't treat files or directories whose names start with . specially; nothing is hidden.
For example, this script:
#!/bin/sh
mkdir -p .dot/.dot .dot/nodot nodot/.dot nodot/nodot
du -h
produces this output on my system (the specific numbers depend on the nature of the file system, and are irrelevant to the current discussion):
4.0K ./.dot/.dot
4.0K ./.dot/nodot
12K ./.dot
4.0K ./nodot/.dot
4.0K ./nodot/nodot
12K ./nodot
32K .
Does that meet your requirements? If not, can you explain more clearly just what you're looking for? Do you want to list all directories, whether their names begin with . or not? Do you want to list only "hidden" directories? What output would you like for the directory structure created by the above script?
Wrong place for this question, but it's simple enough:
ls -lhd .*
what about ls -lh .* ? (This may answer you question)

A confusion in APUE2(about symbolic link in UNIX)

The original text is below.It is in Section 4.22
The program in Figure 4.24 changes to a specific directory and then calls getcwd to print the working directory. If we run the program, we get
$ ./a.out
cwd = /var/spool/uucppublic
$ ls -l /usr/spool
lrwxrwxrwx 1 root 12 Jan 31 07:57 /usr/spool -> ../var/spool
Note that chdir follows the symbolic link as we expect it to, from Figure 4.17 .but when it goes up the directory tree, getcwd has no idea when it hits the /var/spool directory that it is pointed to by the symbolic link /usr/spool. This is a characteristic of symbolic links.
What does the author really mean by saying that the program hits the /var/spool?
What is the characteristic of symbolic links pointed out by the author?
I did not really understand.
Note that some shells, notably bash, keep track of whether you arrived at a given directory by chasing a symbolic link, and print the current directory accordingly. At least bash has options to cd to do a physical or logical change directory:
cd [-L|-P] [dir]
Change the current directory to dir. The variable HOME is the default dir. [...] The -P option says to use the physical directory structure instead of following symbolic links (see also the -P option to the set builtin command); the -L option forces symbolic links to be followed. An argument of - is equivalent to $OLDPWD. If a non-empty directory name from CDPATH is used, or if - is the first argument, and the directory change is successful, the absolute pathname of the new working directory is written to the standard output. The return value is true if the directory was successfully changed; false otherwise.
In the scenario shown, where /usr/spool is a symbolic link to /var/spool, then:
$ pwd
/
$ cd /usr/spool/uucppublic
/usr/spool/uucppublic
$ cd -L ..
/usr/spool
$ cd /usr/spool/uucppublic
/usr/spool/uucppublic
$ cd -P ..
/var/spool
$
For most people, a plain cd .. would do the same as cd -L ... You can choose to have bash do the same as cd -P .. instead if you prefer (using set -P or set -L).
The process of finding the pathname of the current directory should be understood too. Logically, the process (kernel) opens the current directory (.) and reads the inode number (and device number). It then opens the parent directory (..), and reads entries from that until it finds one with the matching inode number (and device number). This then gives it the last component of the pathname. It can now repeat the process, finding the the inode number of the next directory up, and opening its parent directory (../..), etc, until it reaches the root directory (where the inode number for both . and .. is the same, and the value is conventionally 2). Note that this even works across mount points. Beware of auto-mounted remote (NFS) file systems, though; it can be really slow if you scan through a directory containing several hundred automounted machines - as the naïve search outline above mounts all the machines until it finds the correct one. So, actual getcwd() functions are cleverer than this, but it explains how the path of the current directory is found. And it also shows why the process will not encounter /usr/spool when evaluating the directory under /var/spool/uucppublic - it simply never opens the /usr directory.
Note that the realpath() function (system call) takes a name possibly referencing symlinks and resolves it to a name that contains no symlinks at all. Passed /usr/spool/uucppublic, it would return /var/spool/uucppublic, for example.
Expanding on what #undor_gongor wrote:
Each process has a current working directory. It's not stored as the path name of the directory; it's a reference to the directory itself.
If it were stored as a path name, then the getcwd() function's job would be trivial: just print the path name. Instead, it has to readi the current directory, open its .. entry, then open that directory's .. entry, and so forth until it reaches the root (i.e., a directory whose .. entry points to the directory itself). It builds up the full path of the current directory in reverse order as it does this.
Since .. can't be a symlink, this process is not affected by symbolic links.
(Shells might have a $PWD or $CWD variable, or a pwd built-in, that is affected by symlinks; these typically work by remembering the string that was passed to cd or pushd.)
Assume you have a symlink /usr/spool pointing to /var/spool.
It says if you follow that symlink (e.g. cd /usr/spool), you end up in the pointed-to directory (/var/spool). Then, the information that you followed a symlink is lost. You are in /var/spool as if you had done cd /var/spool directly.
A further cd .. brings you to /var (as opposed to /usr).
UPDATE:
As pointed out by Keith Thompson and Jonathan Leffler, there are some shells that do remember the path you followed (i.e. /usr/spool). In such shells, cd ..
would go to /usr/. However, programs started from such a shell would still see /var/spool as the working directory.
This is probably the reason the author let you write a program for displaying cwd (to work-around such shells' internals).

Resources