Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

UNIT 2 : LINUX FILE STRUCTURE

Introduction to Linux File System and Structures –


Linux file system is a hierarchical structure that organizes files and directories on a
Linux operating system. The file system is rooted at the top-level directory, which is
called the root directory or simply "/". All other directories and files are located under
this directory in a tree-like structure.
The Linux file system is designed to be modular and extensible. Each directory has a
specific purpose, and files are stored in locations that make sense for their intended use.
For example, system configuration files are typically stored in the "/etc" directory, while
user files are stored in the "/home" directory.
The Linux file system follows the Filesystem Hierarchy Standard (FHS) which defines
the directory structure and layout of a Linux system. The FHS is a standardization effort
that aims to ensure consistency and compatibility across different Linux distributions.
Some important directories in the Linux file system include:
/bin: contains essential command-line utilities such as ls, cp, mv, etc.
/sbin: contains system administration utilities such as ifconfig, fdisk, etc.
/usr: contains user applications and support files such as libraries, headers, and
documentation.
/var: contains variable data files such as log files, mail spools, etc.
/etc: contains system-wide configuration files.
/home: contains user home directories.
Understanding the Linux file system structure and organization is important for system
administrators and users to effectively manage their Linux systems.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


inode (Index Node) :
An inode (short for index node) is a data structure used by the file system to store
information about a file or directory in a Unix or Linux operating system. Each
file or directory in a file system is represented by a unique inode number, which
is assigned when the file or directory is created.
The inode contains important information about the file or directory, such as its
owner and group, permissions, creation and modification timestamps, and the
location of the actual data on the disk. When a user requests to access a file or
directory, the file system uses the inode to locate the file data on the disk.
In addition to storing metadata about a file or directory, the inode also stores a
list of pointers to the disk blocks that contain the actual data of the file. This list
of pointers is called the inode's block allocation map or extent tree, and it allows
the file system to quickly access and read the file data from disk.
In Unix and Linux systems, the maximum number of inodes that can be created
is typically determined at the time the file system is created. This maximum
number of inodes is based on the size of the file system and the average size of
the files that are expected to be stored on it. If the file system runs out of available
inodes, it can no longer create new files or directories, even if there is still disk
space available.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


File Descriptor :
In a Unix or Linux operating system, a file descriptor is a unique identifier that is
used by the operating system to track and manage open files or other input/output
(I/O) resources such as sockets, pipes, and devices.
When a process opens a file or creates a new I/O resource, the operating system
assigns it a file descriptor, which is a non-negative integer value. The file
descriptor is used by the process to refer to the open file or I/O resource in
subsequent I/O operations, such as reading, writing, and closing.
By default, when a process starts, it has three open file descriptors: standard input
(stdin), standard output (stdout), and standard error (stderr), which are assigned
file descriptor values of 0, 1, and 2, respectively.
In addition to these standard file descriptors, a process can open additional files
or I/O resources by using the open() system call, which returns a new file
descriptor that can be used in subsequent I/O operations. The process can also
duplicate an existing file descriptor using the dup() or dup2() system calls, which
create a new file descriptor that refers to the same open file or I/O resource as the
original file descriptor.
File descriptors are an important concept in Unix and Linux programming, as
they allow processes to perform I/O operations on files and other resources in a
standardized way. By using file descriptors, processes can communicate with
each other through pipes and sockets, redirect their standard I/O streams, and
interact with system devices and resources.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


System Calls:
The mechanism used by an application program to request service
from the operating system is called System calls.
System calls often use a special machine code instruction which causes the
processor to change mode (e.g. to "supervisor mode" or "protected mode").
This allows the OS to perform restricted actions such as accessing hardware
devices or the memory management unit.

System calls are divided into 5 categories mainly :


 Process Control
 File Management
 Device Management
 Information Maintenance
 Communication

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


