Linux has long been the foundation of server infrastructure, cloud platforms, containerization, and many cybersecurity tools. For DevOps and DevSecOps professionals, working with Linux through the terminal is an essential skill. In the first part of this series, we will explore the Linux file system structure, basic navigation commands, file creation and management, as well as tools for searching and analyzing information.
This article marks the beginning of a four-part series on Linux for DevOps and DevSecOps. It is designed for both beginners who are just getting familiar with the system and professionals who want to refresh their knowledge and improve their command-line skills. We will start with the fundamentals commonly used in server administration, application configuration, and system security assessments.
Rather than spending time on lengthy explanations of what an operating system is or why the terminal is necessary, we will focus on specific tools, their capabilities, and practical examples of how to use them. Most of the commands covered can be executed in a standard Linux environment, although some paths and available utilities may vary depending on the distribution.
The Linux file system is organized as a single directory tree that begins at the root directory /. Unlike Windows, where users typically work with separate drives such as C:, D:, and other drive letters, Linux integrates all file systems into a unified hierarchy through mount points.
This means that system configurations, applications, user home directories, event logs, and even device interfaces all have their designated locations within the overall structure. Understanding this organization makes it easier to locate files and navigate unfamiliar Linux environments.
A simplified structure of the root directory looks like this:
/ ├── etc # Системні конфігурації ├── var # Журнали, кеш і змінні дані ├── proc # Інформація про процеси та ядро ├── sys # Інтерфейси до пристроїв і драйверів ├── tmp # Тимчасові файли ├── home # Домашні каталоги користувачів ├── root # Домашній каталог суперкористувача ├── dev # Файли пристроїв ├── usr # Програми, бібліотеки та ресурси ├── bin # Базові виконувані програми ├── sbin # Системні утиліти адміністрування ├── opt # Додаткове програмне забезпечення ├── run # Дані активних служб ├── mnt # Точки монтування └── boot # Файли завантаження системи
In modern Linux distributions, the /bin and /sbin directories are often symbolic links to their corresponding directories within /usr. Other directories, such as /srv and /media, may also be present in an actual system. The directory tree shown above primarily highlights the locations you are most likely to work with.
The /etc directory contains system configuration files. This is where settings for services, network components, and many installed applications are stored. For example,
/etc/hostsis used to map hostnames to IP addresses locally,/etc/fstabdefines file systems to be mounted, and/etc/ssh/sshd_configcontrols SSH server configuration if the server is installed. For DevSecOps professionals, reviewing this directory is important because configuration errors can lead to unintended access exposure or other security issues.
The /var directory stores data that changes during system operation. This may include caches, job queues, data from individual services, and system logs. One particularly important subdirectory is
/var/log, which contains authentication logs, web server logs, and logs from other components on many systems. If an application stops working or a server behaves unexpectedly, analyzing these logs is often one of the first troubleshooting steps.
The /proc and /sys directories differ from regular directories. They provide access to virtual file systems through which the Linux kernel exposes information about processes, hardware, and the system’s internal state. For example,
/proc/cpuinfocontains processor information,/proc/meminfoprovides memory usage statistics, and PID-named subdirectories within/procallow you to inspect individual processes. The/sysdirectory provides information about devices, drivers, and certain kernel subsystems. Some parameters can also be modified, so writing to these directories without understanding the consequences is not recommended.
The /home and /root directories store user data. The
/homedirectory typically contains the home directories of regular user accounts, while/rootis the home directory of the superuser. These locations may contain personal files, shell configurations, SSH keys, and development tool settings. In particular, the hidden~/.sshdirectory often stores SSH client configurations and key material, so access to it should be carefully controlled.
It is also important to remember /tmp, /dev, and /run. The first is used for temporary files, the second provides file-based interfaces to devices, and the third contains runtime data for active services and processes. The contents of /tmp may be cleaned automatically, so important information should not be stored there without a backup.
For everyday work, you do not need to memorize the purpose of every directory. What matters more is understanding the general structure: configuration files are typically found in /etc, logs in /var/log, process information in /proc, and user files in their respective home directories.
When working with Linux servers, a graphical user interface is often completely absent. Administrators connect via SSH and perform the necessary operations through the command line. Therefore, one of the first skills to learn is how to quickly identify your current location, move between directories, and inspect their contents.
To get started, you only need to master three essential commands: pwd, cd, and ls.
The pwd (print working directory) command displays the absolute path to your current working directory. For example:
pwd
The result might look like this:
/home/devops/projects
This means that the user is currently in the projects directory, which is located inside their home directory. This command is particularly useful after navigating extensively through the file system or when running scripts where it is important to know the working directory relative to which paths are resolved.
To determine the physical path, resolving symbolic links, you can use pwd -P. The pwd -L option displays the logical path, which may preserve symbolic link references.
Moving between directories is done using cd (change directory). This command accepts both absolute and relative paths. An absolute path always begins with / and specifies a location starting from the root of the file system. A relative path is resolved from the current working directory.
Let’s look at the most commonly used options:
cd /etc cd /var/log cd .. cd ../.. cd ~ cd -
In the first two cases, we navigate to specific system directories. The cd .. command moves up one directory level, while cd ../.. moves up two levels at once. The ~ symbol represents the current user’s home directory, so cd ~ allows you to quickly return to it regardless of your current location.
The cd - command is particularly useful because it takes you back to the previous working directory. For example, if you are checking a configuration in /etc/nginx and then move to /var/log/nginx, you can switch between these locations without repeatedly typing their full paths.
The ls (list) command is used to display directory contents. Without arguments, it lists the files and subdirectories in the current location, but additional options allow you to retrieve much more detailed information.
ls ls /etc ls -l ls -a ls -lh ls -lt ls -lS ls -ld /etc
The -l option enables a detailed listing format that displays file permissions, owner, group, size, and last modification time. The -a option includes hidden files, whose names begin with a dot. The -h option is used with the long listing format to display file sizes in a more readable format, such as kilobytes or megabytes.
The ls -lah combination is one of the most useful commands for everyday work:
ls -lah /etc/ssh
This command allows you to quickly inspect the contents of a directory, including hidden files and directories, and check their ownership and access permissions. For DevSecOps professionals, this information can be valuable during an initial system security audit.
Two other options worth remembering are -t and -S. The first sorts entries by modification time, while the second sorts them by size. For example, ls -lt helps you quickly identify recently modified files, while ls -lS displays the largest files at the top of the list.
When you need to examine an entire project structure rather than a single directory, the tree utility is a more convenient choice. It displays the hierarchy of files and directories in a tree-like format, making it easier to analyze complex directory structures.
tree tree -L 2 tree -a tree -d tree -I "node_modules"
For example, `tree -L 2` limits the display depth to two levels, while `tree -a` reveals all files and directories—including hidden ones that begin with a dot, such as `.git` or `.env`. The `tree -d` command displays only directories, whereas `tree -I “node_modules”` excludes the `node_modules` folder from the output. This is particularly useful when working on large projects where you need to quickly view the directory structure without being distracted by dependencies or extraneous files.
On Ubuntu and Debian, the utility can be installed, if necessary, using the following command:
sudo apt install tree
As a result, even basic commands such as pwd, cd, ls, and tree allow you to navigate virtually any Linux environment. The key is to understand the difference between absolute and relative paths and always verify your current working directory before performing operations that modify files.
When administering servers, you often need to locate a specific file. This could be a web server configuration file, a backup, an error log, or a file that has recently appeared on the system. If the exact path is unknown, manually browsing dozens of directories can be inconvenient, especially on large servers.
For these tasks, Linux provides the find and locate utilities. Both allow you to search for files, but they operate differently.
The find command searches directly through the file system. It recursively traverses a specified directory and examines files and directories based on defined criteria. You can filter search results by name, type, owner, size, permissions, or modification time.
For example, to find all files with the .log extension in the current directory and its subdirectories, simply run:
find . -type f -name "*.log"
The dot (.) after find represents the current directory. The -type f option limits the results to regular files, while -name specifies the search pattern. The * wildcard matches any sequence of characters, so the command will find files with any name ending in .log.
If you need to find configuration files in /etc, simply change the starting directory and search pattern:
find /etc -type f -name "*.conf"
You can also perform searches from the root of the file system, but this increases system load and may result in permission errors. It is often more practical to limit the search scope to directories that are actually relevant to the task.
One of the most useful features of find is searching by file size. For example, if a server is running low on free disk space, you can check for excessively large log files:
find /var/log -type f -size +100M
The command finds regular files larger than 100 MiB. This helps identify log files that have grown excessively due to application errors, high volumes of logged events, or improperly configured log rotation.
Searching by modification time is equally useful. For example:
find /etc -type f -mmin -60
This command displays files in /etc whose contents have been modified within the last 60 minutes. This can be useful if a service stops working after an update or configuration change.
To find files modified within the last 24 hours, use -mtime -1:
find /var/log -type f -mtime -1
It is important to distinguish between different file timestamps. The -mtime and -mmin options refer to changes in file contents. If you need to find files based on metadata changes, such as modifications to ownership or access permissions, use -ctime or -cmin.
In DevSecOps, you may also need to identify files with insecure access permissions. For example:
find /etc -type f -perm 0777
This allows you to find files for which all user categories have been granted the full set of standard read, write, and execute permissions. The presence of such files does not necessarily indicate that the system has been compromised, but it is a strong reason to investigate why such broad permissions have been assigned.
Additionally, find supports executing commands on matching files using the -exec option. For example, you can find large log files and display their sizes:
find /var/log -type f -size +100M -exec ls -lh {} +
The {} symbols represent the paths of the matching files, which are passed as arguments to the specified command. This approach is useful for diagnostics but requires caution, especially when -exec is used to perform operations that modify or delete files.
For quick searches by filename, you can use locate. Unlike find, this command does not traverse the file system for every query. Instead, it searches a previously generated index. As a result, searches are usually much faster.
locate nginx.conf locate -i readme locate -l 10 "*.log"
The -i option makes the search case-insensitive, while -l 10 limits the output to the first ten matches.
The drawback of this approach is that the database may not include new files created since its last update. If this is important for your current task, you can manually update the index:
sudo updatedb
On Debian and Ubuntu, the `plocate` package can be used to implement `locate`:
sudo apt install plocate
Therefore, find is the preferred choice when you need up-to-date results and advanced search criteria. The locate utility is better suited for quickly finding files by name when relying on the freshness of the index is acceptable.
Now that we have covered navigation and file searching, we can move on to working with files themselves. In Linux, most standard operations that are performed through a file manager in a graphical environment can also be executed directly from the terminal.
The mkdir command is used to create directories, while touch is used to create empty files. For example, let’s set up a small practice project with directories for configuration files, logs, and backups.
mkdir -p ~/linux-lab/config mkdir -p ~/linux-lab/logs mkdir -p ~/linux-lab/backups touch ~/linux-lab/config/app.conf touch ~/linux-lab/logs/app.log
In this example, the -p option allows you to create an entire hierarchy of nested directories if they do not already exist. Additionally, the command will not fail simply because the specified directory already exists.
This is why mkdir -p is frequently used in automation scripts that may be executed repeatedly.
The touch command, in turn, is not limited to creating empty files. If a file already exists, it typically updates its timestamps without modifying its contents. This can be useful when testing scripts or processes that depend on file modification times.
The cp (copy) command is used to copy files. The simplest approach involves specifying the source file and the destination path:
cp ~/linux-lab/config/app.conf ~/linux-lab/backups/app.conf.bak
As a result, a separate file will appear in the backup directory. The original configuration will remain in place, and its copy can be used for recovery following unsuccessful changes.
Additional parameters allow you to modify the copying behavior:
cp -r source_dir backup_dir cp -p app.conf app.conf.bak cp -i source.txt destination.txt cp -v source.txt /tmp/
The -r option allows you to copy directories recursively, including all nested files. The -p option attempts to preserve timestamps, permissions, and ownership, as far as the current user’s privileges allow. The -i option prompts for confirmation before overwriting files, while -v displays the operations being performed.
When backing up configuration files, it is sometimes important to preserve not only their contents but also access permissions, symbolic links, and other metadata. In such cases, cp -a is recommended, as it is designed for archive-style copying.
If you need to move or rename a file rather than copy it, use the mv (move) command. The same command supports both operations.
mv old.conf new.conf mv app.log ~/linux-lab/backups/ mv old.conf ~/linux-lab/config/new.conf
In the first example, the file is renamed; in the second, it is moved to another directory; and in the third, both operations are performed simultaneously.
In practice, mv is frequently used when updating configurations, deploying applications, or organizing archives. However, it is important to remember that moving a file may overwrite an existing file at the destination. For additional protection, you can use mv -i, which typically prompts for confirmation before overwriting.
The rm (remove) command deserves special attention. It is used to delete files and directories, but unlike a standard graphical file manager, it does not move deleted items to the Trash.
rm file.txt rm -i file.txt rm -r old_directory/
The standard rm command deletes the specified file. The -i option adds a confirmation prompt, while -r allows you to recursively delete directories along with their contents.
Particular caution is required when using the rm -rf combination. The -f option disables certain safeguards and forces deletion without prompting, while -r extends the operation to nested directories. An incorrect path or careless use of variables in a script can result in the loss of large amounts of data.
On production servers, before performing bulk deletions, it is advisable to first review the list of files and directories that match the specified criteria and ensure that up-to-date backups are available.
Another important feature of Linux is the ability to create different types of links to files. The ln (link) command is used for this purpose.
A hard link is an additional name for the same file object. It refers to the same inode as the original filename. If one name is deleted, the data remains accessible through other hard links as long as they exist.
A symbolic link, or symlink, works differently. It contains a path to another object and functions similarly to a shortcut. Symbolic links can point to both files and directories and can also reference objects across different file systems.
Examples of how to create them:
ln original.txt hardlink.txt ln -s original.txt shortcut.txt ln -s /var/log ~/system-logs
In the first case, a hard link is created; in the second, a symbolic link to a file; and in the third, a link to the system log directory.
To check where a symbolic link points, you can use the following command:
ls -l ~/system-logs
As a result, the command will display the path to which the symbolic link points.
For DevOps professionals, symbolic links are particularly useful when organizing configurations and deploying applications. For example, they allow you to maintain a consistent path to the current version of an application, even when the actual files are stored in directories with different names.
In Linux, file extensions are not required and do not determine a file’s actual format. An executable program may have no extension at all, while a file named document.txt does not necessarily contain plain text.
To identify a file’s type based on its contents, use the file command.
file /bin/bash file /etc/passwd file archive.tar.gz file unknown_file
In the first case, the utility may identify an ELF executable file or a symbolic link to it, depending on the system and how the command is invoked. For /etc/passwd, it will typically identify text data, while for an archive, it will detect the corresponding compression format.
This is particularly useful when analyzing unknown files. For example, if a suspicious file without an extension appears on a server, the file command can help perform an initial classification without executing it. However, the result is not a comprehensive security assessment: it only describes the likely type of content.
To inspect detailed file metadata, use the stat command. Unlike file, this utility displays an object’s file system attributes, including its size, owner, group, access permissions, inode, link count, and timestamps.
stat /etc/passwd
Among the information displayed, you can find three important timestamps:
Access (atime) – the time when the file’s contents were last accessed, provided that the file system tracks this information.
Modify (mtime) – the time when the file’s contents were last modified.
Change (ctime) – the time when the file’s inode metadata or contents were last changed, but not necessarily the time when the file was created.
These timestamps are important for troubleshooting and incident investigations. For example, a change in mtime can help determine when a configuration file was edited. However, timestamps should not be treated as definitive evidence of a particular action, since their accuracy and behavior depend on the file system, mount options, and how files are accessed or modified.
Some file systems also support file creation timestamps, which stat may display separately as Birth.
After locating the required file, the next task is often to read its contents. This could be a service configuration file, a system log, a list of users, or the output generated by an application.
Linux provides several tools for these operations, each suited to different situations. The simplest option is cat (concatenate). This command reads files and writes their contents to standard output, which is typically displayed in the terminal.
cat /etc/os-release cat -n /etc/hosts cat file1.txt file2.txt
The first example displays information about the installed Linux distribution. The second shows the contents of /etc/hosts with line numbers, while the third displays the contents of two files sequentially.
The command is well suited for small configuration files and short text files. However, if you use cat to open a log containing several hundred thousand lines, its entire contents will be printed to the terminal, making it difficult to find the information you need.
For large files, less is a more convenient option. This utility opens an interactive viewer that allows you to navigate through text, jump to specific lines, and search for matching patterns.
less /etc/passwd less -N /var/log/syslog less -S app.log
The -N option adds line numbers, while -S disables automatic wrapping of long lines. This is useful when working with logs, where each entry may contain multiple fields.
Inside less, standard navigation keys are available. Press Space to move to the next page, b to return to the previous page, g to jump to the beginning of the file, and G to jump to the end. To search for specific text, press /, enter your search query, and confirm it by pressing Enter. Use n and N to navigate between search results, and press q to exit.
The more command offers similar functionality, but with more limited features. Therefore, less is generally the more convenient choice for everyday work with large text files.
If you do not need to view the entire file, you can use the head and tail commands. The first displays the beginning of a file, while the second shows its end.
head -n 20 app.log tail -n 50 app.log
These examples display the first 20 and last 50 lines of a file, respectively. This approach is useful when you need to quickly inspect a file’s structure or read the most recent log entries.
The tail -f command is particularly useful for troubleshooting. Instead of exiting after displaying the last few lines, it continues monitoring the file and displays new entries as they appear.
For example, if Nginx is installed on a server and its logs are stored in the default directory, you can run:
sudo tail -f /var/log/nginx/access.log
Now, as HTTP requests arrive, new log entries will appear directly in the terminal. This allows you to monitor web server behavior, verify incoming requests, and quickly identify unusual activity.
To stop monitoring the file, press Ctrl+C.
If a log file is periodically moved or recreated due to log rotation, tail -F is often a better choice than tail -f. This mode attempts to continue tracking the file by its name, even after it has been replaced.
However, it is important to remember that not all modern systems store events exclusively in plain-text log files. On distributions using systemd, a significant portion of system information may be stored in the system journal, which can be accessed using journalctl. We will explore working with services and processes in greater detail in the upcoming articles.
When working with Linux, knowing where a file is located is not enough. It is equally important to be able to quickly find specific entries within it, especially when dealing with large event logs, configuration files, or structured text data.
The grep, awk, and sed utilities are used for these tasks. These tools allow you to filter information, extract specific fields, process text, and automate repetitive operations.
The grep command is one of the most widely used text analysis tools in Linux. It searches the contents of a file or an input data stream and outputs lines that match a specified pattern.
For example, to find all messages containing the word error in an application log, use:
grep "error" app.log
By default, the search is case-sensitive. Therefore, `error`, `Error`, and `ERROR` will be treated as different strings. To find all variations regardless of case, the `-i` parameter is added:
grep -i "error" app.log
If you need to get line numbers or count the number of matches, the -n and -c options are used.
grep -in "error" app.log grep -ic "error" app.log
The second example counts the number of lines containing a match, rather than the total number of occurrences of the word. This is an important distinction when the same text appears multiple times within a single line.
Sometimes, you need to do the opposite and exclude certain messages from the results. For example, to filter out all lines containing debug:
grep -v "debug" app.log
The -v option inverts the search condition. As a result, only lines that do not match the specified pattern will be displayed.
When you need to search for multiple types of messages simultaneously, you can use extended regular expressions with grep -E.
grep -Ei "error|failed|critical" app.log
This command finds lines containing any of the three specified patterns. It is useful during the initial analysis of log files when you need to quickly identify messages related to potential errors.
Another useful feature of grep is the ability to display context around matching lines. For example:
grep -C 3 "failed" app.log
The -C 3 option displays three lines before and after each match. This allows you to see not only the error message itself but also the events that occurred immediately before and after it.
To control the context separately, use -A (lines after the match) and -B (lines before the match).
The command also supports recursive searches within directories. For example:
grep -rn "TODO" ~/linux-lab
This example checks files in a specified directory and its subdirectories, finds lines containing “TODO”, and displays their line numbers.
To search only within specific file types, you can apply additional restrictions:
grep -rn --include="*.conf" "listen" /etc
This approach allows you to search for specific parameters in configuration files without manually examining the entire contents of system directories.
While grep is primarily used to search for matching lines, awk allows you to work with individual fields within those lines. It is a powerful tool for processing text-based tables, log files, and delimited data.
It works by reading lines sequentially, splitting them into fields, and performing specified actions. By default, spaces and tabs are used as field separators, but this behavior can be customized.
For example, the /etc/passwd file contains information about local user accounts. The fields in each entry are separated by colons. To extract only the usernames, you can run:
awk -F: '{print $1}' /etc/passwd
Here, `-F:` specifies a colon as the delimiter, and `$1` refers to the first field of each line.
If you need to obtain both the username and their UID:
awk -F: '{print $1, $3}' /etc/passwd
The variable $3 corresponds to the third field. This allows you to select only the specific attributes you need, without outputting the entire record.
awk also supports conditions. For example:
awk -F: '$3 >= 1000 {print $1, $3}' /etc/passwd
The command will display records where the UID is 1000 or greater. In many Linux distributions, this range is used for regular user accounts, though specific rules may vary. Therefore, this example serves as a way to filter by UID, rather than a universal method for precisely identifying all human user accounts.
Additionally, `awk` allows you to work with line numbers using the `NR` variable. For instance, you can output the fifth line of a file or count the total number of lines:
awk 'NR==5' app.log
awk 'END {print NR}' app.log
For DevOps and DevSecOps, `awk` is particularly useful when you need to quickly process large text-based datasets without writing a standalone program. For example, you can use it to extract specific log fields, count the number of entries, or generate a brief report based on the output of a system command.
`sed` — Text Editing and Transformation
A third tool worth knowing is `sed` (stream editor). It is designed for stream-based text processing and allows for operations such as replacing, deleting, filtering, and otherwise transforming lines of text.
The most common use case for `sed` is automated text replacement. For instance, if you need to change the value `debug` to `info` in a configuration file, you can run the following:
sed 's/debug/info/g' app.conf
In this example, `s` denotes a substitution operation, and `g` indicates that all occurrences in each line should be replaced.
By default, `sed` does not modify the original file; instead, it simply outputs the processed text. This is useful for verifying the result before applying any actual changes.
To write the result directly to a file, use the `-i` option. However, exercise caution when using it, as an incorrect substitution could corrupt a configuration or delete essential values.
A safer approach when using GNU sed involves creating a backup copy:
sed -i.bak 's/debug/info/g' app.conf
After the command is executed, the `app.conf` file will be modified, and its previous version will be saved under the name `app.conf.bak`.
In addition to replacing text, `sed` allows for filtering lines. For example, you can remove comments that begin with the `#` character, or empty lines, from the output:
sed '/^#/d' app.conf sed '/^$/d' app.conf
These examples use a regular expression. The ^ symbol denotes the beginning of a line, $ denotes the end, and d is used to remove the line from the output.
It is also possible to output only a specific range of lines:
sed -n '10,20p' app.log
This command will display lines 10 through 20, inclusive—useful when examining a specific section of a log file or configuration.
The true power of the Linux command line becomes apparent when different tools are used together. This is made possible by the “pipe” mechanism, represented by the `|` symbol.
It allows the standard output of one command to be passed as the standard input to the next. This enables the creation of data-processing sequences without the need for intermediate files.
For example, suppose we need to examine the last 1,000 entries in a log file and extract only the error messages:
tail -n 1000 app.log | grep -i "error"
First, `tail` retrieves the end of the file, after which `grep` filters the lines based on a specified word.
If you need to count the number of such lines, you can use:
tail -n 1000 app.log | grep -ic "error"
Or, for example, get the usernames from /etc/passwd, sort them, and display the first ten:
awk -F: '{print $1}' /etc/passwd | sort | head -n 10
In this case, awk extracts the required field, sort sorts the resulting list, and head limits the number of results.
These types of command combinations form the foundation of many Linux automation workflows. By using pipelines, you can quickly analyze system data, extract relevant information, and create lightweight checks without writing complex scripts.
However, it is important to remember that each command has its own limitations. For example, a simple grep search cannot replace proper analysis of structured JSON logs, while processing logs with awk requires an understanding of their format.
To reinforce the tools discussed, we will set up a small learning environment and perform several operations that resemble the day-to-day tasks of an administrator or DevOps engineer. All the actions described below take place within the home directory and do not require any changes to system configurations.
First, let’s create the structure for this learning project:
mkdir -p ~/linux-lab/{config,logs,backups}
cd ~/linux-lab
pwd
tree
After executing the commands, we will have separate directories for settings, logs, and backups.
Now, let’s create a simple configuration file:
printf 'mode=debug\nport=8080\n' > config/app.conf
The `printf` command generates text, and the `>` symbol redirects it to a file. If the file already exists, its previous content will be overwritten, so this operator should be used with caution.
Let’s check the result:
cat config/app.conf
We should get:
mode=debug port=8080
Before changing the configuration, let’s create a backup:
cp -p config/app.conf backups/app.conf.bak
Now you can change the value of the application’s operating mode:
sed -i 's/mode=debug/mode=info/' config/app.conf
Let’s check whether the changes have actually been made:
grep "mode=" config/app.conf
Expected result:
mode=info
Next, let’s create a small test log with a few messages:
printf '%s\n' \ 'INFO Application started' \ 'INFO Connected to database' \ 'ERROR Connection timeout' \ 'WARNING Retry scheduled' \ 'ERROR Request failed' \ > logs/app.log
Now you can practice searching for error messages:
grep -n "ERROR" logs/app.log
The command will find the matching lines and display their numbers. If you need to find out the number of such messages:
grep -c "ERROR" logs/app.log
In our case, the result will be 2.
Finally, let’s check the metadata of the created files:
stat config/app.conf file logs/app.log ls -lah config logs backups
These commands display configuration information, identify log types, and allow for the verification of the structure of created files.
In this process, we walked through a small yet typical operational scenario: we set up a project structure, prepared a configuration, created a backup, modified settings, generated a log, and located error messages within it.
A significant portion of day-to-day work in Linux consists of exactly these types of operations—though in real-world environments, you would be dealing with server configurations, application logs, and system service data rather than sample files.
In the first part of this series, we explored the Linux file system structure, learned how to navigate between directories, create, copy, and delete files, and locate specific information using standard command-line tools.
We paid special attention to working with system logs and processing text data using tools like `grep`, `awk`, and `sed`. These utilities are frequently used for troubleshooting errors, verifying configurations, automating tasks, and performing initial analysis of security events.
In the next installment of the “Linux for DevOps and DevSecOps” series, we will cover users and groups. We will examine account management mechanisms, the purpose of the `/etc/passwd` and `/etc/shadow` files, and how to use `sudo`. This will help you understand how Linux manages system access and why proper privilege management is a crucial component of its security.