The main reason that most operating system users choose Linux over other operating systems is the freedom to explore. With Linux, you are bound to some loosely coupled operating system rules. The OS predefines some changeable standard rules to use within its environment.
Once you shed off the beginner’s coat, you can get out of these default rules and create your own. Under Linux, the operating system is your loyal servant and you the master.
This case is not viable in other operating system distributions as there are too many abstractions in place. The operating systems here are more of your assistant. You can never have more power than the operating system, like with the case of Linux. As you continue to build your user experience under a Linux OS environment, your OS curiosity will grow daily. You will always want to know what is hidden here and what more you can do under its umbrella.
Working with files and directories on Linux
A perfect case scenario is your daily interaction with files and folders under the Linux operating system environment. There is more to using the Linux OS file system than just creating, editing, modifying, and deleting the user file systems and folders. Every action linked with the user files and folders/directories under a Linux environment leaves a user footprint or fingerprint. It is like walking into a room to touch and interchange items.
If a Linux landlord or caretaker manages this room you entered, it will know exactly what you did and which items you touched or interchanged. Linux has useful commands to help us achieve such results. You will know what happened to the files and folders in your Linux OS and identify these actions based on when they happened.
In short, when dealing with files and directories under a Linux operating system environment, we can build an events timeline to identify vulnerable file modifications through timestamps attached to each modification. As an advantage, you will know whether the modification was associated with malicious content through the generated system logs.
The Linux commands to use
We will pipe some simple commands to help us understand the objectified implication of this article piece. You first need to launch your terminal and navigate a system path that you know has many files and folder directories. To be safe and not play around with your vulnerable system files, you could use your “Documents” directory that is usually predefined in the Linux operating system. The following command should get you to this “Documents” directory.
$ cd ~/Documents
It is a popular directory with many files and sub-directories. Another directory to use for this article experiment is the “Downloads” directory. It is one place you will never miss downloaded files and other sub-directories.
$ cd ~/Downloads
To kick off this experiment, we need some relatable sample output from our terminal. We will key in a command string on our terminal that will enable us to list active files and their associated subdirectories. Also, each element of the resulting output from this command will be linked with a timestamp that points to the last modification attempt on the associated file, directory, or subdirectory.
The command string to use is as follows:
$ find . -printf '%T@ %t %pn' | sort -k 1 -n | cut -d' ' -f2-
The screenshot below is the output for using the above command string.
From an analytical point of view, the bottom screen of the command output represents the recently modified items on your parent working directory. The output list can be long, depending on the files and folders you have on your machine. Scrolling up on the output terminal reveals older files and folder modifications. In summary, we have an output that ranks the oldest files and folder modifications to the newest modifications.
As you have noticed, the above command string you pasted on your terminal has three important command arguments. We need to understand what each of them does.
The “find” command is the first one to execute from the command string. It has the sole objective of recursively listing the active files and directories on your parent working directory. The “.” argument that follows the “find” argument points this command to the current working directory. If you are not sure of the directory you are under; you can key in the “pwd” command on your terminal. It will print out the path to the directory you are currently under.
The “.” argument is translated as the output of the “pwd” command. It makes it easier to find the files and directories of your current working directory. The next argument on the command string is “-printf”. It is a flag for a print argument. It prints the files and directories on your current working directory in a specified format. The format it takes is specified by the argument “%T@%t%pn”. It is the command argument that immediately follows it.
The ‘%T@’ portion of this argument represents the epoch time. By definition, epoch time or Unix epoch is the timestamp on 1 January 1970. It is represented as 00:00:00 UTC. The output on your terminal takes this format to represent the modification dates associated with the listed files and directories. The ‘%t’ portion of the argument now takes the epoch time format to display the latest modification timestamp associated with the listed files and directories.
Depending on your Linux distro or flavor, the terminal output might not display the epoch time associated with the output list of modified files. This statement is proof of the output from my end.
The ‘%p’ portion of the argument outputs the names of the displayed files on that current working directory. Finally, the ‘/n’ portion of the argument serves the purpose of a newline character. After each successive listing of a modified file, this newline character takes the display cursor and skips the next file display to a new line on the terminal screen. It makes it easier for us to associate each displayed file differently.
Another approach to working with the earlier stated command string is replacing the ‘%t’ portion of the “%T@%t%pn” argument with ‘%c’. The resulting command string should look similar to the following:
$ find . -printf '%T@ %c %pn' | sort -k 1 -n | cut -d' ' -f2-
The output of running this command string should produce an output similar to the following screenshot.
Observing the above screenshot keenly reveals the following observation. The output list of files on the current working directory is displayed with a ”last status change time” instead of the ”modification time”. It is the effect of replacing ‘%c’ with ‘%t’ in “%T@%t%pn”. This last command prints out permission changes associated with the outputted file list. The files’ contents might not change, but the metadata associated with them does.
At this stage, the output results do not follow any chronological order as we are yet to address the sort command. The modification timestamp is first printed, followed by the name of the associated file.
This command argument has three parameters, namely ‘-k’, ‘1’, and ‘n’. The sort command is responsible for the order in which the file list output appears on our screens. In this case, the modification date is printed first, followed by the file path to the modified file or directory. The ‘-k’ portion of this command argument indicates the start position to begin the sorting process.
The ‘-k’ portion of the sort command argument posses a question answered by the ‘1’ portion of the same argument. In this case, the sorting process starts from the first column as indicated by ‘1’. The sort command argument is also responsible for the newest modified file being at the bottom of the list and the oldest at the top. The ‘-n’ portion of the argument is responsible for the numerical of time with decimal points precision.
If you use ‘-nr’ instead of ‘-n’, the output of the command string will have the newly modified files and directories on top of the terminal output and old file modifications at the bottom. It reverses the sorting order of the terminal output.
The main purpose of the “cut” command argument is to organize the output of our terminal printout in a tidy manner. The ‘-d’ and ‘ ’ options of this command argument combine to generate white spaces and then cut off the file content details printout that might try to succeed these white spaces.
With this simple command string, you can recursively print the files on your current working directory, with each output linking the said files to their modification dates.
Alternative command options
You might argue that the command “ls -lrt” perfectly lists all the files within an active directory path on your Linux operating system, from the oldest to modify to the newest. On the other hand, this command does not consider the file contents existing in subfolders. If listing subdirectories is not your objective, you could add the “-type f” argument to the command string. Consider the following modification of the command.
$ find . -type f -printf '%T@ %t %pn' | sort -k 1 -n | cut -d ' ' -f2-
Using the “-type d” command argument will have an opposite effect to the above command. Your terminal will only output modified directories from the oldest to the newest. Consider its implication as follows:
$ find . -type d -printf '%T@ %t %pn' | sort -k 1 -n | cut -d ' ' -f2-
You are now familiar with the walkthrough of recursively printing files and directories on your current working directory with the additional knowledge of knowing when they were last modified based on their associated timestamps.
From this knowledge, you have the capability of composing a timeline of events that chronologically reveals the order of files and directories modification together with the path to their storage location.