MADE WITH AND HARDWORK BY VIKAS KUMAWAT
Device Drivers:
Device drivers in Linux are software modules that allow the operating system to
communicate with the hardware devices attached to the system. These drivers provide
an abstraction layer between the operating system and the hardware, allowing the
operating system to communicate with the hardware in a standard way, without needing
to know the details of the specific hardware.
Linux device drivers are typically implemented as kernel modules, which are
dynamically loaded and unloaded by the kernel as needed. These modules can be
compiled into the kernel, or loaded at runtime using the "insmod" or "modprobe"
commands.
Device drivers in Linux are organized into several layers, each of which provides a
different level of abstraction:
1. Bus layer: This layer provides a standardized interface for communicating with
different buses, such as PCI, USB, or SCSI. Each bus has its own driver that handles
low-level communication with the hardware.
2. Device layer: This layer provides a standardized interface for communicating with
different types of devices, such as disk drives, network cards, or video cards. Each
device has its own driver that handles device-specific functionality.
3. Filesystem layer: This layer provides a standardized interface for accessing files on
different types of filesystems, such as ext4, NTFS, or FAT. Each filesystem has its
own driver that handles filesystem-specific functionality.
4. Network layer: This layer provides a standardized interface for communicating over
different types of networks, such as Ethernet or Wi-Fi. Each network device has its
own driver that handles network-specific functionality.
Writing a device driver for Linux typically involves the following steps:

1. Understanding the hardware: The first step in writing a device driver is to understand the
hardware that the driver will be communicating with. This includes understanding the
hardware architecture, the communication protocols used by the device, and the specific
commands and data formats used to communicate with the device.
2. Writing the driver code: Once the hardware is understood, the driver code can be written.
This involves implementing the necessary functions and data structures to interface with
the hardware, as well as implementing any device-specific functionality.
3. Testing and debugging: After the driver code is written, it must be tested and debugged to
ensure that it is working correctly. This involves testing the driver with different types of
hardware and under different conditions to ensure that it is reliable and performs well.
4. Integration with the kernel: Once the driver is tested and debugged, it can be integrated into
the Linux kernel. This involves building the driver as a kernel module and ensuring that it
is loaded correctly at boot time.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


System Calls For File Management :

create :
The create system call is used to create a new file or open an existing file with
write-only access, truncating the file to zero length if it already exists. It takes
two arguments: a const char * specifying the name of the file to be created, and
an int specifying the file mode to be used. The file mode is a bitwise OR of file
permission bits (e.g. 0644).
Syntax for the create system call:
int create(const char *pathname, mode_t mode);
The create system call creates a new file with the specified pathname and returns
a file descriptor to the file. If the file already exists, it is truncated to zero length.
The mode parameter specifies the file mode permissions to be set for the new
file.
Here's an example of how to use create to create a new file:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {


int fd = open("myfile.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Write to the file
char *str = "Hello, world!\n";
write(fd, str, strlen(str));
close(fd);
return 0;
}

This program creates a new file called "myfile.txt" with write-only access and
permissions 0644. It then writes the string "Hello, world!\n" to the file and closes
it. If an error occurs while opening the file, the ‘perror’ function is used to print
an error message to stderr.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


open :
The open system call is used to open or create a file in Linux.
The syntax for the open system call is:
#include <fcntl.h>

int open(const char *pathname, int flags);


int open(const char *pathname, int flags, mode_t mode);

The first argument, pathname, is the name of the file to open or create. The
second argument, flags, specifies how the file should be opened or created. The
flags argument can be a combination of the following constants:
O_RDONLY: Open the file for reading only.

O_WRONLY: Open the file for writing only.

O_RDWR: Open the file for reading and writing.

O_CREAT: Create the file if it does not exist.

O_TRUNC: Truncate the file to length 0 if it exists.

O_APPEND: Append data to the end of the file.

O_EXCL: If O_CREAT is also specified and the file already exists, fail with an
error.
O_DIRECTORY: Ensure that pathname refers to a directory.

O_NOFOLLOW: Do not follow symbolic links.

O_SYNC: Write data to the file and ensure that it is physically written to disk
before the open call returns.
O_CLOEXEC: Set the close-on-exec flag for the file descriptor.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


The optional third argument, mode, specifies the permissions to be set on the file
if it is created. If the file already exists, this argument is ignored. The mode
argument is a combination of the following constants:
S_IRWXU: Read, write, and execute permissions for the owner of the file.

