The use and work of “ls -l *.c”
Using ls -l *.c in the Command Line (Shell)
Before we jump into discussing about today’s topic, What is a Shell?
The shell is the outermost layer of the operating systems. Shells incorporate a programming language to control processes and files, as well as to start and control other programs. The shell manages the interaction between you and the operating system by prompting you for input, interpreting that input for the operating system, and then handling any resulting output from the operating system.[3] Shell is simple a way to communicate with operating system to do certain jobs. Even in GUI mode we are using the shell ideology it is just we are clicking a file which contains a certain sequential commands of the shell.
“Unix-like operating system such as Linux organizes its files in what is
called a hierarchical directory structure”. [4]
The shell is a textual representation of the file system on your computer. So, a graphical interface in contrast uses icons of folders to represent the files they hold. and those icons in the background are a sequence of shell commands. The user can double click the folders to execute the commands and gain access to the files. [5]
Today we will be discussing the use of ls -l *.c
and what happens in the back end from the computer side. Let’s start by defining what ls is in most computing devices. In computing, ls
is a command to list computer files in Unix and Unix-like operating systems. ls
is specified by POSIX and the Single UNIX Specification. [1] ls is a short for list, which means asking or requesting the computer to list. when you type ls
to the command line it will list the files in the current directory.
This may not seem useful when you look at it this way because you can do this and a lot more with the GUI interface, you might say. But this is the least ls
can do. ls
is much powerful than that and here we will grasp a tip of its power from the lake of ls
use. And I assure you you will prefer ls
than GUI folder listing after this tutorial.
First, let’s see the syntax of ls[2]:
ls [OPTION]... [FILE]...
The ls
command when invoked without any option or argument as we said before lists the files and directories in the current working directory excluding the files which name starts with “.”(dot — indicating hidden files). Let’s split and see the syntax tools one by one[2]:
ls - the list command in the UNIX like systems
[OPTION] - the arguments to use the power of ls
Option presents the arguments specified to direct ls how or when or what to list. There are a lot of arguments like -l
(for long detailed list), -a
(to list hidden files), -i
(to list index number of the files), -s
(to list files with their allocated file size), -S
(to list sorted with file size), and of course including --help
(to view help menu), and --version
(to see version information), and money more. You can invoke man ls
on google or your UNIX machine terminal and lookup all the available arguments for ls
.
[FILE] - a file directory if it is not in the current working directory or name of a file
FILE presents a file name or directory name what or where to list the file information. When we put the file name with no other argument or directory name it lists the file if it exists in the current working directory. Or, if we put arguments with the file name it will list detail information about the file, of course still if it exists in the current working directory. when we put the directory name or location of the directory, the ls
command goes to that directory and execute the list command along with the specified arguments.
Now after explaining the basic syntax of ls
, lets go back to today’s topic which is the working procedure of ls -l *.c
. As we have said before ls
lists files in the current working directory, when -l
argument is added it lists the files in vertical alphabetical order unless sorting argument is specified, it is called long listing in Linux. What is the point of listing vertical/horizontal? you might say but -l
doesn’t only list vertically in alphabetical order, it reveals and prints seven facts about each item/file. Lets see them one by one;
ls -l
total 4
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello
drwxrwxr-x 2 sertse sertse 4096 Aug 29 09:04 Hello
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.c
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.exe
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.out
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.py
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.sh
-rw-rw-r-- 1 sertse sertse 0 Aug 29 09:04 hello.txt
The word “total” is followed by the number of file system blocks that the directory’s files occupy. Each subsequent line supplies details on a single item. The first character specifies the folder or file type. It is a directory if the letter “d” appears. UNIX uses hyphens to identify standard files; various letters denote specialized data files and links. [6]
This identifier is directly followed by a set of nine letters and hyphens. They disclose the item’s security permissions. The first three permissions apply to the file’s owner, and the next set pertains to members of the owner’s group. The final three characters identify access permissions for all other users. [6] Permission is a topic for another class, so if you want to read stay tuned.
The next item in each ls -l listing is the number of links. A file typically has one link, but there are more links if it has aliases. The count starts at two for folders because UNIX considers the parent and current directories to be links. [6]
The UNIX ls -l command’s listings also indicate the owner and group assigned to a file. The file size follows the group name; it is measured in bytes. A calendar date appears after the file size indicating the last time the file modified. It may include year as well, depending on how long its been.[6]
Finally, the name of a file or directory appears at the end of each line. This is what ls -l
can do. The ls -l *.c
is no different it just adds a specification to the list. As we have mentioned above the third argument holds a file name or directory name in this case it is neither :( hmm … well *
in Unix means whatever. So, *.c
means whatever the file name is just check if it ends with the two characters .c
. So, in the ls -l *.c
case, it means list the files whose name ends with .c
characters. Since there is no asterisk after the .c
characters it will only list the files which ends with c
. For example: if there are two files:
$ ls
hello.cs hello.c
$ ls -l *.c
-rw-rw-r-- 1 sertse sertse 0 Aug 29 11:04 hello.c
This is what the ls -l *.c
command show us but how? we still didn’t answer how this is done in the background. Well when you type ls -l *.c
and hit enter the getline
function of the shell reads the argument with the \n
line character but that new line will be changed into \0
which helps the shell function to recognize the end of the string to identify what command typed and use the strtok
function to parse the command. The function split the sentence into an array of strings [ls
] [-l
] [*.c
]. Then before anything else the function checks if the command ls
is listed under the builtin command or an alias, if either ways, it continues to the next operation. Which is pushing the command to another process.
If the command is not a builtin command neither an alias, the function compares it with the with the PATH and sent to the error handler function to print an error message.
What is a PATH? A PATH is a concatenated string of path names where the builtin commands might be saved. [5]
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
This directories hold the builtin function of almost all Unix commands. So, the command will be searched within this folders and if it doesn’t exist, it will be passed to the error handler and to print an error message indicating the wrong command.
As the ls
exists in the PATH directories and it will be appended to the directory it was found in, in this case /bin
so /bin/ls
, and it will be executed. But the shell is doing all this on one process so far so when it decided to execute the command it will create an identical child process to execute the ls -l *.c
command. The parent process will be waiting until the child process ends before doing any other operations. So the shell have the location of the ls
program which is /bin/ls
so it will attach the array of the option/flag and the file specifier and send it to the ls
program.
Then the ls program receives the array of strings and check if the flag and the file specifier is a valid input. If the input is valid then the ls
program finds the current working directory address and receive the full file information in the folder using the flag -l
then searches for files whose filename is ending with .c
and if they are available the program will send their detailed information to the standard output. If there is no file ending with .c
the program will return the error message to the standard output.
I hope you get a great insight of how the ls -l *.c
works. For further knowledge follow me and stay tuned for next tutorials.
References
[1] Richard Stall man and David Mackenzie. (.n.d). LS. Retrieved from https://en.wikipedia.org/wiki/Ls
[2] ls — Linux manual page. (n.d.). https://man7.org/linux/man-pages/man1/ls.1.html
[3] Operating system shells. (n.d.). https://www.ibm.com/docs/en/aix/7.2?topic=administration-operating-system-shells
[4] William Shotts. (n.d.). The Linux Command Line. https://linuxcommand.org/tlcl.php
[5] Erica Caoili. (Nov, 2019). The Command Line with ls -l
. https://medium.com/swlh/the-command-line-with-ls-l-6efaf01cc4c0
[6] livefirelabs. (n.d.). The UNIX ls -l
Command Explained. https://www.livefirelabs.com/unix_commands/the-unix-ls-l-command-explained.htm