Normally ls doesn't print filenames that start with a dot. With -a, it does, but that includes . and .., which exist in all directories, and hence aren't very interesting. With -A it prints everything but those two.
$ touch normal .hidden
$ ls
normal
$ ls -a
./ ../ .hidden normal
$ ls -A
.hidden normal
In that if-statement, the command substitution $( .. ) captures the output of ls, and [[ -z ... ]] tests if it's the empty string. That is, that there's no files in the directory.
Usually, reading the output of ls is not a good idea, if you want to loop over files in the shell, you can just use *. Here, it should work, though, except for the fact that if the given directory name contains whitespace (or filename glob characters), they'll be expanded on the command line of ls, which may mess up the results.
See:
- https://mywiki.wooledge.org/ParsingLs
- When is double-quoting necessary?
. is the relative reference for the current directory.
.. is the relative reference for the parent directory.
This is why cd .. makes the parent directory the new working directory.
. and .. are hard links to the current and the parent directory
(/ is the parent of itself).
With the -a option ls shows all inodes in the current directory, i.e. also the hidden files which filenames begin with ad dot, therefore . and .. are shown.
The ls -al command is a combination of ls -l (use a long listing format) and ls -a (do not ignore entries starting with .)
The result is a long list (the ls -l part) with (from left to right):
- filetype
- file permissions
- number of links
- owner name
- owner group
- file size
- time of last modification
- the name of the file or directory
while the ls -a means that hidden files are listed as well.
see also man ls (as always man is the first source of information), and this link.
A little more explanation on what you see
The output starts with the number of disc blocks, used by the directory (in your case 76). From the GNU docs:
For each directory that is listed, preface the files with a line ‘total blocks’, where blocks is the total disk allocation for all files in that directory. The block size currently defaults to 1024 bytes, but this can be overridden.
Then:
- the first character describes wether it is a directory (
d) or a file (-) (or some other file type, see the docs for a complete listing)
File permissions:
- the permissions in a nine-character section (3x3 for owner / group / other users)
Links
- The number of links is the number of hard links to the file. For a directory, the number of hard links is the number of (immediate) subdirectories plus the parent directory and itself.
Owner
- name of the owner
- name of the (owner) group
File size
- You see many files with the size of
4096, which is the minimum size for a directory onext3andext4.
ls - list directory contents
You have 76 directories in /home/blog
drwxrwxr-x - These are the permissions for each one
The number after the permissions is the number of file/folders/links in this folder
After that the current user
After that the folders owner
Next is the group ID for the group the file belongs too.
Next is date and time the file was modified
The far right entery is the name of the folder
You can append ls with other commands for example
ls -a
Displays hidden files (starting with .)
You can find all the commands here
The reason behind ls -a showing . and .. has nothing to do with utility and everything to do with Unix (and Linux) filesystems.
Everything is a file.
Directories are really files that contain lists of files. "Inside" any given directory, because that is the perspective of the user, if not exactly the perspective of the filesystem, there are two special files.
- The first, called
., is a reference to the current working directory. This is used by people almost every day, when they do things like running a command in the current directory via./scriptname. - The second, called
..is a reference to the CWDs parent directory. Like.,..is used every day by everyone who desires to change directories to the parent directory viacd ...
The system call getdents(), which is the workhorse on the system side of ls, simply enumerates all files in a directory. (remember: everything is a file. devices, directories, sockets, etc. so they all show up)
From the utility side of things, the author(s) of the ls command have provided a number of options, and combinations of options, that allow us to filter out certain pieces or types of information, for example @Gilles commented above that ls -A will show all dotfile, with the exceptions of . and ... All of these options could be considered post-processing options. They affect what is displayed by ls, not what is found by ls.
There's really no reason to explicitly list . and .., by default, since we all know they are there, what they are for, and when to use them.
It can definitely be helpful to be able to have some option to see them though, when you're troubleshooting strange permissions problems.
Check out the manpage for getdents()¹. It explains a bit more about how it works, and includes the source code for a sample program that you can compile with gcc -Wall, which lists all the files in a directory.
—
1. At least, the Ubuntu manpage for getdents() seems to have the sample code.
ls doesn't normally display . and ... By default, ls hides all files whose name begins with a . (dot files). ls -a displays them because you asked to show everything. Some versions of ls have a slightly different option, ls -A, to show all dot files but not . or ...
Showing . can be useful if you're listing more than the names; for example ls -la reports the permissions and ownership of the current directory and its parent along those of the files in the directory.