S_IRUSR: Read permission for the owner of the file.

S_IWUSR: Write permission for the owner of the file.

S_IXUSR: Execute permission for the owner of the file.

S_IRWXG: Read, write, and execute permissions for the group owner of the file.

S_IRGRP: Read permission for the group owner of the file.

S_IWGRP: Write permission for the group owner of the file.

S_IXGRP: Execute permission for the group owner of the file.

S_IRWXO: Read, write, and execute permissions for others.

S_IROTH: Read permission for others.

S_IWOTH: Write permission for others.

S_IXOTH: Execute permission for others.

The open system call returns a file descriptor, which is an integer that identifies
the open file. If the call fails, it returns -1 and sets errno to indicate the error.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


close :
The close system call is used to close a file descriptor that was previously opened
using the open system call. When a process finishes working with a file, it should
close it using the close system call to free up resources.
The syntax for the close system call is as follows:
#include <unistd.h>
int close(int fd);

Where, fd is the file descriptor of the file that needs to be closed.


The close system call returns 0 on success and -1 on failure, with the specific
error code set in the errno variable. Some common reasons for failure include:
 The file descriptor passed to close is not valid or is not open for writing.
 A signal was received while the close system call was in progress.
 A file system error occurred while trying to write the changes to disk.
Here's an example usage of the close system call:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("Failed to open file");
return 1;
}

// do some work with the file

int result = close(fd);


if (result == -1) {
perror("Failed to close file");
return 1;
}
return 0;
}

In this example, we open the file "example.txt" for reading using the open system
call, do some work with it, and then close it using the close system call. The
perror function is used to print any error messages that occur.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


read :
The read system call is used to read data from a file descriptor. Its syntax is as
follows:
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

The first argument fd is the file descriptor from which to read data. The second
argument buf is a buffer where the read data will be stored. The third argument
count is the maximum number of bytes to read.
The read system call returns the number of bytes actually read, or -1 if an error
occurs. If the return value is 0, it means that the end of the file has been reached.

write :
The write() system call is used to write data to a file descriptor (a connection to
a file or other input/output resource).
The syntax for the write() system call is:
ssize_t write(int fd, const void *buf, size_t count);
where:
fd: file descriptor to write to.
buf: pointer to the buffer containing the data to write.
count: number of bytes to write.
The write() system call returns the number of bytes actually written, or -1 if an
error occurred. It writes count bytes from the buffer buf into the file that has as
its descriptor fd.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


lseek :
The lseek system call is used to reposition the file offset of an open file descriptor.
It is commonly used to move the read/write pointer to a specific location in the
file.
The syntax of lseek is:
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
where fd is the file descriptor of the file being manipulated, offset is the number
of bytes to move the file pointer, and whence specifies the starting position from
which the offset is applied. The possible values of whence are:
SEEK_SET - The offset is set to offset bytes from the beginning of the file.
SEEK_CUR - The offset is set to its current location plus offset bytes.
SEEK_END - The offset is set to the end of the file plus offset bytes.
The return value of lseek is the resulting offset from the beginning of the file after
the operation has been performed.

link :
The link() system call creates a new hard link to an existing file. A hard link is a
secondary name for an existing file that refers to the same inode on disk. Creating
a hard link does not create a new copy of the file; it simply creates another name
for the same file.
The syntax for the link() system call is as follows:
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
where oldpath is the path to an existing file, and newpath is the path to the new
hard link that will be created.
The link() system call returns 0 on success, or -1 on failure, in which case the
errno variable is set to indicate the specific error that occurred.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


symlink :
symlink() is a system call used to create a symbolic link to an existing file. It
takes two arguments: the name of the file to be linked, and the name of the
symbolic link to be created.
The syntax for the symlink() function is:

#include <unistd.h>

int symlink(const char *target, const char *linkpath);


Here, target is the name of the file that the symbolic link should point to, and
linkpath is the name of the symbolic link to be created.
If successful, symlink() returns 0. On error, it returns -1 and sets errno
appropriately.Example :
#include <unistd.h>
#include <stdio.h>

int main() {
if (symlink("/home/user/myfile.txt", "/home/user/mylink.txt") != 0) {
perror("symlink");
return 1;
}
return 0;
}

This example creates a symbolic link /home/user/mylink.txt that points to the


file /home/user/myfile.txt.

unlink :
unlink() is a system call used to remove a file from the file system. It takes a
single argument, which is the path to the file to be removed.
Here is the syntax for using unlink() in C programming language:
int unlink(const char *pathname);
The unlink() function returns 0 if the file is successfully removed, or -1 if an
error occurs. The error code can be retrieved using the errno variable.
Note that unlink() does not remove directories. To remove a directory, you can
use the rmdir() function.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


stat :
The stat system call is used to retrieve information about a file or file system. It
takes a filename as input and fills a structure with information about the file, such
as its type, size, and modification time.
The syntax for stat system call is:
int stat(const char *path, struct stat *buf);
path: The path of the file for which we want to retrieve the information.
buf: A pointer to a structure where the information will be stored.
The stat system call returns 0 on success and -1 on failure. If it returns -1, then
the errno variable will be set to indicate the error that occurred.
Here is an example usage of stat system call to retrieve information about a file:
#include <stdio.h>
#include <sys/stat.h>

int main() {
struct stat fileStat;
if (stat("example.txt", &fileStat) == -1) {
perror("stat failed");
return 1;
}
printf("File size: %ld bytes\n", fileStat.st_size);
printf("File modification time: %ld\n", fileStat.st_mtime);
printf("File type: ");
switch (fileStat.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown\n"); break;
}
return 0;
}

This program retrieves information about the file named "example.txt", and prints
its size, modification time, and type.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


fstat :
fstat() is a system call used to get information about an open file descriptor. It
takes a file descriptor as its first argument and a pointer to a struct stat as its
second argument. The struct stat contains information about the file, such as its
size, permissions, owner, and timestamps.
Here is an example of using fstat():
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
int fd = open("file.txt", O_RDONLY);
struct stat st;
fstat(fd, &st);
printf("File size: %ld bytes\n", st.st_size);
close(fd);
return 0;
}
In this example, the open() function is used to open the file "file.txt" for reading,
and the resulting file descriptor is stored in the variable fd. The fstat() function
is then called to get information about the file, and the struct stat is stored in the
variable st. Finally, the file is closed using close().
The st struct contains the following fields:
st_dev: The device ID of the device containing the file.
st_ino: The inode number of the file.
st_mode: The file mode (permissions).
st_nlink: The number of hard links to the file.
st_uid: The user ID of the file's owner.
st_gid: The group ID of the file's owner.
st_rdev: The device ID (if the file is a special file).
st_size: The size of the file in bytes.
st_atime: The last access time of the file.
st_mtime: The last modification time of the file.
st_ctime: The last status change time of the file.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


lstat :
lstat() is a system call used to retrieve the attributes of a file or symbolic link. It
is similar to stat(), but when passed a symbolic link, it returns information about
the link itself rather than the file it refers to.
The syntax of lstat() is as follows:
int lstat(const char *path, struct stat *buf);
Here, path is the path to the file or symbolic link whose attributes are to be
retrieved, and buf is a pointer to a struct stat buffer where the information will
be stored. The function returns 0 on success and -1 on failure.
lstat() is often used to determine the type of a file, whether it is a regular file,
directory, symbolic link, etc., as well as other attributes such as permissions and
modification times.

chmod :
chmod is a system call that is used to change the permissions of a file or
directory. It allows the user to add or remove read, write, and execute
permissions for the owner, group, and other users.
Syntax:
int chmod(const char *pathname, mode_t mode);
Here, pathname is the name of the file or directory whose permissions are to be
changed, and mode is the new permission mode. The mode argument is an
integer that represents the new permissions as a combination of bits.
The permissions are represented by three digits, where the first digit is for the
owner, the second digit is for the group, and the third digit is for other users.
Each digit is a sum of the permissions for read, write, and execute, where
read=4, write=2, and execute=1.
For example, to give read, write, and execute permissions to the owner, and
only read permission to the group and others, the mode argument would be
0o744 (owner: 7=4+2+1, group: 4=4, others: 4=4).
The chmod system call returns 0 on success, and -1 on failure, setting the errno
variable to indicate the error.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


chown:
The chown system call in Linux is used to change the owner and group of a file
or directory. The syntax of the chown system call is:
int chown(const char *pathname, uid_t owner, gid_t group);
Here, pathname is the path of the file or directory whose owner and group you
want to change, owner is the user ID of the new owner, and group is the group
ID of the new group.
For example, to change the owner of a file named myfile.txt to user alice and
group users, you can use the following code snippet:
#include <unistd.h>
#include <sys/types.h>

int main() {
const char *path = "myfile.txt";
uid_t uid = getpwnam("alice")->pw_uid;
gid_t gid = getgrnam("users")->gr_gid;
chown(path, uid, gid);
return 0;
}

Here, getpwnam and getgrnam are used to retrieve the user and group IDs of
alice and users, respectively.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


Directory API :
In Linux, directories are also considered files, but they are special files that
contain a list of files and subdirectories within them. The Directory API in Linux
provides a set of system calls that enable programs to manipulate directories and
the files and subdirectories within them.
Using the Directory API, programs can create, open, and close directories, read
the contents of directories, create and delete files and subdirectories within them,
and change their attributes such as permissions and ownership. These operations
can be performed using system calls such as opendir, readdir, closedir, mkdir,
rmdir, chdir, and getcwd, among others.
The Directory API is essential for file management in Linux, as it enables
programs to access and manipulate files and directories, and provides a
convenient way for users to organize and manage their files.

opendir :
The opendir() function is a Directory API function in Linux that opens a
directory stream corresponding to the directory name passed as an argument. It
returns a pointer to the DIR stream, which is used in subsequent directory-related
system calls.
The syntax for opendir() is as follows:
DIR *opendir(const char *name);
Here, name is a character pointer representing the name of the directory to be
opened. The function returns a pointer to the DIR stream if successful, and NULL
if it encounters an error.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


readdir :
The readdir function is part of the directory API in Linux and is used to read the
contents of a directory. It reads the next entry from the directory stream and
returns a pointer to a dirent structure. The dirent structure contains information
about the directory entry, such as its name, inode number, file type, and file size.
Here is the syntax for readdir function:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
The dirp argument is a pointer to the directory stream that was opened with
opendir. The function returns a pointer to a dirent structure on success, and
NULL on failure or when the end of the directory stream is reached.
Here is an example of using readdir to read the contents of a directory:
#include <stdio.h>
#include <dirent.h>

int main() {
DIR *dir;
struct dirent *entry;

dir = opendir("/path/to/directory");
if (dir == NULL) {
perror("opendir");
return 1;
}

while ((entry = readdir(dir)) != NULL) {


printf("%s\n", entry->d_name);
}

closedir(dir);
return 0;
}

This program opens a directory using opendir, reads the contents of the directory
using readdir, and prints the name of each directory entry to the console. It then
closes the directory stream using closedir.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


closedir :
The closedir() function is a system call used to close a directory stream opened
by the opendir() function. It takes one argument, which is the pointer to the
directory stream to be closed. Once a directory stream is closed, any further
access to it will be invalid.
The syntax for closedir() function is:
#include <dirent.h>
int closedir(DIR *dirp);
Here, dirp is a pointer to the directory stream to be closed.
The closedir() function returns 0 on success and -1 on failure.
mkdir :
The mkdir system call in Linux is used to create a new directory with a specified
name and permission bits. The syntax for the mkdir command is as follows:
int mkdir(const char *pathname, mode_t mode);
Here, pathname is the name of the new directory that is to be created, and mode
specifies the permission bits for the new directory. The permission bits can be
specified using the same syntax as for the chmod command.
For example, the following code creates a new directory called newdir with read,
write, and execute permissions for the owner, and read and execute permissions
for others:
#include <sys/stat.h>
#include <sys/types.h>

int main() {
const char* dir_name = "newdir";
int status = mkdir(dir_name, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
if (status == -1) {
// handle error
}
return 0;
}
In this example, S_IRWXU represents read, write, and execute permissions for
the owner, S_IRGRP | S_IXGRP represents read and execute permissions for
the group, and S_IROTH | S_IXOTH represents read and execute permissions
for others. The bitwise OR operator (|) is used to combine these permission bits
into a single mode value that is passed to the mkdir function.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


rmdir :
The rmdir system call is used to remove an empty directory.
Syntax:
#include <unistd.h>
int rmdir(const char *path);
Here, path: The path to the directory to be removed.
Return value:
On success, 0 is returned.
On failure, -1 is returned, and the error number is set appropriately.
Description:
The rmdir system call removes the directory entry specified by path and
decrements the link count of the directory. If the link count reaches 0, the
directory and its contents are removed.
The directory must be empty, or the EEXIST or ENOTEMPTY error will be
returned.
The user must have write and execute permissions on the directory in order to
remove it.
Example:
#include <stdio.h>
#include <unistd.h>

int main() {
int status = rmdir("my_directory");
if(status == 0) {
printf("Directory removed successfully.\n");
} else {
printf("Failed to remove directory.\n");
}
return 0;
}

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


umask :
The umask system call can be used by programs to set the umask value
programmatically. The umask system call takes a single argument, which is the
new umask value to set.
The umask value is usually expressed as an octal number, where each digit
represents the permissions that should be masked for the owner, group, and
others, respectively.
The syntax for using the umask system call is as follows:
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);

Here, the mask argument is an integer representing the new mask to be set. The
return value of the umask() function is the previous mask value.
For example, to set the umask to 022 (meaning that the group and others will have
read permission, but not write or execute permission), you would use the
following code:
#include <sys/stat.h>
mode_t old_mask = umask(022);

This will set the umask value to 022 and return the previous umask value (which
can be used to restore the previous umask value later if needed).

File Links :
A link in UNIX is a pointer to a file. Like pointers in any programming
languages, links in UNIX are pointers pointing to a file or a directory. Creating
links is a kind of shortcuts to access a file. Links allow more than one file name
to refer to the same file, elsewhere.
There are two types of links :
1. Soft Link or Symbolic links
2. Hard Links

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


Hard Link Soft Link
 Each hard linked file is assigned the  A soft link is similar to the file shortcut
same Inode value as the original, feature which is used in Windows
therefore they reference the same Operating systems. Each soft linked file
physical file location. contains a separate Inode value that
points to the original file. Soft links can
be linked across different file systems.

 ls -l command shows all the links with  ls -l command shows all links with first
the link column shows number of links. column value l? and the link points to
original file.

 Links have actual file contents  Soft Link contains the path for original
file and not the contents.

 Removing any link, just reduces the link  Removing soft link doesn’t affect
count, but doesn’t affect other links. anything but removing original file, the
link becomes “dangling” link which
points to nonexistent file.

 Even if we change the filename of the  If we change the name of the original file
original file then also the hard links then all the soft links for that file become
properly work. dangling i.e. they are worthless now.

 We cannot create a hard link for a  A soft link can link to a directory.
directory to avoid recursive loops.

 If original file is removed then the link  if the original file is deleted or moved, the
will still show the content of the file. soft linked file will not work correctly
(called hanging link).

 The size of any of the hard link file is  The size of the soft link is equal to the
same as the original file and if we length of the path of the original file we
change the content in any of the hard gave. E.g if we link a file like ln -s
links then size of all hard link files are /tmp/hello.txt /tmp/link.txt then the
updated. size of the file will be 14bytes which is
equal to the length of the
“/tmp/hello.txt”.

 The disadvantage of hard links is that it  Link across file systems: If you want to
cannot be created for files on different link files across the file systems, you can
file systems and it cannot be created for only use symlinks/soft links.
special files or directories.

 Command to create a hard link is:  Command to create a Soft link is:
ln existing_file new_link ln -s existing_file new_link

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


Environment Variables :
Environment variables are variables in system that describe the current environment
settings. These settings help the operating system to access various settings. These
variables basically define the behavior of the environment.

The use of environment variables in Linux is to provide a way for programs and
processes to access configuration information without hardcoding values into the
program. This makes it easier to change configuration settings without having to modify
the program's code.
Here are some of the commonly used environment variables in Linux along with their
use:
PATH - This variable stores the system path, which is a list of directories that the shell
searches when looking for a command to execute.
HOME - This variable contains the path to the current user's home directory.
USER - This variable contains the username of the current user.
TERM - This variable contains the terminal type being used.
PS1 - This variable contains the primary prompt string used by the shell.
LANG - This variable contains the default system language.
SHELL - This variable contains the path to the user's default shell.
DISPLAY - This variable contains the display number of the X Window System.
TMPDIR - This variable contains the path to the system's temporary directory.

Path Setting :
In Linux, the PATH variable is an environment variable that stores a list of directories
that the shell searches when looking for a command to run. When a user enters a
command in the terminal, the shell will look in each directory listed in PATH in the
order they are listed to find the executable file for that command.
The PATH variable is usually set in the user's shell initialization files, such as .bashrc
or .profile. It can be modified using the export command in the terminal or by editing
the initialization files.
The syntax for adding a directory to the PATH variable is as follows:
export PATH=$PATH:/path/to/directory
This command will add /path/to/directory to the end of the PATH variable. To add a
directory to the beginning of the PATH variable, use:
export PATH=/path/to/directory:$PATH

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


/etc/passwd file :
The /etc/passwd file is a system file in Linux that contains information about all the
user accounts on the system. Each line in the file represents a user account and
contains several fields separated by colons (:). The fields are as follows:
1. Username: This is the user's login name.
2. Password: This field used to store encrypted passwords. Modern systems typically
use /etc/shadow to store password hashes instead, which is only accessible by the
root user.
3. UID: This is the user's numeric user ID.
4. GID: This is the user's numeric group ID.
5. User ID Info: This field contains additional information about the user, such as their
full name or a comment.
6. Home directory: This is the absolute path to the user's home directory.
7. Shell: This is the absolute path to the user's default shell.
The /etc/passwd file is used by various system tools and utilities to look up information
about users on the system. For example, the who command uses the /etc/passwd file to
display information about currently logged-in users.
/etc/shadow file :
The /etc/shadow file is a system file in Linux that stores encrypted password
information for user accounts. It is readable only by the root user and is used to enhance
the security of the system by keeping the password information separate from the rest
of the system files.
The file consists of several fields separated by colons, with each line representing the
password information for a single user. The fields are as follows:
1. username: the user's login name
2. password: the encrypted password, represented by a string of characters (x in the file
indicates that the password is stored in the /etc/shadow file)
3. last password change: the number of days since the password was last changed
4. minimum password age: the number of days that must pass before the password can
be changed again
5. maximum password age: the number of days after which the password must be
changed
6. password warning period: the number of days before the password expires that the
user will be warned
7. account inactive period: the number of days after the password expires that the
account will be disabled
8. account expiration date: the date when the account will be disabled, represented as
the number of days since January 1, 1970 (also known as the Unix epoch)
9. reserved field: for future use

MADE WITH AND HARDWORK BY VIKAS KUMAWAT


Add, Modified and Delete Users :
Adding Users:
To add a new user, you can use the adduser command or useradd command,
depending on your distribution.
For example, to add a new user named "vikas", you can use the following
command:
sudo adduser vikas
This will create a new user account with a home directory and a shell.

Modifying Users:
To modify an existing user, you can use the usermod command.
For example, to change the home directory for the user "vikas", you can use the
following command:
sudo usermod -d /new/home/directory vikas

Deleting Users:
To delete a user account, you can use the userdel command.
For example, to delete the user "vikas", you can use the following command:
sudo userdel vikas
Keep in mind that when you delete a user account, the user's home directory and
all of their files will also be deleted. To keep the user's home directory and files,
you can use the -r option with the userdel command:
sudo userdel -r vikas
Note: You may need to use sudo or be logged in as root to execute these
commands.

MADE WITH AND HARDWORK BY VIKAS KUMAWAT

You might also like