CIS120Linux Fundementals
Chapter 1
Introduction to Linux
Unix and the Origins of Linux
Unix is a powerful, multiuser, multitasking operating system that originated in the late 1960s and early 1970s at AT&T's Bell Labs. It was initially developed by Ken Thompson, Dennis Ritchie, and others. Unix quickly became the foundation for many subsequent operating systems due to its robustness, flexibility, and portability. Its design philosophy emphasized simplicity and the use of small, modular utilities that could be combined to perform complex tasks. This modularity and efficiency made Unix highly influential in the computing world.
Linux, a Unix-like operating system, was created by Linus Torvalds in 1991 as a free and open-source alternative to the proprietary Unix. Torvalds, a Finnish software engineer, started the Linux project as a personal hobby while he was a student at the University of Helsinki. In 1991, he announced the project on the MINIX newsgroup, inviting others to contribute to the development. Torvalds made the source code available under the GNU General Public License (GPL), allowing anyone to use, modify, and distribute it. This collaborative approach marked the beginning of Linux's journey and its rapid growth.
GNU/Linux
While the term "Linux" is commonly used to refer to the entire operating system, it is technically only the kernel. The complete operating system is often referred to as GNU/Linux, acknowledging the critical role of the GNU Project in its development. The GNU Project, started by Richard Stallman in 1983, aimed to create a free Unix-like operating system. By the early 1990s, most components of the GNU system were ready, except for the kernel. Linus Torvalds' Linux kernel filled this gap, and together with the GNU components, formed a complete free operating system.
Open Source and Its Importance
Open Source Software (OSS) is characterized by its availability for anyone to use, modify, and distribute freely. The source code of OSS is openly shared, which encourages collaboration and community development. This model fosters innovation and rapid development, as developers from around the world can contribute to the project. Key features of open source include transparency, collaboration, freedom to modify the software, and strong community support. Linux, released under the GPL, exemplifies these principles, allowing it to grow and improve through global contributions.
The open-source movement has had a profound impact on the software industry, promoting the development of high-quality, reliable software. Major companies and organizations, including Google, IBM, and NASA, use and contribute to open-source projects. The open-source model also supports the idea of software freedom, where users have control over their software and can tailor it to meet their specific needs.
Linux Architecture
The architecture of Linux is composed of several layers, each serving a specific function within the operating system. At the base is the hardware layer, which includes all the physical devices such as the CPU, memory, and disk drives. Above this is the kernel layer, the core of the operating system that interacts directly with the hardware. The kernel manages critical tasks like memory management, process management, device management, and system calls.
System libraries, which provide functions and system calls for applications to interact with the kernel, sit above the kernel layer. These libraries enable developers to write applications without needing to manage hardware directly. System utilities are specialized programs that perform individual management tasks, such as disk management and network configuration. These utilities offer essential tools for system administrators and users to manage the operating system.
At the top of the architecture are user applications, which are the software programs used by end-users, such as browsers, text editors, and media players. These applications interact with the system libraries and utilities to perform various tasks, providing a user-friendly interface for interacting with the operating system.
Understanding the Kernel
The kernel is the heart of the Linux operating system, managing hardware resources and facilitating communication between hardware and software. It handles essential functions like memory management, process management, device management, and system calls. The kernel ensures that multiple processes can run simultaneously without interfering with each other, providing a stable and efficient computing environment.
There are different types of kernels, including monolithic kernels and microkernels. Monolithic kernels, like the one used in Linux, include all essential services and device drivers in one large block of code running in a single address space. This design can offer performance advantages but may become complex as more features are added. Microkernels, on the other hand, have only the most basic functions, with additional services running in user space. This design can improve stability and security but may introduce performance overhead.
The Linux kernel is known for its modularity, allowing users to load and unload modules dynamically. This feature enables customization and optimization of the operating system for different hardware and use cases. The Linux kernel also supports a wide range of hardware platforms, from embedded systems to supercomputers, making it highly versatile and adaptable.
In summary, Linux is a Unix-like, open-source operating system created by Linus Torvalds. Its development and evolution have been driven by the open-source community, making it a powerful and flexible operating system. Understanding the basics of Linux, including its architecture and the role of the kernel, provides a solid foundation for further exploration of this widely-used and influential software. As an open-source project, Linux continues to evolve, driven by contributions from developers worldwide, ensuring its relevance and innovation in the ever-changing technology landscape.
Understanding the Linux File System
The Linux file system is structured quite differently from Windows. It uses a hierarchical directory structure where everything starts from the root directory, denoted by a single slash (/
), and branches out into various other directories each with its specific purpose. In this discussion, we'll cover the main directories you'll encounter in a Linux system and what they're typically used for.
Basic Structure of the Linux File System
/
(Root Directory): At the top of the file system hierarchy, the root directory contains all other directories and files. It is the starting point of the file system./bin
(User Binaries): Contains essential user binaries (programs) that are generally needed by both the system administrator and normal users./sbin
(System Binaries): Like/bin
, this directory holds binaries, but these are usually not intended for access by ordinary users. They are essential for system administration (e.g.,init
,ip
,mount
)./etc
(Configuration Files): Contains configuration files required by all programs. This also includes startup and shutdown shell scripts used to start/stop individual programs./dev
(Device Files): Includes device files, which are special files that either represent or are connected to hardware devices, including terminal devices, usb, or any device attached to the system./proc
(Process Information): A virtual file system containing information about system processes. It's mapped to/proc
and isn't a real file system in that it doesn't use disk space./var
(Variable Files): Contains files that are expected to grow in size, such as logs (/var/log
), spool files, and cached data./tmp
(Temporary Files): Intended for storage of temporary files./usr
(User Programs): Used for all user-related programs, libraries, documentation, etc. It contains multiple subdirectories, including:/usr/bin
for binary files/usr/sbin
for system binaries/usr/local
for user programs installed from source or software not officially shipped with the distribution
/home
(Home Directories): Contains the personal directories of all users. Each user has a directory named after their user account within/home
where they store their personal files./boot
(Boot Loader Files): Contains files needed to start the boot process, including the Linux kernel itself and the boot loader (e.g., GRUB)./lib
(System Libraries): Contains essential shared libraries and kernel modules needed to boot the system and run commands in root file system.
Examples of Navigating and Understanding the Linux File System
1. Listing configuration files
You might want to see what configuration files are present for system-wide settings:
ls /etc
2. Checking mounted devices
To see all currently mounted devices and their partitions, you can look at:
cat /proc/mounts
3. Viewing user-specific binaries
If you want to check what binaries are available for all users:
ls /usr/bin
4. Exploring your home directory
To navigate to your home directory and see its contents:
cd ~ # ~ is a shortcut for /home/yourusername
ls
5. Viewing system logs
To check system logs, such as messages related to system functions:
sudo less /var/log/syslog
Conclusion
The Linux file system's hierarchical structure is designed to segregate and organize files in a logical manner, enhancing security, scalability, and manageability. By understanding the role of each directory within this structure, users and administrators can manage their systems more effectively. This model also supports permissions and ownership, making it highly versatile for multi-user and multi-process operations.
pwd, cd and tree Commands
The cd
, pwd
, and tree
commands are essential tools for navigating the Linux file system efficiently. The cd
(change directory) command allows users to move between directories, making it possible to access files and organize the system effectively. The pwd
(print working directory) command helps users confirm their current location within the file system, which is particularly useful when working with deeply nested directories. The tree
command provides a structured view of the directory hierarchy, displaying files and subdirectories in an easy-to-read format. Together, these commands enable users to move through the file system, verify their position, and visualize the directory structure, improving workflow and organization.
pwd Command
The pwd
command in Linux stands for "print working directory." This command is used to display the current directory path you are working in. It is especially useful for verifying your location within the file system, which can help avoid confusion when navigating complex directory structures.
The command below outputs the absolute path of the current working directory. For example, if you are in /home/user/Documents
, this command will output /home/user/Documents
.
pwd
Outputs:
$ pwd
/home/user/Documents
cd Command
The cd
command in Linux is used to change the current working directory. This command is fundamental for navigating the file system. Understanding how to use cd
effectively will help you move between directories quickly and efficiently.
What the cd Command Does
The basic usage of the cd
command changes the current working directory to the specified directory. It allows you to move to different directories, access files, and organize your work environment.
NOTE: In Linux directory structures, the single dot (".") represents the current directory, while the double dot ("..") refers to the parent directory, which is one level above the current directory. The dot (".") is often used to indicate files or commands within the current directory, such as "./script.sh" to run a script located in the directory you are currently in. On the other hand, the double dot ("..") is used to navigate up the directory tree. For example, using "cd .." will move you to the parent directory. These shortcuts provide an efficient way to reference and navigate directories in Linux.
Common Path Shortcuts for the cd Command
Here is a table of some of the most common path shortcuts you can use with the cd
command and their descriptions:
Shortcut | Description |
---|---|
.. or ../ |
Move up one directory level (parent directory) |
~ |
Change to the home directory |
- |
Change to the previous directory |
/ |
Change to the root directory |
. or ./ |
Stay in the current directory |
Relative and Absolute Paths
Understanding the difference between relative and absolute paths is crucial for effective navigation in the Linux file system.
Absolute Path
An absolute path is the complete path from the root directory to the desired directory or file. It always starts with a forward slash /
.
cd /home/user/Documents
This command uses an absolute path to change the current directory to /home/user/Documents
.
Relative Path
A relative path specifies a location relative to the current directory. It does not start with a forward slash/
.
cd Documents
If you are currently in /home/user
, this command uses a relative path to change the directory to /home/user/Documents
.
Examples:
Changing to a Specific Directory:
This command changes the current working directory to /home/user/Documents
.
cd /home/user/Documents
Moving Up One Directory Level (parent directory):
This command moves the current working directory up one level. For example, if you are in /home/user/Documents
, this command will take you to /home/user
.
cd ..
Changing to the Home Directory:
This command changes the current working directory to the home directory of the user. For example, if your home directory is /home/user
, this command will take you there from any location.
cd ~
Changing to the Root Directory:
This command changes the current working directory to the root directory of the file system.
cd /
Returning to the Previous Directory:
This command changes the current working directory to the previous directory you were in. It is useful for toggling between two directories.
cd -
Staying in the Current Directory:
This command keeps you in the current directory. It is often used in scripts to explicitly state that the current directory should remain unchanged.
cd .
tree Command
The tree
command in Linux is used to display the directory structure in a hierarchical format, making it easier to visualize the organization of files and subdirectories. By default, it starts from the current directory and recursively lists all files and directories in a tree-like structure. Users can modify its behavior with options such as -L
to limit the depth of recursion or -d
to show only directories.
The tree
command supports several options to customize its output, as shown in the table below:
Option | Description |
---|---|
-L N |
Limits the depth of directory traversal to N levels. For example, tree -L 2 would just go two levels deep. |
-d |
Displays only directories, excluding files. |
-a |
Shows all files, including hidden ones. |
-f |
Prints the full path for each file and directory. |
-h |
Displays file sizes in a human-readable format. |
--du |
Shows the cumulative disk usage of each directory. |
--dirsfirst |
Lists directories before files in the output. |
Below is a sample output of the tree
command. In this example, the user is in a directory that contains three subdirectories: Documents
, Pictures
, and Scripts
. The tree
command displays the hierarchical structure of these folders and their contents. The Documents
folder contains two files, report.docx
and notes.txt
. The Pictures
folder has a subdirectory named vacation
, which contains two image files, beach.jpg
and sunset.jpg
. The Scripts
folder includes two script files, script.sh
and backup.py
. This output provides a clear visual representation of how files and directories are organized within the current working directory.
.
├── Documents
│ ├── report.docx
│ ├── notes.txt
├── Pictures
│ ├── vacation
│ │ ├── beach.jpg
│ │ ├── sunset.jpg
├── Scripts
│ ├── script.sh
│ ├── backup.py
ls Command
The ls
command in Linux is used to list directory contents. It is one of the most frequently used commands and provides various options to customize the output to meet different needs. The command displays information about files and directories, including their names, sizes, permissions, and more.
What the ls Command Does
The basic usage of the ls
command without any options lists the files and directories in the current directory. By adding various options to the command, you can control the amount and type of information displayed, as well as the format of the output.
Common Options for the ls
Command
Here is a table of some of the most popular options for the ls
command and their descriptions:
Option | Description |
---|---|
-l |
Use a long listing format |
-a |
Include directory entries whose names begin with a dot (.) |
-h |
With -l , print sizes in human-readable format (e.g., 1K, 234M, 2G) |
-R |
List subdirectories recursively |
-t |
Sort by modification time, newest first |
-r |
Reverse order while sorting |
-S |
Sort by file size, largest first |
-1 |
List one file per line |
-d |
List directories themselves, not their contents |
-i |
Print the index (inode) number of each file. An inode number in Linux is a unique identifier for a file or directory in a file system. Inodes are data structures that store metadata about files, such as their permissions, size, and owner. |
-F |
Append indicator (one of */=>@) |
-G |
Inhibit display of group information |
--color |
Colorize the output (when output is to a terminal) |
-p |
Append a slash (/) to directory names |
-Q |
Enclose entry names in double quotes |
--full-time |
Use a full time format for listings |
-v |
Natural sort of (version) numbers within text |
Examples
Basic ls command:
Displays a list of files and directories in the current location.
ls
Output:
file1.txt file2.txt dir1 dir2
Long listing format:
Provides detailed information such as file permissions, owner, and size.
ls -l
Output:
total 16
-rw-r--r-- 1 user group 1234 Jun 4 12:34 file1.txt
-rw-r--r-- 1 user group 5678 Jun 4 12:34 file2.txt
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir1
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir2
Including hidden files:
Shows all files, including those that start with a dot (.), which are hidden by default.
ls -a
Output:
. .. .hiddenfile file1.txt file2.txt dir1 dir2
Human-readable file sizes:
Displays file sizes in KB, MB, or GB instead of bytes.
ls -lh
Output:
total 16K
-rw-r--r-- 1 user group 1.2K Jun 4 12:34 file1.txt
-rw-r--r-- 1 user group 5.6K Jun 4 12:34 file2.txt
drwxr-xr-x 2 user group 4.0K Jun 4 12:34 dir1
drwxr-xr-x 2 user group 4.0K Jun 4 12:34 dir2
Recursive listing:
Lists the contents of all subdirectories as well.
ls -R
Output:
.:
file1.txt file2.txt dir1 dir2
./dir1:
file3.txt
./dir2:
file4.txt
Sorting by modification time:
Displays files in order of their last modification, newest first.
ls -lt
Output:
total 16
-rw-r--r-- 1 user group 5678 Jun 4 12:34 file2.txt
-rw-r--r-- 1 user group 1234 Jun 4 12:34 file1.txt
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir1
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir2
Reverse order sorting:
Lists files in reverse order, with the oldest files displayed first.
ls -lr
Output:
total 16
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir2
drwxr-xr-x 2 user group 4096 Jun 4 12:34 dir1
-rw-r--r-- 1 user group 5678 Jun 4 12:34 file2.txt
-rw-r--r-- 1 user group 1234 Jun 4 12:34 file1.txt
Conclusion
The ls
command is a powerful tool for navigating and managing files and directories in Linux. By understanding and using the various options available, you can customize the output to suit your needs and efficiently work with your filesystem. Experiment with the different options and combinations to get comfortable with this essential command.
The Less Command
Lesson on the less
Command in Linux
Introduction to less
In Linux, less
is a command-line utility that allows users to view the contents of a file interactively. It is an improved version of the older more
command and provides features such as scrolling both forwards and backwards through text files, searching within files, and navigating large files efficiently.
Basic Usage
To use less
, simply type less
followed by the name of the file you want to view:
less filename.txt
This opens filename.txt
in the less
viewer, where you can navigate using the following keys:
Navigation
Here are the navigation keys you can use while viewing a file with less
:
Key Combination | Description |
---|---|
Up/Down Arrows or j/k | Scroll up and down one line at a time. |
Page Up/Page Down or [SPACE]/[b] | Scroll up and down one screen at a time. |
G | Go to the end of the file. |
1G or gg | Go to the beginning of the file. |
/pattern | Search forward for a pattern (n for next occurrence). |
?pattern | Search backward for a pattern (N for previous occurrence). |
Examples
Viewing a File:
less example.log
Navigating:
- Scroll down using j or the down arrow key.
- Scroll up using k or the up arrow key.
- Jump to the end of the file with G.
Searching:
- Search for the word "error" in the file:
/error
- Search for the word "error" in the file:
Common Options
Here are some common options you can use with less
:
Option | Description |
---|---|
-N |
Display line numbers. |
-i |
Ignore case in searches. |
-S |
Truncate long lines (useful for wide text files). |
-F |
Quit automatically if entire file can be displayed. |
+<line_number> |
Start viewing the file from a specific line number. |
file Command
The file
command in Linux is used to determine the type of a file. This command helps users identify
files without relying solely on file extensions. The file
command examines the content of a file and
outputs a human-readable description of the file type.
Common Options for the file Command
The file
command comes with various options to refine its behavior. Below is a table of some of the most
common options and their descriptions:
Option | Description |
---|---|
-b |
Brief mode: do not prepend filenames to output lines |
-i |
Output MIME type strings rather than the traditional human-readable ones |
-f <name> |
Read the filenames to be examined from name instead of from the command line |
-z |
Try to look inside compressed files |
-L |
Follow symbolic links |
-s |
Read block or character special files |
-r |
Raw mode: do not translate unprintable characters to \ooo notation |
Examples
Here are some examples of how to use the file
command with different options, along with the expected
output:
Determining the File Type
This command checks the type of the file example.txt
.
file example.txt
Output
example.txt: ASCII text
Using the -b
Option (Brief Mode)
This command outputs only the file type without the filename.
file -b example.txt
Output
ASCII text
Using the -i
Option (MIME Type)
This command outputs the MIME type of the file example.txt
.
file -i example.txt
Output
example.txt: text/plain; charset=us-ascii
Checking Multiple Files
This command checks the types of multiple files.
file file1.txt file2.jpg file3.zip
Output
file1.txt: ASCII text
file2.jpg: JPEG image data, JFIF standard 1.01
file3.zip: Zip archive data, at least v2.0 to extract
Reading File Names from a File
Each line in filenames.txt
should contain the name of a file that actually exists in the directory where you run the command. For example:
file -f filenames.txt
Below is the contents of filenames.txt
document.pdf
image.png
script.sh
binaryfile
textfile.txt
directory/
Output
document.pdf: PDF document, version 1.4
image.png: PNG image data, 800 x 600, 8-bit/color RGB, non-interlaced
script.sh: Bourne-Again shell script, ASCII text executable
binaryfile: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux)
textfile.txt: ASCII text
directory/: directory
Explanation
file -f filenames.txt
reads each filename from the filefilenames.txt
and runs thefile
command on it.- The output describes the type of each file, just as if you had run
file filename
on each one individually. - If a filename in
filenames.txt
does not exist, an error message likefilename: cannot open 'filename' (No such file or directory)
will appear.
Looking Inside Compressed Files
This command attempts to look inside the compressed file compressed.tar.gz
and identify its contents.
file -z compressed.tar.gz
Output
compressed.tar.gz: gzip compressed data, was "compressed.tar", last modified: ...
Following Symbolic Links
This command follows the symbolic link symlink
and checks the type of the
file it points to. The output depends on the file type of the target. NOTE: We will be looking at symbolic links in Chapter 2
file -L symlink
Output
symlink: ASCII text
Conclusion
The file
command is a powerful tool for identifying the types of files in Linux. By understanding and
utilizing its various options, you can efficiently determine file types and gain insights into the nature of the
files you are working with. Practice using these options to become comfortable with the file
command
and enhance your file management skills in Linux.
Chapter 2
mkdir Command
The mkdir
command in Linux is used to create directories. It is a straightforward command but comes with various options that allow for more advanced directory creation scenarios. Understanding how to use mkdir
effectively can help you organize your file system efficiently.
What the mkdir Command Does
The basic usage of the mkdir
command creates a single directory with the specified name. You can also create multiple directories at once or nested directories in one command.
Common Options for the mkdir Command
Here is a table of some of the most common options for the mkdir
command and their descriptions:
Option | Description |
---|---|
-p |
Create parent directories as needed |
-v |
Print a message for each created directory |
-m |
Set file mode (permissions) for the new directories |
--help |
Display help information about the mkdir command |
--version |
Output version information |
Examples
Creating a single directory:
This command creates a single directory named mydirectory
.
mkdir mydirectory
Creating multiple directories:
This command creates three directories named dir1
, dir2
, and dir3
.
mkdir dir1 dir2 dir3
Creating nested directories:
This command creates a nested directory structure. If the parent directories do not exist, the -p
option ensures they are created.
mkdir -p parent/child/grandchild
Verbose output:
The -v
option provides verbose output, confirming the creation of each directory.
mkdir -v mydirectory
Setting permissions while creating a directory:
This command creates a directory named mysecureddir
with permissions set to 755
(rwxr-xr-x).
mkdir -m 755 mysecureddir
Using the --help
option:
The mkdir --help command displays a help message detailing the usage, available options, and descriptions for the mkdir command. It provides a quick reference for users on how to create directories with different options.
mkdir --help
Output:
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.
Mandatory arguments to long options are mandatory for short options too.
-m, --mode=MODE set file mode (as in chmod), not a=rwx - umask
-p, --parents no error if existing, make parent directories as needed
-v, --verbose print a message for each created directory
--help display this help and exit
--version output version information and exit
Conclusion
The mkdir
command is essential for creating directories in Linux. With its various options, you can create single or multiple directories, set specific permissions, and handle nested directories with ease. By practicing these commands and options, you will become proficient in managing directory structures in your Linux environment.
cp, mv and rm Commands
The cp
(copy), mv
(move), and rm
(remove) commands are essential tools in Linux for file and directory management. These commands allow users to copy, move, and delete files and directories. Understanding their options and usage can greatly enhance your efficiency when working with the Linux command line.
The cp Command
The cp
command is used to copy files and directories. It can copy a file to another file, multiple files to a directory, or entire directories to another location.
cp [options] source destination
Commonly Used cp Options:
Option | Description |
---|---|
-a |
Archive mode; preserves attributes and copies recursively |
-i |
Prompt before overwriting files |
-r |
Recursively copy directories |
-u |
Copy only when the source file is newer than the destination file or when the destination file is missing |
-v |
Verbose mode; show files as they are copied |
-p |
Preserve file attributes (e.g., timestamps, ownership) |
--backup |
Make a backup of each existing destination file |
Examples:
To copy a file to another file:
This copies the contents of file1.txt
to file2.txt
. If file2.txt
does not exist, it is created.
cp file1.txt file2.txt
To copy a file to a directory:
This copies file1.txt
to the /home/user/documents/
directory.
cp file1.txt /home/user/documents/
To copy multiple files to a directory:
This copies file1.txt
and file2.txt
to the /home/user/documents/
directory.
cp file1.txt file2.txt /home/user/documents/
To copy a directory and its contents recursively:
This copies the documents
directory and all its contents to the backup
directory.
cp -r /home/user/documents /home/user/backup/
To copy files and preserve their attributes:
This copies file1.txt
to the documents
directory while preserving its attributes.
cp -p file1.txt /home/user/documents/
To copy files with verbose output:
This shows the files being copied in the terminal.
cp -v file1.txt /home/user/documents/
The mv Command
The mv
command is used to move files and directories. It can also be used to rename files and directories. When a file or directory is moved to a new location, the original is deleted.
Basic usage of mv
:
mv [options] source destination
Commonly Used mv
Options:
Option | Description |
---|---|
-i |
Prompt before overwriting files |
-u |
Move only when the source file is newer than the destination file or when the destination file is missing |
-v |
Verbose mode; show files as they are moved |
-f |
Force move by overwriting destination files without prompt |
--backup |
Make a backup of each existing destination file |
Examples:
To move a file to another location:
This moves file1.txt
to the documents
directory.
mv file1.txt /home/user/documents/
To rename a file:
This renames file1.txt
to file2.txt
.
mv file1.txt file2.txt
To move a directory to another location:
This moves the documents
directory to the backup
directory.
mv /home/user/documents /home/user/backup/
To move files with verbose output:
This shows the files being moved in the terminal.
mv -v file1.txt /home/user/documents/
To move files and prompt before overwriting:
This prompts before overwriting file1.txt
in the documents
directory.
mv -i file1.txt /home/user/documents/
To force move files without prompting:
This moves file1.txt
to the documents
directory without prompting, even if it overwrites an existing file.
mv -f file1.txt /home/user/documents/
The rm Command
The rm
command is used to remove files and directories. It is a powerful command that deletes files and directories permanently, so it must be used with caution.
Basic usage of rm
:
rm [options] file
Commonly Used rm Options:
Option | Description |
---|---|
-i |
Prompt before every removal |
-f |
Force removal of files without prompting |
-r |
Recursively remove directories and their contents |
-v |
Verbose mode; show files as they are removed |
--preserve-root |
Do not remove the root directory |
Examples:
To remove a file:
This removes file1.txt
.
rm file1.txt
To remove multiple files:
This removes file1.txt
and file2.txt
.
rm file1.txt file2.txt
To remove a directory and its contents recursively:
This removes the documents
directory and all its contents.
rm -r /home/user/documents/
To remove files with verbose output:
This shows the files being removed in the terminal.
rm -v file1.txt
To force remove files without prompting:
This removes file1.txt
without prompting, even if it is write-protected.
rm -f file1.txt
To prompt before every removal:
This prompts for confirmation before removing file1.txt
.
rm -i file1.txt
Summary
The cp
, mv
, and rm
commands are powerful tools for managing files and directories in Linux. The cp
command allows for copying files and directories with various options to preserve attributes, prompt before overwriting, and provide verbose output. The mv
command enables moving and renaming files and directories, with options to prompt before overwriting, force move, and provide verbose output. The rm
command allows for removing files and directories, with options to force removal, prompt before deletion, and provide verbose output. By mastering these commands and their options, you can efficiently manage your files and directories in the Linux environment.
Creating Symbolic and Hard Links
Understanding the ln Command and Paths in Linux
The ln
command in Linux is used to create links between files. Links are pointers that allow multiple filenames to refer to the same file content. There are two types of links: hard links and symbolic (or soft) links. Understanding the difference between these types and how to use the ln
command can greatly enhance your file management capabilities in Linux. Additionally, knowing how to use relative and absolute paths is crucial when creating symbolic links.
Hard Links
A hard link is a direct reference to the physical data on the disk. When you create a hard link, it points to the same inode (index node) as the original file. This means that both the original file and the hard link are indistinguishable from each other. Any changes made to one will reflect in the other because they both point to the same data blocks. However, deleting one will not affect the other; the data remains accessible as long as there is at least one link pointing to it.
To create a hard link:
ln file1.txt file1_hardlink.txt
This command creates a hard link named file1_hardlink.txt
pointing to file1.txt
. Both filenames now refer to the same data.
Symbolic (soft) Links
A symbolic link, or soft link, is a reference that points to another file by its pathname. Unlike hard links, symbolic links are independent of the physical data. They act as shortcuts or aliases to the original file. If the original file is moved or deleted, the symbolic link becomes a broken link and no longer functions. Symbolic links can span different filesystems and can link to directories, whereas hard links cannot.
To create a symbolic link:
ln -s file1.txt file1_symlink.txt
This command creates a symbolic link named file1_symlink.txt
pointing to file1.txt
. If file1.txt
is deleted or moved, file1_symlink.txt
will become a broken link.
Examples and Differences
Creating Hard and Symbolic Links:
ln file1.txt file1_hardlink.txt
ln -s file1.txt file1_symlink.txt
These commands create a hard link and a symbolic link to file1.txt
.
Modifying Content:
If you modify the contents of file1.txt
, both file1_hardlink.txt
and file1_symlink.txt
will reflect those changes because they reference the same data (for the hard link) or the same file (for the symbolic link).
Deleting Files:
Deleting file1.txt
:
rm file1.txt
The hard link file1_hardlink.txt
still retains access to the data, whereas the symbolic link file1_symlink.txt
becomes a broken link.
File System Boundaries: Hard links cannot be created across different filesystems. Attempting to do so results in an error. Symbolic links, however, can point to files on different filesystems without any issues.
Linking to Directories: Hard links cannot be used to link directories due to the potential for filesystem inconsistencies. Symbolic links can link to directories without any problems.
ln -s /home/user/documents mydocuments_symlink
This command creates a symbolic link named mydocuments_symlink
pointing to the /home/user/documents
directory.
Relative Path Requirements for symbolic Links
Symbolic links require the path to be relative to their location. For example, if you have directory1
and directory2
in a directories
folder and directory1
has file1.txt
, to create a hard link in directory2
that points to file1.txt
in directory1
, you would use:
ln directory1/file1.txt directory2/hardln
For a symbolic link, the relative path matters:
ln -s ../directory1/file1.txt directory2/symbolicln
The ../
is necessary for the symbolic link because it needs the relative path based upon the locate of where the symbolic link is located. Since the symbolic link is in directory2 the path to the source file (file 1) must go up one level (out of directory2) and then into directory 1.
Understanding Relative and Absolute Paths
When creating links using the ln
command, it's important to understand the concepts of relative and absolute paths. These concepts are crucial for correctly creating symbolic (symbolic) links, as the path you provide determines the link's functionality and reliability.
Absolute Paths:
An absolute path specifies the complete directory location from the root directory (/
). It provides the full path to a file or directory, regardless of the current working directory. Absolute paths are useful when you want to ensure that a link always points to the correct location, regardless of where the link is accessed from.
For example, if you want to create a symbolic link to a file located at /home/user/documents/file1.txt
from any directory, you would use an absolute path:
ln -s /home/user/documents/file1.txt /home/user/links/file1_symlink.txt
This command creates a symbolic link named file1_symlink.txt
in the /home/user/links
directory, pointing to /home/user/documents/file1.txt
.
Relative Paths:
A relative path specifies the location of a file or directory in relation to the current working directory. It does not start with a slash (/
) and is interpreted based on the current directory. Relative paths are useful when the structure of the directories is known and fixed, allowing for more flexible and portable links.
For example, consider the following directory structure:
/home/user/
├── documents/
│ └── file1.txt
└── links/
If you are in the /home/user/links
directory and want to create a symbolic link to file1.txt
located in documents
, you would use a relative path:
ln -s ../documents/file1.txt file1_symlink.txt
This command creates a symbolic link named file1_symlink.txt
in the current directory (/home/user/links
), pointing to ../documents/file1.txt
.
Summary
The ln
command is a powerful tool for creating links between files in Linux. Hard links directly reference the physical data on the disk and can only be used within the same filesystem. They provide a robust way to access the same data through different filenames. symbolic links act as shortcuts to the original file or directory and can span different filesystems. They are more flexible but can become broken if the original file is deleted or moved. By mastering the use of hard and symbolic links, and understanding the differences between relative and absolute paths, you can efficiently manage and organize your files and directories in the Linux environment.
Chapter 3
Type Command
The type
command in Linux is used to explain how a given command name will be interpreted when executed in the command line. It helps determine whether a command is a built-in shell command, an alias, a function, or an external executable program. Understanding this distinction is essential for effective command-line usage and troubleshooting.
Built-in Shell Command
A built-in shell command is a command that is executed directly by the shell itself, without calling any external program. These commands are integral to the shell and are typically used for managing the shell environment. For example, cd
, which changes the current directory, is a built-in command.
Example:
type cd
Output:
cd is a shell builtin
Alias
An alias is a shortcut or a substitute for another command or a series of commands. It is defined by the user to simplify command execution. For example, the ls
command might be aliased to ls --color=auto
to always display directory listings with color.
Example:
type ls
Output:
ls is aliased to 'ls --color=auto'
Function
A function in the shell is a user-defined set of commands grouped together under a single name. Functions can include any number of commands and can be used to automate repetitive tasks. Functions are defined in the shell and executed directly by it.
Example:
type my_function
Output (assuming my_function
is defined):
my_function is a function
my_function ()
{
echo "This is a custom function"
}
External Executable Program
An external executable program is a standalone binary or script located in the filesystem, which the shell executes by spawning a new process. These programs reside in directories specified in the system's PATH environment variable. For example, grep
is an external program used for pattern matching within text.
Example:
type grep
Output:
grep is /bin/grep
Summary
- Built-in Shell Command: Executed directly by the shell, integral to shell functionality (e.g.,
cd
). - Alias: User-defined shortcut for commands or command sequences (e.g.,
ls
aliased tols --color=auto
). - Function: User-defined set of commands executed directly by the shell (e.g., a custom function).
- External Executable Program: Standalone binary or script executed by the shell (e.g.,
grep
located at/bin/grep
).
Using the type
command allows users to discern how commands will be interpreted and executed, aiding in efficient command-line usage and troubleshooting.
Help and Man commands
In Linux, the help
and man
commands are essential tools for users to understand and utilize the vast array of commands and utilities available in the system. These commands provide detailed information and documentation, aiding both beginners and experienced users in mastering Linux commands.
The help Command
The help
command is primarily used to display information about built-in shell commands. Since built-in commands are executed directly by the shell and not as separate programs, they often do not have separate manual pages. The help
command provides a concise reference for these built-ins, explaining their usage and options.
To use the help
command, simply type help
followed by the name of the built-in command. For example:
help cd
This command will display information about the cd
command, including its syntax and available options. The help
command is specific to built-ins and will not work with external commands.
Common Options for the help Command
Option | Description |
---|---|
-d |
Display a brief description of the command. |
-m |
Display usage in a pseudo-manpage format. |
-s |
Display a short usage synopsis for the command. |
--help |
Display help information for the help command. |
The man Command
The man
(manual) command provides comprehensive documentation for a wide range of commands and programs in Linux. Each command or program typically has a manual page that describes its purpose, usage, options, and examples. The man
pages are organized into sections, each covering a different category of commands or functions.
To use the man
command, type man
followed by the name of the command or program. For example:
man ls
This command will open the manual page for the ls
command, which lists directory contents. The manual page includes a description of the command, its syntax, available options, and examples of how to use it.
Common Options for the man Command
Option | Description |
---|---|
-k |
Search the short descriptions and manual page names for the keyword. |
-f |
Display a one-line description of the command (equivalent to whatis ). |
-a |
Display all the manual pages for the command. |
-w |
Print the location of the manual page files instead of displaying them. |
--help |
Display a help message with available options. |
Examples
Using help
for a built-in command:
help echo
Output:
echo: echo [-neE] [arg ...]
Write arguments to the standard output.
Options:
-n do not append a newline
-e enable interpretation of backslash escapes
-E disable interpretation of backslash escapes (default)
Exit Status:
Returns success unless a write error occurs.
Using man
for an external command:
man grep
Output:
GREP(1) User Commands GREP(1)
NAME
grep - print lines that match patterns
SYNOPSIS
grep [OPTION]... PATTERNS [FILE]...
grep [OPTION]... -e PATTERNS ... [FILE]...
grep [OPTION]... -f FILE ... [FILE]...
DESCRIPTION
grep searches for PATTERNS in each FILE. A FILE of “-” stands for standard input.
By default, grep prints the matching lines.
In addition, three variant programs egrep, fgrep and rgrep are available:
egrep is the same as ‘grep -E’.
fgrep is the same as ‘grep -F’.
rgrep is the same as ‘grep -r’.
OPTIONS
-i, --ignore-case
Ignore case distinctions in patterns and input data.
-v, --invert-match
Select non-matching lines.
-r, --recursive
Read all files under each directory, recursively.
-n, --line-number
Prefix each line of output with the line number.
-c, --count
Suppress normal output; print a count of matching lines for each input file.
-l, --files-with-matches
Suppress normal output; print the name of each input file that contains a match.
-w, --word-regexp
Select only those lines containing matches that form whole words.
-h, --no-filename
Suppress the prefixing of file names on output.
--help
Display help and exit.
--version
Output version information and exit.
EXAMPLES
grep 'error' logfile
Print all lines containing "error" in logfile.
grep -i 'hello' file.txt
Print lines containing "hello", case insensitive.
grep -r 'TODO' ~/projects/
Recursively search for "TODO" in all files under ~/projects/.
SEE ALSO
sed(1), awk(1), find(1), xargs(1)
GNU Grep 3.7 April 2023 GREP(1)
Navigating the Man Pages
Within the man
pages, you can navigate using the arrow keys to scroll up and down. Press q
to quit and return to the command prompt.
Organization of man Pages
Man pages are organized into sections based on the type of command or documentation they contain. Here are the common sections:
Section | Description |
---|---|
1 | User commands (executable programs or shell commands). |
2 | System calls (functions provided by the kernel). |
3 | Library calls (functions within program libraries). |
4 | Special files (usually found in /dev). |
5 | File formats and conventions. |
6 | Games and screensavers. |
7 | Miscellaneous (macro packages, conventions, etc.). |
8 | System administration commands (usually only for root). |
Accessing Specific Sections
If a command has entries in multiple sections, you can specify the section number. For example, to view the manual page for the passwd
command related to user account management (section 1), use:
man 1 passwd
Apropos, Info and Whatis commands
In Linux, the apropos
, info
, and whatis
commands are essential tools for finding and understanding command-line utilities and their functions. These commands help users navigate the vast amount of documentation available in Linux systems, making it easier to find relevant information about commands and programs.
The apropos Command
The apropos
command searches the manual page names and descriptions for a keyword or phrase, returning a list of commands and their brief descriptions that match the search criteria. This is particularly useful when you know what a command should do but do not remember the exact command name. The apropos
command is often used to find commands related to a specific topic.
Example Usage:
apropos copy
Output:
bcopy (3) - copy byte sequence
cp (1) - copy files and directories
copy_file_range (2) - copy a range of data from one file to another
dd (1) - convert and copy a file
memccpy (3) - copy memory area
memcpy (3) - copy memory area
memmove (3) - copy memory area
scopy (3) - copy vectors
strcpy (3) - copy a string
strlcpy (3) - copy a string with size limit
strncpy (3) - copy a fixed number of characters from a string
Common Options for the apropos Command
Option | Description |
---|---|
-a |
Combine multiple search keywords with a logical AND. |
-e |
Use exact matching for search keywords. |
-l |
Display output in a long listing format. |
-s |
Search only within the specified manual section(s). |
-w |
Search for whole words only. |
The info Command
The info
command provides access to the GNU info system, which contains detailed documentation for many commands and programs. Unlike the man
pages, which provide a single, often concise entry, info
pages can contain more comprehensive and structured documentation. The info
system uses a tree structure and hyperlinks to navigate from one section to another, making it easier to explore detailed documentation.
The tree structure of info
documentation allows users to start from a top-level menu and navigate through various nodes (sections), similar to browsing a website. Each node can contain links to other nodes, enabling users to jump directly to related topics or subtopics.
Example Usage:
info bash
This command will open the info documentation for the Bash shell, providing detailed information on its features and usage. The top-level menu will look something like this:
File: bash.info, Node: Top, Next: Introduction, Up: (dir)
Bash (GNU Bourne-Again SHell)
*****************************
This manual is for Bash, the GNU command-line interpreter. This edition
describes Bash version 5.1.
* Menu:
* Introduction:: An introduction to the shell.
* Basic Shell Features:: The shell's basic features.
* Shell Builtin Commands:: Commands that are built into the shell.
* Shell Variables:: Variables used by the shell.
* Shell Arithmetic:: Shell arithmetic.
* Job Control:: Job control features.
* Shell Commands:: Commands defined internally by the shell.
* Shell Functions:: Shell functions.
* Shell Scripts:: Shell scripts.
* Shell Grammar:: Shell grammar rules.
* Command Line Editing:: Command line editing features.
* Installing Bash:: How to build and install Bash.
* Reporting Bugs:: How to report bugs in Bash.
* GNU Free Documentation License:: Your rights under this license.
* Index:: Index of concepts and functions.
To navigate through the documentation, you can use the arrow keys to move between nodes or press Enter to follow a hyperlink. For example, selecting "Basic Shell Features" and pressing Enter will take you to a detailed section on basic shell features.
Common Options for the info Command
Option | Description |
---|---|
--all |
Display all available info documentation. |
--apropos |
Search all indexes for the specified string. |
--directory |
Add the specified directory to the list of info directories. |
--output |
Specify a file to which to write the output. |
--help |
Display a help message with available options. |
Navigating info Pages
Key | Function |
---|---|
h |
Open the help menu |
? |
Show help summary |
q |
Quit the info viewer |
Space |
Scroll forward one page |
Backspace |
Scroll backward one page |
n |
Move to the next node |
p |
Move to the previous node |
u |
Move up one level in the hierarchy |
l |
Move back to the last visited node |
t |
Move to the top (root) of the documentation |
m |
Open a menu (then type the menu item name) |
Enter |
Follow a hyperlink (when the cursor is on it) |
Tab |
Jump to the next hyperlink |
Shift + Tab |
Jump to the previous hyperlink |
[ |
Move to the last node visited |
] |
Move to the next node in the sequence |
The whatis Command
The whatis
command displays a one-line description of a specified command. It is used to quickly get an overview of what a command does, without delving into the full documentation provided by the man
or info
commands. The whatis
command searches the manual page database for the given command name and displays the summary line from the relevant manual page.
Example Usage:
whatis ls
Output:
ls (1) - list directory contents
Common Options for the whatis Command
Option | Description |
---|---|
-l |
Display output in a long listing format. |
-w |
Search for whole words only. |
-r |
Use a regular expression for the search pattern. |
-s |
Search only within the specified manual section(s). |
--help |
Display a help message with available options. |
The cat Command
Thecat
(short for "concatenate") command is one of the most frequently used commands in Linux, providing versatile functionalities such as reading and concatenating files, creating new files, and appending data to existing ones. Mastering the cat
command is essential for efficient file management in a Linux environment.
Syntax
cat [OPTION]... [FILE]...
Common Options
Option | Description |
---|---|
-A |
Show all, equivalent to -vET |
-b |
Number non-blank output lines |
-e |
Equivalent to -vE |
-E |
Display $ at the end of each line |
-n |
Number all output lines |
-s |
Suppress repeated empty output lines |
-T |
Display TAB characters as ^I |
-v |
Use ^ and M- notation, except for LFD and TAB |
Examples
To display the contents of a file, use:
cat filename.txt
This command outputs the contents of filename.txt
to the terminal.
If you want to concatenate multiple files, you can use:
cat file1.txt file2.txt
This merges the contents of file1.txt
and file2.txt
and displays the combined content.
Creating a new file can be done with:
cat > newfile.txt
This is a new file created using the cat command.
Press Enter then Ctrl+D to save and exit.
Output:
cat newfile.txt
This is a new file created using the cat command.
This command creates newfile.txt
with the provided content.
To append data to an existing file, use:
cat >> existingfile.txt
Appending this text to the existing file.
Press Enter then Ctrl+D to save and exit.
Output:
cat existingfile.txt
Appending this text to the existing file.
This appends the provided content to existingfile.txt
.
For displaying line numbers, the command is:
cat -n filename.txt
This displays the contents of filename.txt
with line numbers.
If you want to suppress repeated empty lines, use:
cat -s filename.txt
This command displays the contents of filename.txt
but suppresses repeated empty lines.
To display $
at the end of each line, use:
cat -E filename.txt
This command displays the contents of filename.txt
and adds a $
at the end of each line.
To show all characters, including non-printing characters, use:
cat -A filename.txt
Suppose file.txt
contains:
John Doe
Jane Smith
Mike Johnson
Output:
John Doe$
Jane Smith$
$
Mike Johnson$
This command displays the contents of filename.txt
with non-printing characters made visible.
You can combine multiple options as well:
cat -nE filename.txt
This command displays the contents of filename.txt
with line numbers and $
at the end of each line.
Summary
The cat
command is a powerful tool in Linux for displaying, creating, and concatenating files. Understanding its options and applications can greatly enhance your efficiency when working with text files in the terminal.
The sort and uniq Commands
The sort
and uniq
commands in Linux are essential for organizing and processing text files. They are often used together to sort and remove duplicates from lists of data. Understanding these commands and their options can significantly improve your efficiency in managing text data.
The sort
Command
The sort
command sorts lines of text files. It arranges the lines in a specified order, either alphabetically or numerically. The basic syntax for the sort
command is:
sort [OPTION]... [FILE]...
Common Options for sort
Option | Description |
---|---|
-b |
Ignore leading blanks |
-d |
Consider only blanks and alphanumeric characters |
-f |
Fold lowercase to uppercase characters |
-g |
General numeric sort |
-i |
Consider only printable characters |
-M |
Sort by month name |
-n |
Numeric sort |
-r |
Reverse the result of comparisons |
-k |
Sort via a key |
To sort the contents of a file alphabetically, use:
sort filename.txt
This command sorts the lines in filename.txt
alphabetically. For a numeric sort, where lines are sorted based on numerical values, use:
sort -n filename.txt
If you want to sort the lines in reverse order, the -r
option can be used:
sort -r filename.txt
Combining options allows for more specific sorting, such as ignoring leading blanks and sorting numerically:
sort -bn filename.txt
The uniq
Command
The uniq
command filters out repeated lines in a file, displaying only unique lines. It is often used after the sort
command because uniq
works only on adjacent duplicate lines. The basic syntax for the uniq
command is:
uniq [OPTION]... [FILE]...
Common Options for uniq
Option | Description |
---|---|
-c |
Prefix lines by the number of occurrences |
-d |
Only print duplicate lines |
-u |
Only print unique lines |
-i |
Ignore differences in case when comparing |
-f |
Skip fields before comparing |
-s |
Skip characters before comparing |
To remove duplicate lines from a file, first sort the file and then use uniq
:
sort filename.txt | uniq
This command sorts the lines in filename.txt
and then filters out duplicate lines. To count the occurrences of each line, use the -c
option:
sort filename.txt | uniq -c
This will prefix each line with the number of times it appears in the file. If you want to display only the duplicate lines, use the -d
option:
sort filename.txt | uniq -d
For displaying only unique lines, use the -u
option:
sort filename.txt | uniq -u
Examples
Sorting a file alphabetically:
sort fruits.txt
Sorting a file numerically:
sort -n numbers.txt
Sorting a file and ignoring leading blanks:
sort -b names.txt
Sorting a file in reverse order:
sort -r items.txt
Removing duplicate lines from a sorted file:
sort animals.txt | uniq
Counting the occurrences of each line:
sort animals.txt | uniq -c
Displaying only duplicate lines:
sort colors.txt | uniq -d
Displaying only unique lines:
sort colors.txt | uniq -u
Summary
The sort
and uniq
commands are powerful tools for organizing and processing text data in Linux. sort
arranges lines in a specified order, while uniq
filters out repeated lines. Mastering these commands and their options will enable you to efficiently manage and manipulate text files in your Linux environment.
The head, tail and wc Commands
The head
, tail
, and wc
commands in Linux are fundamental tools for handling text files and streams. Each command serves a specific purpose, allowing users to view and analyze file content efficiently.
The head Command
The head
command is used to display the beginning of a file. By default, it shows the first ten lines, but you can specify the number of lines to display. The basic syntax is:
head [OPTION]... [FILE]...
Common Options for head
Option | Description |
---|---|
-n |
Print the first NUM lines |
-c |
Print the first NUM bytes |
-q |
Never print headers |
-v |
Always print headers |
For example, to display the first 5 lines of a file, use:
head -n 5 filename.txt
To display the first 20 bytes of a file, use:
head -c 20 filename.txt
The tail Command
The tail
command is used to display the end of a file. Like head
, it shows the last ten lines by default but can be customized to show a specific number of lines or bytes. The basic syntax is:
tail [OPTION]... [FILE]...
Common Options for tail
Option | Description |
---|---|
-n |
Print the last NUM lines |
-c |
Print the last NUM bytes |
-f |
Output appended data as the file grows (useful for logs) |
-q |
Never print headers |
-v |
Always print headers |
For example, to display the last 10 lines of a file, use:
tail -n 10 filename.txt
To follow a file and display new lines as they are added (useful for monitoring log files), use:
tail -f filename.txt
The wc Command
The wc
(word count) command is used to count the number of lines, words, and bytes in a file. It provides a quick way to get an overview of a file's size. The basic syntax is:
wc [OPTION]... [FILE]...
Common Options for wc
Option | Description |
---|---|
-l |
Print the newline counts |
-w |
Print the word counts |
-c |
Print the byte counts |
-m |
Print the character counts |
-L |
Print the length of the longest line |
For example, to count the number of lines in a file, use:
wc -l filename.txt
To count the number of words in a file, use:
wc -w filename.txt
To count the number of bytes in a file, use:
wc -c filename.txt
Examples
Displaying the first 10 lines of a file:
head filename.txt
Displaying the last 15 lines of a file:
tail -n 15 filename.txt
Counting the number of lines, words, and bytes in a file:
wc filename.txt
Counting the number of characters in a file:
wc -m filename.txt
Summary
The head
, tail
, and wc
commands are essential for viewing and analyzing file contents in Linux. The head
command allows you to view the beginning of a file, while the tail
command lets you see the end. The wc
command provides counts of lines, words, characters, and bytes, offering a quick way to understand the size and structure of a file. Mastering these commands will enhance your ability to manage and analyze text files efficiently in a Linux environment.
Redirection
Redirection in Linux is a fundamental concept that allows users to control the input and output of commands. By default, commands take input from the keyboard and send output to the terminal. Redirection modifies this behavior to send output to files, read input from files, and handle errors effectively.
Standard Output and Input Redirection
The most basic form of redirection involves redirecting the standard output (stdout) of a command to a file. This is done using the >
operator. For example:
ls > filelist.txt
This command lists the directory contents and writes the output to filelist.txt
, overwriting the file if it exists. To append the output to an existing file instead of overwriting it, the >>
operator is used:
echo "Additional line" >> filelist.txt
This command adds "Additional line" to filelist.txt
, preserving its existing contents.
Standard Error Redirection
In addition to standard output, Linux commands also produce standard error (stderr) messages. These messages can be redirected to a file using the 2>
operator. For example:
ls non_existent_file 2> errorlog.txt
This command attempts to list a non-existent file, redirecting the resulting error message to errorlog.txt
. If you want to append error messages to an existing file instead of overwriting it, use the 2>>
operator:
ls another_non_existent_file 2>> errorlog.txt
Combining Standard Output and Error Redirection
Often, it's useful to redirect both stdout and stderr to the same file. This can be done using the &>
operator:
ls existing_file non_existent_file &> combinedlog.txt
This command lists the contents of existing_file
and attempts to list a non-existent file, redirecting both the output and error messages to combinedlog.txt
. To append both stdout and stderr to an existing file, use the &>>
operator:
ls another_existing_file another_non_existent_file &>> combinedlog.txt
Redirecting Input
Redirection can also be used to take input from a file instead of the keyboard. This is done using the <
operator. For example:
sort < unsorted_list.txt
This command sorts the contents of unsorted_list.txt
and displays the sorted list on the terminal.
The grep Command
The grep
command in Linux is a powerful tool used for searching and filtering text. It searches through files or input for lines that match a given pattern and prints the matching lines. The name "grep" stands for "global regular expression print," reflecting its ability to search globally for lines matching a pattern and print them. This command is especially useful for sifting through large files or streams of data to find specific information quickly and efficiently. The basic syntax for the grep
command is:
grep [OPTION]... PATTERN [FILE]...
Common Options for grep
Option | Description |
---|---|
-i |
Ignore case distinctions |
-v |
Invert the match, displaying lines that do not match |
-r |
Recursively search directories |
-l |
Print the names of files with matching lines |
-n |
Prefix each line of output with the line number |
-c |
Print only a count of matching lines per file |
-w |
Match whole words only |
-e |
Specify multiple patterns to search for |
-A |
Print lines after the matching line |
-B |
Print lines before the matching line |
-C |
Print lines around the matching line |
Examples
To search for a specific pattern in a file, you can use:
grep "pattern" filename.txt
This command searches for "pattern" in filename.txt
and prints all lines containing that pattern. If you want to ignore case distinctions, use the -i
option:
grep -i "pattern" filename.txt
This command searches for "pattern" in a case-insensitive manner. To invert the match, showing lines that do not contain the pattern, use the -v
option:
grep -v "pattern" filename.txt
To search recursively through directories, you can use the -r
option:
grep -r "pattern" /path/to/directory
This command searches for "pattern" in all files within /path/to/directory
and its subdirectories. If you want to print the names of files containing the matching lines, use the -l
option:
grep -l "pattern" *.txt
For including line numbers with the matched lines, use the -n
option:
grep -n "pattern" filename.txt
To count the number of matching lines per file, use the -c
option:
grep -c "pattern" filename.txt
To match whole words only, preventing partial matches, use the -w
option:
grep -w "pattern" filename.txt
If you need to specify multiple patterns, you can use the -e
option:
grep -e "pattern1" -e "pattern2" filename.txt
To print lines after the matching line, use the -A
option followed by the number of lines to display:
grep -A 3 "pattern" filename.txt
To print lines before the matching line, use the -B
option:
grep -B 3 "pattern" filename.txt
For printing lines around the matching line, use the -C
option:
grep -C 3 "pattern" filename.txt
Summary
The grep
command is a versatile and powerful tool for searching and filtering text in Linux. By understanding and utilizing its various options, you can efficiently locate and manage data within files and directories. Whether you need to search for a specific pattern, count occurrences, or view surrounding lines, grep
provides the functionality needed to handle these tasks effectively.
Linux Pipelines
Pipelines in Linux are a powerful feature that allows users to connect multiple commands together, passing the output of one command as the input to the next. This enables complex operations to be performed in a streamlined and efficient manner, utilizing the strengths of different commands to process data in a sequential flow. The pipe operator (|
) is used to create a pipeline, facilitating this flow of data between commands.
Using pipelines, you can combine simple commands to perform complex tasks without the need for intermediate files. For example, to find all files in a directory that contain a specific string, you could use a combination of grep
and ls
. By using a pipeline, the output of ls
(a list of files) is passed directly to grep
to search for the string:
ls | grep "pattern"
This command lists all files in the current directory and filters those that contain "pattern" in their names. Another common use of pipelines is to filter and sort data. For instance, you can use cat
to display a file's contents, grep
to filter lines containing a specific string, and sort
to sort the filtered lines:
cat filename.txt | grep "pattern" | sort
This command displays the contents of filename.txt
, filters lines containing "pattern", and sorts the resulting lines. Pipelines can also be used to process numerical data. For example, you can use ps
to list running processes, grep
to filter for specific processes, and wc
to count the number of matching processes:
ps aux | grep "process_name" | wc -l
This command lists all running processes, filters for those containing "process_name", and counts the number of matching processes. Additionally, pipelines can be used for text manipulation and analysis. For instance, you can use cat
to display a file's contents, tr
to translate or delete characters, and cut
to extract specific fields:
cat data.txt | tr '[:lower:]' '[:upper:]' | cut -d',' -f1
This command converts the contents of data.txt
to uppercase and extracts the first field (assuming the fields are comma-separated). Pipelines are also useful for monitoring system performance. You can use top
to display system information, head
to display the top lines, and tee
to save the output to a file while also displaying it:
top -b -n 1 | head -n 10 | tee top_output.txt
This command runs top
in batch mode, displays the first 10 lines, and saves the output to top_output.txt
.
Summary
Pipelines in Linux provide a flexible and efficient way to connect commands and process data sequentially. By passing the output of one command as the input to another, pipelines enable the creation of powerful command chains that can perform complex tasks with minimal effort. Understanding and utilizing pipelines can greatly enhance your productivity and capability in the Linux environment.
The tee Command
The tee
command in Linux is a versatile tool used for reading from standard input and writing to both standard output and one or more files simultaneously. This command is particularly useful when you need to view the output of a command on the screen while also saving it to a file. The name "tee" is derived from the T-splitter used in plumbing, symbolizing its ability to split the input data stream into two directions. The basic syntax for the tee
command is:
tee [OPTION]... [FILE]...
Common Options for tee
Option | Description |
---|---|
-a |
Append the output to the file instead of overwriting it |
-i |
Ignore interrupt signals |
-p |
Diagnose errors writing to non-pipes |
For example, to write the output of a command to a file and display it on the terminal simultaneously, you can use:
ls -l | tee output.txt
This command lists the directory contents in long format, displays it on the terminal, and writes it to output.txt
. If you want to append the output to an existing file instead of overwriting it, use the -a
option:
ls -l | tee -a output.txt
This command appends the directory listing to output.txt
without overwriting the existing content. The -i
option is used to ignore interrupt signals, ensuring that the tee
command continues to run even if you accidentally press Ctrl+C
:
ls -l | tee -i output.txt
The tee
command can also be used to write output to multiple files. For instance:
ls -l | tee output1.txt output2.txt
This command writes the output of ls -l
to both output1.txt
and output2.txt
, while still displaying it on the terminal.
Examples
Writing output to a file and terminal:
echo "Hello, World!" | tee hello.txt
Appending output to an existing file:
echo "Additional line" | tee -a hello.txt
Ignoring interrupt signals:
ls -l | tee -i filelist.txt
Writing output to multiple files:
echo "Multi-file output" | tee file1.txt file2.txt
Listing all files in a directory, saving to getall.txt
, and filtering lines containing "hello" to hello.txt
:
ls -l | tee getall.txt | grep "hello" > hello.txt
Summary
The tee
command is a powerful and flexible utility for duplicating the output of a command, allowing it to be both displayed on the terminal and saved to one or more files. This dual functionality makes it an invaluable tool for tasks such as logging command output or capturing real-time data for later analysis. Understanding and utilizing the tee
command's options can greatly enhance your ability to manage and redirect command output effectively in a Linux environment.
Chapter 4
Linux Expansion
In Linux, expansion is the process where the shell takes certain special characters or patterns in commands and translates them into a more concrete form before executing the command. This allows you to use shortcuts or patterns to save time and effort when interacting with the system. There are several types of expansions in Linux that you’ll use often, including pathname expansion, tilde expansion, arithmetic expansion, brace expansion, parameter expansion, and command substitution. Let's explore these one by one.
Pathname Expansion (Wildcard Expansion)
Pathname expansion, or wildcard expansion, is when the shell interprets special characters like *
and ?
to match files and directories.
*
matches any number of characters.?
matches exactly one character.[abc]
matches any character from the seta
,b
, orc
.
Examples:
This will list all files and directories in the current working directory.
echo *
This will list all files in the current directory with a .txt
extension.
echo *.txt
This will match files like file1.txt
, fileA.txt
, but not file10.txt
(because ?
only matches one character).
ls file?.txt
This will match all .jpg
files whose names start with any letter between a
and c
.
ls [a-c]*.jpg
Tilde Expansion
Tilde expansion uses the ~
symbol to represent the current user’s home directory, or another user’s home directory.
Examples:
Changes to your home directory.
cd ~
Lists the contents of your Documents
folder within your home directory.
ls ~/Documents
Expands to the home directory of another user named username
. This will just print the expanded path to the terminal
echo ~username
Copies a file from your Downloads
directory to your Documents
directory.
cp ~/Downloads/file.txt ~/Documents/
Arithmetic Expansion
Arithmetic expansion lets you perform mathematical operations directly in your commands. It uses the format $((expression))
, where expression
is a mathematical formula.
Examples:
Outputs 8
by adding 5 and 3.
echo $((5 + 3))
Outputs 7
by subtracting 2 from 9.
echo $((9 - 2))
Outputs 12
by multiplying 2 and 6.
echo $((2 * 6))
Outputs 5
by dividing 10 by 2.
echo $((10 / 2))
Follows the correct order of operations and outputs 13
(5 * 2 = 10, then 3 + 10 = 13).
echo $((3 + 5 * 2))
The parentheses ensure that 5 + 3 is evaluated first (resulting in 8), then multiplied by 2 to get 16.
echo $(( (5 + 3) * 2 ))
Brace Expansion
Brace expansion generates arbitrary strings by expanding text enclosed in braces {}
. This is very useful for creating sequences of similar file or directory names.
Examples:
Expands to fileA.txt
, fileB.txt
, fileC.txt
.
echo file{A,B,C}.txt
Creates directories folder_1
, folder_2
, ..., folder_5
.
mkdir folder_{1..5}
Creates files image_001.png
, image_002.png
, ..., image_005.png
.
touch image_{001..005}.png
Expands to project_alpha_test
, project_beta_test
, and project_gamma_test
.
echo project_{alpha,beta,gamma}_test
Parameter Expansion
Parameter expansion retrieves the value of variables and allows for operations on those variables. Variables in Linux can store data like strings or numbers and are often used in scripts.
Examples:
Displays the value of the HOME
variable, which is your home directory path.
echo $HOME
Displays the value of the USER
variable, which is your current username.
echo $USER
Displays the list of directories where the system searches for executable files.
echo ${PATH}
You can also modify variables using parameter expansion. For instance, setting a default value if a variable isn’t set:
echo ${UNSET_VARIABLE:-default_value}
This outputs default_value
if UNSET_VARIABLE
is not defined.
Command Substitution
Command substitution allows the output of one command to be used as an argument in another command. The syntax is either $(command)
or `command`
.
Examples:
This will print the current date by substituting the output of the date
command.
echo "The current date is: $(date)"
This prints a list of files in the current directory.
echo "Files in the directory: $(ls)"
This counts and prints the number of files in the current directory by combining ls
and wc -l
(which counts lines).
echo "Number of files: $(ls | wc -l)"
More Examples of Combining Expansions
You can also combine different types of expansions to perform more complex tasks. Here are some useful Examples:
Combining Brace Expansion and Tilde Expansion:
mkdir ~/projects/{project1,project2,project3}
This creates three directories (project1
, project2
, and project3
) inside the projects
folder in your home directory.
Combining Arithmetic Expansion and Command Substitution:
echo "The result of 5 + 10 is $((5 + 10))"
Outputs The result of 5 + 10 is 15
.
Combining Command Substitution with Pathname Expansion:
echo "Today's log file: log_$(date +%Y%m%d).txt"
Creates a dynamic filename for the log based on today’s date, for example, log_20240925.txt
.
Conclusion
Linux expansions allow you to write more powerful and efficient commands by automating common tasks like listing files, performing calculations, creating multiple directories or files, and substituting commands within other commands. As you become familiar with expansions like pathname, tilde, arithmetic, brace, parameter expansion, and command substitution, you will find yourself saving time and effort when working on the command line. This flexibility is one of the reasons why Linux is such a powerful system for both casual users and professionals.
Single and Double Quotes
In Linux, quotes play a crucial role in how the shell interprets and processes text. Single quotes (' '
) and double quotes (" "
) are used to define strings and manage the interpretation of special characters within those strings. Understanding the differences between single and double quotes is essential for effective command-line usage.
Single Quotes
Single quotes (' '
) are used to preserve the literal value of each character within the quotes. This means that any special characters, such as $
, *
, or \
, are treated as regular characters and not as special shell characters.
Example:
[me@linuxbox ~]$ echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'
text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
In this example, everything inside the single quotes is treated literally. The shell does not perform any expansion or interpretation of special characters. Thus, the output is exactly what was input: text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
.
Double Quotes
Double quotes (" "
) preserve the literal value of most characters within the quotes. However, they allow the interpretation of certain special characters, such as $
, \
, !
, and backticks `
.
Example:
[me@linuxbox ~]$ echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER"
text ~/*.txt {a,b} foo 4 me
In this example, the double quotes allow for variable expansion and command substitution. Here's the breakdown of what happens inside the double quotes:
$(echo foo)
is a command substitution and gets replaced byfoo
.$((2+2))
is an arithmetic expansion and gets replaced by4
.$USER
is a variable expansion and gets replaced by the username,me
.
The tilde (~
) and brace {}
expansions are not processed within double quotes.
No Quotes
When no quotes are used, the shell processes all forms of expansion: pathname expansion, brace expansion, command substitution, arithmetic expansion, and variable expansion.
Example:
[me@linuxbox ~]$ echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
text /home/me/ls-output.txt a b foo 4 me
Here’s what happens step-by-step:
~/*.txt
is expanded to/home/me/ls-output.txt
, assuming there is a file namedls-output.txt
in the home directory.{a,b}
is brace expansion and gets replaced bya
andb
.$(echo foo)
is command substitution and gets replaced byfoo
.$((2+2))
is arithmetic expansion and gets replaced by4
.$USER
is variable expansion and gets replaced byme
.
The result is text /home/me/ls-output.txt a b foo 4 me
.
Creating Files and Folders with Spaces
When creating files or folders with spaces in their names, quotes are essential to ensure the shell correctly interprets the spaces as part of the name rather than as separators between different arguments.
Examples:
This command creates a directory named My Folder
.
mkdir "My Folder"
This command creates a file named New Document.txt
.
touch "New Document.txt"
This command renames a file from Old Name.txt
to New Name.txt
.
mv "Old Name.txt" "New Name.txt"
Summary
Single and double quotes in Linux are powerful tools for controlling how the shell interprets text and special characters. Single quotes preserve the literal value of all characters within the quotes, making them ideal for strings that contain special characters that should not be interpreted by the shell. Double quotes allow for variable expansion, command substitution, and arithmetic expansion, providing flexibility when working with dynamic content. Understanding the differences between single and double quotes, as well as how unquoted text is processed, is crucial for writing effective and accurate shell commands.
Keyboard Tricks
Command line users don't enjoy excessive typing, which is why many commands have short names like cp
, ls
, mv
, and rm
. One of the cherished goals of using the command line is to achieve the most with the fewest keystrokes, minimizing the need to use a mouse. This chapter explores bash features that enhance keyboard efficiency.
Command Line Editing
The bash
shell uses a library called Readline to implement command line editing, offering features beyond basic arrow key navigation. These tools, while numerous, can be selectively learned to increase productivity. Note that some key sequences, especially those involving the Alt key, may be intercepted by the GUI but will work correctly in a virtual console.
Cursor Movement Commands:
Key | Action |
---|---|
Ctrl-a |
Move cursor to the beginning of the line. |
Ctrl-e |
Move cursor to the end of the line. |
Ctrl-f |
Move cursor forward one character (same as right arrow key). |
Ctrl-b |
Move cursor backward one character (same as left arrow key). |
Alt-f |
Move cursor forward one word. |
Alt-b |
Move cursor backward one word. |
Ctrl-l |
Clear the screen and move the cursor to the top-left corner. |
Modifying Text Commands:
Key | Action |
---|---|
Ctrl-d |
Delete the character at the cursor location. |
Ctrl-t |
Transpose the character at the cursor with the preceding one. |
Alt-t |
Transpose the word at the cursor with the preceding word. |
Alt-l |
Convert characters from the cursor to the end of the word to lowercase. |
Alt-u |
Convert characters from the cursor to the end of the word to uppercase. |
Cutting and Pasting (Killing and Yanking) Text:
Readline documentation refers to cutting and pasting as killing and yanking. Cut items are stored in a temporary buffer called the kill-ring.
Key | Action |
---|---|
Ctrl-k |
Kill text from the cursor to the end of the line. |
Ctrl-u |
Kill text from the cursor to the beginning of the line. |
Alt-d |
Kill text from the cursor to the end of the current word. |
Alt-Backspace |
Kill text from the cursor to the beginning of the current word (or previous word if at the start of a word). |
Ctrl-y |
Yank text from the kill-ring and insert it at the cursor location. |
The Meta Key
The term meta key, often used in Readline documentation, maps to the Alt key on modern keyboards. Historically, before the widespread use of PCs, terminals connected to larger computers used a key designated as meta. On modern systems, pressing the Esc key can substitute for holding the Alt key.
Completion
The shell provides a completion mechanism using the Tab key. Completion simplifies the process of typing commands by automatically filling in pathnames, variables, usernames, commands, and hostnames.
Examples:
For completion to be successful, the input must be unambiguous. For example let's say you have mutiple folders in the same directory that start with dir (dir1, dir2 and dir3). If you enter the line below and press the tab key once you will hear a chime and on the second press it will give you all the folders (or files) that start with dir
First tab press
[me@linuxbox ~]$ ls dir
Second tab press
[me@linuxbox ~]$ ls dir
dir1/ dir2/ dir3
If you have 100 or more folders or files that start with 0 (000 - 099) and you enter 0 and press tab. You will hear a chime and then the following will be displayed
Display all 100 possibilites? (y or n)
This is the behavior on the cidermill server.
Completion commands:
Key | Action |
---|---|
Alt-? |
Display a list of possible completions. |
Alt-* |
Insert all possible completions. |
Using History
bash
maintains a history of entered commands, stored in the .bash_history
file in the home directory. This feature, combined with command line editing, reduces typing effort.
To view the history list:
[me@linuxbox ~]$ history | less
To search the history list for commands:
[me@linuxbox ~]$ history | grep /usr/bin
Using history expansion:
[me@linuxbox ~]$ !88
History Expansion Commands:
Sequence | Action |
---|---|
!! |
Repeat the last command. |
!number |
Repeat history list item number. |
!string |
Repeat last history list item starting with string. |
!?string |
Repeat last history list item containing string. |
script Command
The script
command in Linux is used to record a terminal session, capturing all the input and output during the session into a file. It is particularly useful for creating logs of interactive shell sessions, debugging, or documenting command-line activities.
Syntax
script [options] [file]
Key Features
Records Terminal Sessions
Captures everything displayed in the terminal, including user input and command output.Default Output File
If no file is specified, the session is saved in a file namedtypescript
.Interactive Use
The command runs interactively and exits when the user typesexit
or pressesCtrl+D
.
Common Options
Option | Description |
---|---|
-a |
Append output to the specified file instead of overwriting it. |
-c <command> |
Run a specific command and log its output. The session ends after completion. |
-f |
Flush output to the file as it is written, useful for real-time monitoring. |
-q |
Run in quiet mode, suppressing the start and end messages. |
--timing=<file> |
Record timing information for playback with the scriptreplay command. |
Examples
Basic Use
script session.log
This starts recording the session into session.log
.
Appending to a File
script -a session.log
Appends the current session to an existing log file.
Running a Command
script -c "ls -l" output.log
Logs the output of ls -l
into output.log
.
Quiet Mode
script -q log.txt
Runs the session without displaying the starting and ending messages.
Using Timing
script --timing=timing.log session.log
Creates a timing file timing.log
to replay the session later.
Replay the Session
The scriptreplay
command can be used to replay a session recorded with timing information:
scriptreplay timing.log session.log
Notes
- The
script
command is part of theutil-linux
package, so it is available on most Linux distributions. - It can capture all terminal activity, making it useful for auditing, troubleshooting, and education.
Summing Up
In this chapter, we've explored various keyboard tricks and features in bash
that can significantly reduce typing effort. These tools are optional but can be very helpful as you become more familiar with the command line.
Chapter 5
Linux Permissions
Lesson: Understanding Linux Permissions
Linux permissions are a fundamental aspect of the operating system's security model, controlling the access rights of users to files and directories. Each file and directory in Linux is associated with an owner (author), a group, and permission settings for three categories of users: the owner, the group, and everyone else.
Owner (Author), Group, and Everyone
Owner (Author): The owner is typically the user who created the file or directory. By default, the owner has full control over the file or directory, meaning they can read, write, and execute it. The owner can also change the permissions for the group and others.
Group: Each file and directory is associated with a group. Users in this group have specific permissions that can be different from those of the owner. This is useful in collaborative environments where a set of users need to share access to files and directories.
Everyone (Others): This category includes all other users who are not the owner and do not belong to the group associated with the file or directory. Permissions for others are generally more restrictive to maintain security.
Types of Permissions
There are three types of permissions in Linux:
- Read (r): Permission to read the contents of the file or directory.
- Write (w): Permission to modify the contents of the file or directory.
- Execute (x): Permission to execute the file, if it is a script or program. For directories, execute permission allows users to enter the directory and access its contents.
Viewing Permissions
You can view the permissions of files and directories using the ls -l
command. The output provides detailed information, including the permission settings.
Example:
$ ls -l
-rwxr-xr-- 1 user group 4096 Jul 10 14:55 file.txt
The output can be broken down as follows:
-rwxr-xr--
indicates the permissions.1
is the number of hard links.user
is the owner.group
is the group.4096
is the file size.Jul 10 14:55
is the last modification date and time.file.txt
is the file name.
The permission string -rwxr-xr--
can be interpreted as:
rwx
(read, write, execute) for the owner.r-x
(read, execute) for the group.r--
(read) for others.
id, chmod and umask
In Linux, managing user identities and permissions is crucial for system security and functionality. Commands like id
, chmod
, and umask
play a significant role in this management. Understanding these commands helps in effectively setting and modifying access controls on files and directories.
The id Command
The id
command is used to display the user ID (UID) and group ID (GID) of the current user or a specified user. It provides detailed information about the user, including their primary group and any supplementary groups they belong to.
Example:
$ id
uid=1000(user) gid=1000(user) groups=1000(user),27(sudo),1001(developers)
In this example, uid=1000(user)
indicates that the user's ID is 1000. The primary group ID is also 1000, and the user belongs to the sudo
and developers
groups as well.
You can also specify a username to get the ID details for that particular user:
$ id alice
uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(projects)
The chmod
Command
The chmod
command is used to change the permissions of files and directories. Permissions determine who can read, write, or execute a file. There are three types of permissions: read (r), write (w), and execute (x). Each permission has an associated numerical value:
- Read (r) = 4
- Write (w) = 2
- Execute (x) = 1
These values are added together to set permissions. For instance, a permission setting of rwx
(read, write, and execute) adds up to 7 (4+2+1).
Permissions are set for three categories of users: the owner, the group, and others. The chmod
command can use either symbolic or numeric modes to change permissions.
Symbolic Mode
In Linux, symbolic mode is used to set file permissions by representing the user (or class of users) and the permissions themselves symbolically, using characters. This is an alternative to the octal (numeric) mode for controlling access to files and directories. Let me break it down step by step:
User Classes
In symbolic mode, permissions are assigned to three classes of users:
- u (user): The file owner.
- g (group): The users in the file's group.
- o (others): All other users.
- a (all): Refers to u, g, and o together.
Permissions
There are three types of permissions that can be granted or denied to each user class:
- r (read): Permission to read the file or list the contents of a directory.
- w (write): Permission to modify the file or change the contents of a directory.
- x (execute): Permission to execute the file or enter the directory.
Operators
You use the following operators to set permissions:
- + (add): Adds the specified permission.
- - (remove): Removes the specified permission.
- = (assign): Sets the specified permission and removes all others.
Examples
Grant execute permission to the owner (user):
chmod u+x filename
This adds execute permission for the file owner.
Remove write permission from group members:
chmod g-w filename
This removes the write permission from the group.
Set read and write permissions for others (overwriting previous permissions):
chmod o=rw filename
This ensures that others can only read and write, removing any other permissions (like execute) if they exist.
Grant read, write, and execute permissions to all users:
chmod a+rwx filename
This gives read, write, and execute permissions to everyone.
Combining Changes
You can make changes to multiple classes at once:
- Grant read permission to group and others:
chmod go+r filename
-
You can combine commands using a comma.
For example, we have a permission of 777 and we want to change it to 655. We would do the following:chmod ug-x,o-rwx filename
Symbolic mode is helpful because it's human-readable and allows setting permissions selectively for different user classes in a clear way.
Numeric Mode
In numeric mode, you use a three-digit octal number to set permissions. Each digit represents the permissions for the owner, group, and others, respectively.Example:
chmod 755 file.txt
This sets the permissions to:
7
(4+2+1) for the owner (rwx).5
(4+0+1) for the group (r-x).5
(4+0+1) for others (r-x).
Another example:
chmod 644 file.txt
This sets the permissions to:
6
(4+2) for the owner (rw-).4
(4+0) for the group (r--).4
(4+0) for others (r--).
The umask Command
The umask
command sets the default permissions for newly created files and directories. The umask
value determines which permission bits will be turned off by default. It is specified as a three-digit octal number.
Example:
umask 022
A umask
value of 022 means that new files will be created with permissions 644 (666 - 022) and new directories with permissions 755 (777 - 022). The value 022 masks off the write permission for the group and others.
To view the current umask
setting, simply run:
umask
To change the umask
value temporarily for the current session, you can use:
umask 027
This sets the default permissions so that new files are created with permissions 640 and directories with permissions 750.
Unusual umask Values
A umask
value of 222 is technically valid but results in very restrictive permissions for new files and directories.
Example:
umask 222
With a umask
of 222:
- New files would have permissions 444 (666 - 222), meaning they are read-only for everyone.
- New directories would have permissions 555 (777 - 222), allowing read and execute permissions but no write permissions for anyone.
Such a setting might be useful in very specific scenarios where files and directories should not be modified by anyone once created.
Examples
- Viewing user ID and group information:
id
Output:
uid=1000(user) gid=1000(user) groups=1000(user),27(sudo),1001(developers)
- Changing file permissions using symbolic mode:
chmod g+w file.txt
This adds write permission for the group.
- Changing file permissions using numeric mode:
chmod 755 script.sh
This sets the permissions to rwxr-xr-x
.
- Setting the umask value:
umask 027
This sets the default permissions so that new files are created with rw-r-----
and directories with rwxr-x---
.
- Setting an unusual umask value:
umask 222
This results in new files with r--r--r--
and directories with r-xr-xr-x
.
Summary
Understanding and effectively using id
, chmod
, and umask
is essential for managing user identities and permissions in Linux. The id
command provides information about user and group IDs, chmod
allows for precise control over file and directory permissions, and umask
sets default permission settings for new files and directories. Mastering these commands ensures better security and proper access control in a Linux environment.
sudo and su Commands
In Linux, su
and sudo
are powerful commands used to perform administrative tasks and execute commands with elevated privileges. Both commands are essential for system administration and security, enabling users to manage the system effectively while maintaining proper access control.
NOTE: You do not have permissions to use the su or sudo commands on the Cidermill server.
The su Command
The su
command stands for "substitute user" or "switch user." It allows a user to switch to another user account in the system, including the superuser (root). When executed without any arguments, su
defaults to switching to the root user. This command opens a new shell session as the specified user, maintaining their environment and permissions.
Basic usage of su
:
su [username]
Switching to the root user:
su
This command prompts for the root user's password and, upon successful authentication, grants the user root privileges. The shell prompt changes to indicate the new user context, typically #
for the root user.
Switching to a different user:
su alice
This command switches to the user alice
, prompting for alice
's password. The user now operates with alice
's permissions and environment.
Starting a login shell with -
:
su - alice
This command switches to alice
and simulates a full login, loading alice
's environment variables and shell configuration files, such as .bashrc
and .profile
.
The sudo Command
The sudo
command stands for "superuser do." It allows a permitted user to execute a command as the superuser or another user, as specified by the security policy in the /etc/sudoers
file. Unlike su
, sudo
does not switch the user context but runs a single command with elevated privileges. This approach enhances security by limiting the scope of administrative actions and reducing the risk of accidental system changes.
Basic usage of sudo
:
sudo [command]
Executing a command as root:
sudo apt-get update
This command updates the package lists for upgrades and new packages. The user must authenticate with their own password, not the root password.
Running a command as a different user with -u
:
sudo -u alice ls /home/alice
This command lists the contents of alice
's home directory while running as alice
.
Editing the sudoers file:
sudo visudo
This command opens the sudoers file in a safe editor, allowing administrators to configure permissions and security policies for sudo
usage.
Differences Between su
and sudo
- Authentication:
su
requires the target user's password (typically root), whereassudo
requires the invoking user's password. - Scope:
su
opens a new shell session as the target user, whilesudo
executes a single command with elevated privileges. - Configuration:
sudo
is highly configurable through the/etc/sudoers
file, allowing fine-grained control over which users can run specific commands as other users.
Examples
Using su to become root:
su
Password:
[root@linuxbox ~]#
The user switches to the root account and gains full administrative privileges.
Using su
to switch to another user:
su alice
Password:
[alice@linuxbox ~]$
The user switches to alice
, gaining alice
's environment and permissions.
Using sudo
to run a command as root:
sudo systemctl restart apache2
[sudo] password for user:
The user restarts the Apache web server with root privileges after authenticating with their password.
Using sudo
to run a command as another user:
sudo -u alice ls /home/alice
The user lists the contents of alice
's home directory, executing the command as alice
.
Configuring sudo
permissions:
sudo visudo
The administrator edits the sudoers file to grant specific permissions to users or groups, ensuring secure and controlled use of sudo
.
Summary
The su
and sudo
commands are essential tools for managing user permissions and performing administrative tasks in Linux. su
allows switching to another user account, opening a new shell session with that user's permissions and environment. sudo
provides a more secure and flexible approach by enabling the execution of individual commands with elevated privileges, controlled by the sudoers configuration. Mastering these commands ensures effective and secure system administration.
chown, chgrp and passwd Commands
In Linux, managing file ownership and user passwords is crucial for system security and user management. The chown
, chgrp
, and passwd
commands are essential tools for these tasks. Understanding these commands allows administrators to effectively control file access and maintain secure user accounts.
NOTE: You will not have permissions to do these commands on the Cidermill server.
The chown Command
The chown
command stands for "change owner." It is used to change the ownership of files and directories. In Linux, each file and directory is associated with an owner and a group. The chown
command allows the superuser (root) or a user with the necessary permissions to change the owner of a file or directory.
Basic usage of chown
:
chown [owner] [file]
To change the owner of a file:
sudo chown alice file.txt
This command changes the owner of file.txt
to alice
. The sudo
command is used because changing ownership typically requires superuser privileges.
To change the owner and group of a file:
sudo chown alice:developers project/
This command changes the owner of the project
directory to alice
and the group to developers
.
To recursively change ownership:
sudo chown -R alice:developers /home/alice
This command recursively changes the owner and group of all files and directories within /home/alice
to alice
and developers
.
The chgrp Command
The chgrp
command stands for "change group." It is used to change the group ownership of a file or directory. This command is useful when you need to change the group associated with a file or directory without modifying the owner.
Basic usage of chgrp
:
chgrp [group] [file]
To change the group of a file:
sudo chgrp developers file.txt
This command changes the group of file.txt
to developers
.
To recursively change the group of a directory:
sudo chgrp -R developers /project
This command recursively changes the group of all files and directories within /project
to developers
.
The passwd Command
The passwd
command is used to change a user's password. This command can be used by any user to change their own password or by the superuser to change the password of another user. Changing passwords regularly is an essential practice for maintaining system security.
Basic usage of passwd
:
passwd [username]
To change your own password:
passwd
This command prompts the user to enter their current password, followed by the new password. The password must meet the system's complexity requirements.
To change another user's password:
sudo passwd alice
This command allows the superuser to change the password for the user alice
. The superuser is prompted to enter the new password for alice
.
To lock a user's password:
sudo passwd -l alice
This command locks alice
's password, preventing the user from logging in.
To unlock a user's password:
sudo passwd -u alice
This command unlocks alice
's password, allowing the user to log in again.
Examples
To change the owner of a file:
sudo chown bob report.txt
This changes the owner of report.txt
to bob
.
To change the group of a directory:
sudo chgrp managers /reports
This changes the group of the /reports
directory to managers
.
To change your own password:
passwd
The user is prompted to enter their current password and then the new password.
To change another user's password:
sudo passwd john
The superuser is prompted to enter a new password for the user john
.
To recursively change the owner and group:
sudo chown -R user1:team1 /home/user1
This changes the owner to user1
and the group to team1
for all files and directories within /home/user1
.
Summary
The chown
, chgrp
, and passwd
commands are essential for managing file ownership and user passwords in Linux. chown
changes the owner (and optionally the group) of files and directories, chgrp
changes the group ownership, and passwd
changes user passwords. These commands help maintain proper access controls and ensure the security of the system. Understanding how to use these commands effectively is a crucial skill for Linux administrators.
Chapter 6
ps and top Commands
Lesson: Understanding the ps and top Commands in Linux
In Linux, monitoring system processes is crucial for managing system performance and troubleshooting issues. The ps
and top
commands are essential tools for this task, providing detailed information about running processes. Understanding these commands and their options allows administrators to efficiently manage system resources.
The ps Command
The ps
(process status) command is used to display information about active processes. It provides a snapshot of the current processes, allowing users to see details such as process IDs (PIDs), CPU and memory usage, and the commands that started the processes.
Basic usage of ps
:
ps
This command displays information about the processes running in the current shell session.
Common options for ps
:
Option | Description |
---|---|
-e |
Show information about all processes. |
-f |
Display full format listing (detailed). |
-u |
Display processes for a specific user. |
-l |
Display long format listing. |
-aux |
Show all processes with detailed information. |
--sort |
Sort processes based on a specified field. |
Examples of ps
usage:
To display all processes:
ps -e
Output:
PID TTY TIME CMD
1 ? 00:00:02 systemd
2 ? 00:00:00 kthreadd
3 ? 00:00:00 rcu_gp
...
To display detailed information about all processes:
ps -ef
Output:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:19 ? 00:00:02 /sbin/init
root 2 0 0 14:19 ? 00:00:00 [kthreadd]
root 3 2 0 14:19 ? 00:00:00 [rcu_gp]
...
To display processes for a specific user:
ps -u alice
Output:
PID TTY TIME CMD
1234 ? 00:00:00 bash
2345 ? 00:00:01 firefox
...
To display processes in long format:
ps -l
Output:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S root 1 0 0 80 0 - 5466 - ? 00:00:02 systemd
1 S root 2 0 0 80 0 - 0 - ? 00:00:00 kthreadd
1 S root 3 2 0 80 0 - 0 - ? 00:00:00 rcu_gp
...
To show all processes with detailed information:
ps aux
Output:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169936 1232 ? Ss 14:19 0:02 /sbin/init
root 2 0.0 0.0 0 0 ? S 14:19 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 14:19 0:00 [rcu_gp]
...
To sort processes by CPU usage:
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu
Output:
PID PPID CMD %MEM %CPU
2345 1 /usr/bin/firefox 2.3 10.5
1234 1 /usr/bin/bash 0.1 1.0
...
Columns in ps Command Output
Column | Description |
---|---|
PID |
Process ID, a unique identifier for each process. |
TTY |
Terminal type associated with the process. |
TIME |
Cumulative CPU time used by the process. |
CMD |
Command that initiated the process. |
UID |
User ID of the process owner. |
PPID |
Parent process ID. |
%CPU |
Percentage of CPU time used by the process. |
%MEM |
Percentage of physical memory used by the process. |
C |
CPU utilization of the process. |
STIME |
Start time of the process. |
VSZ |
Virtual memory size of the process. |
RSS |
Resident Set Size, the non-swappable physical memory used by the process. |
STAT |
Process state code. |
Here is a list of the common Process state codes ps
:
Code | Description |
---|---|
R |
Running or runnable (on run queue) |
S |
Sleeping (waiting for an event to complete) |
D |
Uninterruptible sleep (usually waiting for I/O) |
Z |
Zombie (terminated but not reaped by parent) |
T |
Stopped, either by a job control signal or because it is being traced |
t |
Stopped by debugger during the tracing |
X |
Dead (should never be seen) |
K |
Wakekill (woken up by a fatal signal while in an uninterruptible sleep) |
W |
Paging (not valid since Linux 2.6.x) |
P |
Parked (used by real-time threads that are parked) |
I |
Idle kernel thread |
L |
Locked (process is waiting for CPU lock or I/O operation to finish) |
< |
High-priority process (has a real-time priority or is in high-priority scheduling class) |
N |
Low-priority process (has a lower priority than normal) |
s |
Session leader (a process that is a session leader) |
l |
Multi-threaded (using CLONE_THREAD, so that it shares the thread group) |
+ |
Process is in the foreground process group |
This format makes the process state codes stand out for easier reference.
The top Command
The top
command provides a real-time, dynamic view of the system's running processes. It continuously updates the display, showing which processes are using the most system resources. top
is highly configurable and allows users to sort and filter processes based on various criteria.
Basic usage of top
:
top
This command opens the top
interface, displaying information about the most resource-intensive processes.
Common options for top
:
Option | Description |
---|---|
-d |
Set the delay between updates (in seconds). |
-u |
Show processes for a specific user. |
-p |
Monitor specific PIDs. |
-n |
Number of iterations before top exits. |
-b |
Run top in batch mode (useful for logging). |
-o |
Sort processes based on a specified field. |
Examples of top
usage:
To run top
with the default settings:
top
Output:
top - 14:29:03 up 1:10, 2 users, load average: 0.48, 0.34, 0.23
Tasks: 193 total, 1 running, 192 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.5 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.5 si, 0.0 st
KiB Mem : 8000224 total, 3145752 free, 2392308 used, 2462164 buff/cache
KiB Swap: 8191996 total, 8191996 free, 0 used. 5062348 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2345 alice 20 0 2674292 473240 100768 S 10.5 5.9 1:23.45 firefox
1234 bob 20 0 43456 3824 3236 S 1.0 0.1 0:00.75 bash
...
To set the delay between updates to 5 seconds:
top -d 5
To show processes for a specific user:
top -u alice
Output:
top - 14:31:12 up 1:12, 2 users, load average: 0.42, 0.32, 0.22
Tasks: 13 total, 1 running, 12 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.2 us, 0.3 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.5 si, 0.0 st
KiB Mem : 8000224 total, 3145752 free, 2392308 used, 2462164 buff/cache
KiB Swap: 8191996 total, 8191996 free, 0 used. 5062348 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2345 alice 20 0 2674292 473240 100768 S 10.5 5.9 1:23.45 firefox
...
To monitor specific PIDs:
top -p 1234,5678
Output:
top - 14:32:45 up 1:14, 2 users, load average: 0.35, 0.31, 0.21
Tasks: 2 total
, 1 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.7 us, 0.3 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8000224 total, 3145752 free, 2392308 used, 2462164 buff/cache
KiB Swap: 8191996 total, 8191996 free, 0 used. 5062348 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 bob 20 0 43456 3824 3236 S 1.0 0.1 0:00.75 bash
5678 charlie 20 0 123456 5678 678 S 0.0 0.1 0:00.05 someprocess
To run top
for a specific number of iterations:
top -n 10
To run top
in batch mode for logging:
top -b -n 1 > top_output.txt
To sort processes by memory usage:
top -o %MEM
Output:
top - 14:34:19 up 1:16, 2 users, load average: 0.30, 0.28, 0.20
Tasks: 193 total, 1 running, 192 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.5 sy, 0.0 ni, 98.0 id, 0.0 wa, 0.0 hi, 0.5 si, 0.0 st
KiB Mem : 8000224 total, 3145752 free, 2392308 used, 2462164 buff/cache
KiB Swap: 8191996 total, 8191996 free, 0 used. 5062348 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2345 alice 20 0 2674292 473240 100768 S 10.5 5.9 1:23.45 firefox
6789 bob 20 0 1234567 234567 34567 S 1.0 3.0 0:12.34 someotherprocess
...
Columns in top
Command Output
Column | Description |
---|---|
PID |
Process ID, a unique identifier for each process. |
USER |
User who owns the process. |
PR |
Priority of the process. |
NI |
Nice value, which affects the process priority. |
VIRT |
Virtual memory size used by the process. |
RES |
Resident Set Size, the non-swappable physical memory used by the process. |
SHR |
Shared memory size used by the process. |
S |
Process state (e.g., running, sleeping). |
%CPU |
Percentage of CPU time used by the process. |
%MEM |
Percentage of physical memory used by the process. |
TIME+ |
Total CPU time used by the process. |
COMMAND |
Command that started the process. |
Explanation of Fields
Header Information
Field | Description |
---|---|
top - 14:34:19 |
Current time when top was run. |
up 1:16 |
System uptime, showing how long the system has been running. |
2 users |
Number of users currently logged into the system. |
load average: 0.30, 0.28, 0.20 |
System load averages for the last 1, 5, and 15 minutes. |
Task Information
Field | Description |
---|---|
Tasks: 193 total |
Total number of tasks (processes) currently managed by the system. |
1 running |
Number of tasks currently running. |
192 sleeping |
Number of tasks currently sleeping (inactive but not stopped). |
0 stopped |
Number of tasks currently stopped (halted). |
0 zombie |
Number of zombie tasks (terminated but not reaped by parent). |
CPU Usage Information
Field | Description |
---|---|
%Cpu(s): |
Overview of CPU usage breakdown. |
1.0 us |
Percentage of CPU time spent in user space. |
0.5 sy |
Percentage of CPU time spent in kernel space (system). |
0.0 ni |
Percentage of CPU time spent on low-priority processes. |
98.0 id |
Percentage of CPU time spent idle. |
0.0 wa |
Percentage of CPU time spent waiting for I/O operations to complete. |
0.0 hi |
Percentage of CPU time spent handling hardware interrupts. |
0.5 si |
Percentage of CPU time spent handling software interrupts. |
0.0 st |
Percentage of CPU time stolen from a virtual machine. |
Memory Usage Information
Field | Description |
---|---|
KiB Mem : |
Overview of physical memory usage. |
8000224 total |
Total amount of physical memory. |
3145752 free |
Amount of free memory. |
2392308 used |
Amount of used memory. |
2462164 buff/cache |
Amount of memory used for buffers and cache. |
Swap Usage Information
Field | Description |
---|---|
KiB Swap: |
Overview of swap memory usage. |
8191996 total |
Total amount of swap space. |
8191996 free |
Amount of free swap space. |
0 used |
Amount of used swap space. |
5062348 avail Mem |
Amount of memory available for starting new applications, without swapping. |
Summary
The ps
and top
commands are powerful tools for monitoring and managing system processes in Linux. ps
provides a static snapshot of current processes, offering various options for detailed views and sorting. top
offers a dynamic, real-time view, allowing users to interactively monitor and manage processes. By mastering these commands and their options, administrators can effectively manage system resources and ensure optimal performance.
jobs, fg and bg Commands
In Linux, managing background and foreground processes is essential for multitasking and efficient workflow. The jobs
, fg
, and bg
commands allow users to control and manipulate these processes. Additionally, keyboard shortcuts like Ctrl-C
and Ctrl-Z
provide quick ways to interact with running processes. Understanding these commands and shortcuts can greatly enhance your command-line productivity.
Creating and Running a Background Script
Consider the following script that repeatedly outputs a message every 15 seconds:
echo 'echo "I am running"; while sleep 15; do echo "I am running"; done' > myscript.sh
chmod +x myscript.sh
This script prints "I am running" immediately and then every 15 seconds. The chmod +x myscript.sh
command makes the script executable. NOTE: You just do the chmod +x myscript.sh
or chmod 700 myscript.sh
To run this script in the background, use the following command:
./myscript.sh &
This command runs the myscript.sh
script in the background, allowing you to continue using the terminal. Alternatively, you can run the script using:
bash myscript.sh &
The jobs Command
The jobs
command lists all background jobs started in the current shell session. Each job is assigned a job ID, which can be used to manipulate the job with other commands.
Example:
jobs
Output:
[1]+ Running ./myscript.sh &
In this example, job 1 is running in the background.
The fg
Command
The fg
(foreground) command is used to bring a background job to the foreground. You can specify the job ID to bring a specific job to the foreground.
Example:
fg %1
This command brings job 1 (the myscript.sh
script) to the foreground.
If you omit the job ID, fg
brings the most recently stopped or background job to the foreground:
fg
The bg
Command
The bg
(background) command resumes a stopped job in the background. Like fg
, you can specify the job ID to resume a specific job.
Example:
bg %1
This command resumes job 1 (the myscript.sh
script) in the background.
If you omit the job ID, bg
resumes the most recently stopped job:
bg
Keyboard Shortcuts: Ctrl-C and Ctrl-Z
Ctrl-C
:
The Ctrl-C
keyboard shortcut sends the SIGINT
(interrupt) signal to the foreground process, terminating it immediately. This is useful for stopping processes that are taking too long or behaving unexpectedly.
Example:
./myscript.sh
Press Ctrl-C
to stop the myscript.sh
script.
Ctrl-Z
:
The Ctrl-Z
keyboard shortcut sends the SIGTSTP
(terminal stop) signal to the foreground process, suspending it and putting it in the background as a stopped job. This allows you to temporarily halt a process and resume it later with fg
or bg
.
Example:
./myscript.sh
Press Ctrl-Z
to suspend the myscript.sh
script.
Examples Using the Script
To run the script in the background:
./myscript.sh &
This runs the myscript.sh
script in the background.
To list all background jobs:
jobs
Output:
[1]+ Running ./myscript.sh &
To bring the background job to the foreground:
fg %1
This brings job 1 to the foreground.
To suspend the foreground script:
./myscript.sh
Press Ctrl-Z
to suspend the myscript.sh
script.
To resume the stopped job in the background:
bg %1
This resumes job 1 in the background.
To terminate the foreground script:
./myscript.sh
Press Ctrl-C
to stop the myscript.sh
script.
Summary
The jobs
, fg
, and bg
commands, along with keyboard shortcuts Ctrl-C
and Ctrl-Z
, provide powerful tools for managing processes in Linux. These commands allow you to run, suspend, resume, and terminate processes, enhancing your ability to multitask and control your workflow efficiently. By mastering these commands and shortcuts, you can become more productive and effective in the Linux command-line environment.
kill, killall and shutdown Commands
In Linux, controlling processes and managing system shutdowns are crucial for maintaining system stability and performance. The kill
, killall
, and shutdown
commands are essential tools for these tasks. Understanding these commands and their options allows administrators to effectively manage processes and system power states.
The kill Command
The kill
command is used to send signals to processes, typically to terminate them. Each process in Linux has a unique process ID (PID), and the kill
command uses this PID to target specific processes. While kill
can send various signals, it is most commonly used to terminate processes.
Basic usage of kill
:
kill [options] <PID>
Commonly Used kill
Signals:
Signal | Description | Example Command |
---|---|---|
1 |
SIGHUP - Hangup | kill -1 <PID> |
2 |
SIGINT - Interrupt from keyboard | kill -2 <PID> |
9 |
SIGKILL - Kill signal | kill -9 <PID> |
15 |
SIGTERM - Termination signal | kill -15 <PID> |
18 |
SIGCONT - Continue if stopped | kill -18 <PID> |
19 |
SIGSTOP - Stop process | kill -19 <PID> |
Examples:
To gracefully terminate a process with PID 1234:
kill -15 1234
To forcefully terminate a process with PID 1234:
kill -9 1234
To stop a process with PID 1234 without terminating it:
kill -19 1234
To continue a stopped process with PID 1234:
kill -18 1234
The killall Command
The killall
command is used to send signals to multiple processes by name rather than by PID. This command is useful when you need to terminate all instances of a specific process.
Basic usage of killall
:
killall [options] <process_name>
Examples:
To gracefully terminate all instances of the nano
editor:
killall -15 nano
To forcefully terminate all instances of the firefox
browser:
killall -9 firefox
The shutdown Command
The shutdown
command is used to bring the system down in a safe way. It allows administrators to power off, reboot, or halt the system. The shutdown
command can schedule a shutdown for a specified time or immediately.
NOTE: You will not have permissions to shutdown the Cidermill server.
Basic usage of shutdown
:
shutdown [options] [time] [message]
Common shutdown
Options:
Option | Description | Example Command |
---|---|---|
-h |
Halt the system | shutdown -h now |
-r |
Reboot the system | shutdown -r now |
-c |
Cancel a scheduled shutdown | shutdown -c |
+m |
Schedule shutdown in m minutes |
shutdown -h +10 "System update" |
Examples:
To shut down the system immediately:
shutdown -h now
To reboot the system immediately:
shutdown -r now
To schedule a shutdown in 15 minutes with a message:
shutdown -h +15 "System will shut down in 15 minutes"
To cancel a scheduled shutdown:
shutdown -c
You can also reboot the systerm using reboot
reboot
Summary
The kill
, killall
, and shutdown
commands are essential tools for managing processes and system power states in Linux. The kill
command allows for sending various signals to processes using their PIDs, while killall
targets processes by name. The shutdown
command provides options for halting, rebooting, or scheduling system shutdowns. By mastering these commands and their options, administrators can effectively control processes and manage system shutdowns, ensuring system stability and performance.
Understanding the Environment in Linux
The shell maintains a body of information during a session called the environment. Programs use data stored in the environment to determine facts about the system's configuration. While most programs use configuration files to store settings, some also look for values in the environment to adjust their behavior. Knowing this, we can customize our shell experience using the environment.
In this lesson, we will work with the following commands:
printenv
– Print part or all of the environmentset
– Set shell optionsexport
– Export environment to subsequently executed programsalias
– Create an alias for a command
What is Stored in the Environment?
The shell stores two basic types of data in the environment: environment variables and shell variables. Shell variables are bits of data placed there by bash, while environment variables are everything else. In addition to variables, the shell stores some programmatic data, namely aliases and shell functions.
Examining The Environment
To see what is stored in the environment, you can use either the set
builtin in bash or the printenv
program. The set
command will show both shell and environment variables, while printenv
will only display the latter. Since the list of environment contents can be long, it is best to pipe the output into less
.
Example:
printenv | less
Output:
USER=me
PAGER=less
LSCOLORS=Gxfxcxdxbxegedabagacad
XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg
PATH=/home/me/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
DESKTOP_SESSION=ubuntu
QT_IM_MODULE=ibus
QT_QPA_PLATFORMTHEME=appmenu-qt5
JOB=dbus
PWD=/home/me
XMODIFIERS=@im=ibus
GNOME_KEYRING_PID=1850
LANG=en_US.UTF-8
GDM_LANG=en_US
MANDATORY_PATH=/usr/share/gconf/ubuntu.mandatory.path
MASTER_HOST=linuxbox
IM_CONFIG_PHASE=1
COMPIZ_CONFIG_PROFILE=ubuntu
GDMSESSION=ubuntu
SESSIONTYPE=gnome-session
XDG_SEAT=seat0
HOME=/home/me
SHLVL=2
LANGUAGE=en_US
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
LESS=-R
LOGNAME=me
COMPIZ_BIN_PATH=/usr/bin/
LC_CTYPE=en_US.UTF-8
XDG_DATA_DIRS=/usr/share/ubuntu:/usr/share/gnome:/usr/local/share:/usr/share
QT4_IM_MODULE=xim
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-IwaesmWaT0
LESSOPEN=| /usr/bin/lesspipe %s
INSTANCE=
The output lists environment variables and their values. For example, the variable USER
contains the value me
. The printenv
command can also list the value of a specific variable.
Example:
printenv USER
Output:
me
The set
command, when used without options or arguments, will display both shell and environment variables, as well as any defined shell functions. Unlike printenv
, its output is sorted in alphabetical order.
Example:
set | less
Commonly Used set
Options:
Option | Description |
---|---|
-o |
Set a shell option |
+o |
Unset a shell option |
-u |
Treat unset variables as an error |
-x |
Print commands and their arguments as they are executed |
-v |
Print shell input lines as they are read |
Examples:
To set the shell option to treat unset variables as an error:
set -u
To print commands and their arguments as they are executed:
set -x
To unset these options:
set +u
set +x
To view shell options:
set -o
You can also view the contents of a variable using the echo
command:
echo $HOME
Output:
/home/me
To see aliases, enter the alias
command without arguments:
alias
Output:
alias l.='ls -d .* --color=tty'
alias ll='ls -l --color=tty'
alias ls='ls --color=tty'
alias vi='vim'
alias which='alias | /usr/bin/which --tty-only --read-alias --showdot --show-tilde'
To create an alias, use the alias
command followed by the name you want to assign and the command it represents:
alias l='ls -l'
alias rm='rm -i'
Some Interesting Variables
The environment contains quite a few variables, and while they may differ from system to system, the following are commonly found:
Variable | Contents |
---|---|
DISPLAY |
The name of the display if running a graphical environment, usually :0 . |
EDITOR |
The name of the program to be used for text editing. |
SHELL |
The name of the user’s default shell program. |
HOME |
The pathname of your home directory. |
LANG |
Defines the character set and collation order of your language. |
OLDPWD |
The previous working directory. |
PAGER |
The name of the program to be used for paging output, often /usr/bin/less . |
PATH |
A colon-separated list of directories that are searched when you enter the name of an executable program. |
PS1 |
This stands for "prompt string 1" and defines the contents of the shell prompt. |
PWD |
The current working directory. |
TERM |
The name of your terminal type. |
TZ |
Specifies your time zone. |
USER |
Your username. |
How Is The Environment Established?
When you log on to the system, bash starts and reads a series of configuration scripts called startup files, which define the default environment shared by all users. This is followed by more startup files in your home directory that define your personal environment. The exact sequence depends on the type of shell session being started: login or non-login.
Login Shell Session: A session where you are prompted for your username and password, such as when starting a virtual console session.
Non-Login Shell Session: Typically occurs when launching a terminal session in the GUI.
Startup Files for Login Shell Sessions:
File | Contents |
---|---|
/etc/profile |
A global configuration script that applies to all users. |
~/.bash_profile |
A user's personal startup file to extend or override settings in the global configuration script. |
~/.bash_login |
If ~/.bash_profile is not found, bash attempts to read this script. |
~/.profile |
If neither ~/.bash_profile nor ~/.bash_login is found, bash attempts to read this file. This is the default in Debian-based distributions. |
Startup Files for Non-Login Shell Sessions:
File | Contents |
---|---|
/etc/bash.bashrc |
A global configuration script that applies to all users. |
~/.bashrc |
A user's personal startup file to extend or override settings in the global configuration script. |
Non-login shells inherit the environment from their parent process, usually a login shell.
The ~/.bashrc
file is important because it is almost always read. Non-login shells read it by default, and most startup files for login shells are written to read the ~/.bashrc
file as well.
What's in a Startup File?
A typical .bash_profile
might look like this:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
Lines starting with #
are comments. The fourth line contains an if
compound command:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
This means: If the file ~/.bashrc
exists, then read it. This is how a login shell gets the contents of .bashrc
.
The next part deals with the PATH
variable:
PATH=$PATH:$HOME/bin
This modifies PATH
to add $HOME/bin
to the end of the list of directories searched when a command is entered. This allows you to create a bin
directory in your home directory for storing private programs.
Finally:
export PATH
The export
command makes the contents of PATH
available to child processes of the shell.
Modifying the Environment
You can customize your environment by modifying the startup files.
Which Files Should You Modify?
- Add directories to your
PATH
or define additional environment variables in.bash_profile
(or.profile
for some distributions like Ubuntu). - For other customizations, use
.bashrc
.
Text Editors: To modify shell startup files and configuration files, use a text editor. Linux systems typically come with several text
editors, both graphical (like gedit for GNOME or kate for KDE) and text-based (like nano, vi/vim, and emacs).
For this class we will be using vi/vim.
Chapter 7
ping and tracroute Commands
The ping
and traceroute
commands are essential network diagnostic tools in Linux. These commands help users test connectivity and trace the path packets take to reach a destination, respectively. Understanding how to use these commands and interpret their outputs is crucial for troubleshooting network issues.
The ping
Command
The ping
command checks the connectivity between your computer and another host. It sends Internet Control Message Protocol (ICMP) Echo Request packets to the target host and waits for Echo Reply packets. This helps determine if the target host is reachable and measures the round-trip time for messages sent.
Basic usage of ping
:
ping [options] destination
Commonly Used ping
Options:
Option | Description |
---|---|
-c |
Specify the number of packets to send |
-i |
Specify the interval between sending each packet |
-t |
Set the Time to Live (TTL) for packets |
-q |
Quiet output, showing summary only at the end |
-s |
Specify the number of data bytes to be sent |
-w |
Specify a timeout, in seconds, before the command exits |
Examples:
To ping a host:
ping google.com
Output:
PING google.com (172.217.16.206) 56(84) bytes of data.
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=1 ttl=53 time=11.6 ms
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=2 ttl=53 time=10.8 ms
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=3 ttl=53 time=10.9 ms
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 10.805/11.113/11.590/0.347 ms
To ping a host with a specific number of packets:
ping -c 4 google.com
Output:
PING google.com (172.217.16.206) 56(84) bytes of data.
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=1 ttl=53 time=11.6 ms
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=2 ttl=53 time=10.8 ms
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=3 ttl=53 time=10.9 ms
64 bytes from dfw25s14-in-f14.1e100.net (172.217.16.206): icmp_seq=4 ttl=53 time=10.7 ms
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 10.708/11.005/11.586/0.321 ms
The traceroute
Command
The traceroute
command shows the path that packets take to reach a destination. It sends packets with incrementally increasing Time to Live (TTL) values, causing routers along the path to return ICMP Time Exceeded messages. This helps identify each hop along the route to the destination.
Basic usage of traceroute
:
traceroute [options] destination
Commonly Used traceroute
Options:
Option | Description |
---|---|
-m |
Set the maximum TTL for packets |
-p |
Set the destination port |
-q |
Set the number of queries per hop |
-w |
Set the time to wait for a response, in seconds |
-n |
Print hop addresses numerically rather than resolving hostnames |
Examples:
To trace the route to a host:
traceroute google.com
Output:
traceroute to google.com (172.217.16.206), 30 hops max, 60 byte packets
1 192.168.1.1 (192.168.1.1) 2.232 ms 2.089 ms 2.055 ms
2 * * *
3 10.0.0.1 (10.0.0.1) 11.133 ms 11.052 ms 10.939 ms
4 172.217.16.206 (172.217.16.206) 10.714 ms 10.544 ms 10.362 ms
The ***
in the output indicates that the router at that hop did not respond to the traceroute
request within the expected time frame. This can happen due to network congestion, firewalls, or routers configured not to send ICMP Time Exceeded messages.
To trace the route with a maximum of 10 hops:
traceroute -m 10 google.com
Output:
traceroute to google.com (172.217.16.206), 10 hops max, 60 byte packets
1 192.168.1.1 (192.168.1.1) 2.232 ms 2.089 ms 2.055 ms
2 * * *
3 10.0.0.1 (10.0.0.1) 11.133 ms 11.052 ms 10.939 ms
4 172.217.16.206 (172.217.16.206) 10.714 ms 10.544 ms 10.362 ms
Summary
The ping
and traceroute
commands are indispensable for network troubleshooting in Linux. The ping
command checks connectivity and measures round-trip time between your computer and a host, while the traceroute
command traces the path packets take to reach a destination, providing insights into the route and potential points of failure. The ***
in the traceroute
output indicates non-responsive routers, which can be due to various reasons such as network congestion or firewall settings. By mastering these commands and understanding their outputs, you can effectively diagnose and resolve network issues.
ip and netstat Commands
The ip
and netstat
commands are essential tools for managing and monitoring network configurations and connections in Linux. The ip
command is used for network interface configuration, IP address manipulation, and routing, while netstat
is used to display network connections, routing tables, interface statistics, masquerade connections, and multicast memberships. Understanding these commands, their outputs, and their options is crucial for effective network management.
The ip Command
The ip
command is part of the iproute2
package and is used to configure network interfaces, IP addresses, and routing.
Basic usage of ip
:
ip [OPTIONS] OBJECT { COMMAND | help }
Commonly Used ip
Options:
Option | Description |
---|---|
addr |
Display or manipulate IP addresses |
link |
Display or manipulate network interfaces |
route |
Display or manipulate routing tables |
neigh |
Display or manipulate ARP cache |
-s |
Display detailed statistics |
Examples and Output Explanations:
To display all IP addresses:
ip addr
Output:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:53:8b:dc brd ff:ff:ff:ff:ff:ff
inet 192.168.1.10/24 brd 192.168.1.255 scope global dynamic enp0s3
valid_lft 86352sec preferred_lft 86352sec
inet6 fe80::a00:27ff:fe53:8bdc/64 scope link
valid_lft forever preferred_lft forever
lo
: Loopback interface, used for local communication within the host.enp0s3
: Ethernet interface, used for network communication.inet
: IPv4 address of the interface.inet6
: IPv6 address of the interface.mtu
: Maximum Transmission Unit, the size of the largest packet that can be transmitted.qdisc
: Queueing discipline, the algorithm used to manage the queue of packets.
To display the link layer information:
ip link
Output:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 08:00:27:53:8b:dc brd ff:ff:ff:ff:ff:ff
link/loopback
: Indicates the link type for the loopback interface.link/ether
: Indicates the link type for the Ethernet interface.brd
: Broadcast address.
To display the routing table:
ip route
Output:
default via 192.168.1.1 dev enp0s3 proto dhcp metric 100
192.168.1.0/24 dev enp0s3 proto kernel scope link src 192.168.1.10 metric 100
default
: The default gateway.via
: The gateway IP address.dev
: The device (network interface) used.proto
: The protocol used to configure the route.scope
: The scope of the route (link, global, etc.).src
: The source IP address for packets sent via this route.
The netstat Command
The netstat
command displays various network-related information such as network connections, routing tables, interface statistics, masquerade connections, and multicast memberships.
Basic usage of netstat
:
netstat [OPTIONS]
Commonly Used netstat
Options:
Option | Description |
---|---|
-a |
Show all sockets (listening and non-listening) |
-t |
Show TCP connections |
-u |
Show UDP connections |
-n |
Show numerical addresses instead of resolving hostnames |
-r |
Display the routing table |
-i |
Display network interface statistics |
-s |
Display summary statistics for each protocol |
-p |
Show process using the socket |
Examples and Output Explanations:
To display all network connections:
netstat -a
Output:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 192.168.1.10:22 192.168.1.100:54678 ESTABLISHED
udp 0 0 0.0.0.0:68 0.0.0.0:*
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 13383 /run/systemd/notify
Proto
: Protocol (TCP, UDP, etc.).Recv-Q
: Receive queue size.Send-Q
: Send queue size.Local Address
: Local address and port.Foreign Address
: Remote address and port.State
: Connection state (LISTEN, ESTABLISHED, etc.).
To display the routing table:
netstat -r
Output:
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
default 192.168.1.1 0.0.0.0 UG 0 0 0 enp0s3
192.168.1.0 * 255.255.255.0 U 0 0 0 enp0s3
Destination
: Network destination.Gateway
: Gateway IP address.Genmask
: Network mask.Flags
: Route flags (U = up, G = gateway).Iface
: Network interface.
To display network interface statistics:
netstat -i
Output:
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
enp0s3 1500 4823 0 0 0 4325 0 0 0 BMRU
lo 65536 1522 0 0 0 1522 0 0 0 LRU
Iface
: Network interface.MTU
: Maximum Transmission Unit.RX-OK
: Received packets without errors.RX-ERR
: Received packets with errors.RX-DRP
: Dropped received packets.RX-OVR
: Overruns on received packets.TX-OK
: Transmitted packets without errors.TX-ERR
: Transmitted packets with errors.TX-DRP
: Dropped transmitted packets.TX-OVR
: Overruns on transmitted packets.
To display summary statistics for each protocol:
netstat -s
Output:
Ip:
4325 total packets received
0 forwarded
0 incoming packets discarded
4325 incoming packets delivered
4325 requests sent out
Tcp:
240 active connection openings
6 passive connection openings
0 failed connection attempts
0 connection resets received
2 connections established
2103 segments received
2200 segments sent out
0 segments retransmitted
0 bad segments received.
0 resets sent
Udp:
200 packets received
0 packets to unknown port received.
0 packet receive errors
200 packets sent
Ip
: Statistics for the IP protocol.Tcp
: Statistics for the TCP protocol.Udp
: Statistics for the UDP protocol.
Summary
The ip
and netstat
commands are powerful tools for network management and monitoring in Linux. Theipcommand allows for detailed configuration and display of network interfaces, IP addresses, and routing tables. The
netstat` command provides extensive information on network connections, routing tables, and interface statistics. By mastering these commands and understanding their outputs, you can effectively manage and troubleshoot network issues.
wget, ftp and sftp Commands
The wget
, ftp
, and sftp
commands are essential tools for transferring files between computers in Linux. wget
is a non-interactive network downloader, while ftp
and sftp
are used for interactive file transfers, with sftp
being the preferred and more secure option.
The wget Command
The wget
command is used for downloading files from the web. It supports HTTP, HTTPS, and FTP protocols and can download files non-interactively, making it ideal for automated downloads.
Basic usage of wget
:
wget [options] [URL]
Commonly Used wget
Options:
Option | Description |
---|---|
-O |
Write output to a file instead of standard output |
-c |
Resume a partially downloaded file |
-q |
Quiet mode (no output) |
-r |
Recursive download |
-l |
Set the maximum depth for recursive downloads |
--limit-rate |
Limit the download speed |
To download a file using wget
:
wget http://example.com/file.txt
Output:
--2024-07-10 10:00:00-- http://example.com/file.txt
Resolving example.com (example.com)... 93.184.216.34
Connecting to example.com (example.com)|93.184.216.34|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1234 (1.2K) [text/plain]
Saving to: 'file.txt'
file.txt 100%[===================>] 1.21K --.-KB/s in 0s
2024-07-10 10:00:01 (234 MB/s) - ‘file.txt’ saved [1234/1234]
The ftp Command
The ftp
(File Transfer Protocol) command is used to transfer files between a client and a server. It is an older protocol that is less secure compared to sftp
. ftp
transfers data in plaintext, making it vulnerable to interception and attacks. Due to its security limitations, sftp
is now the preferred method for file transfers.
The sftp Command
The sftp
(Secure File Transfer Protocol) command is a secure version of ftp
that uses SSH (Secure Shell) to encrypt the data being transferred. It is preferred over ftp
due to its enhanced security features.
Basic usage of sftp
:
sftp [user@]hostname
Commonly Used sftp
Options:
Option | Description |
---|---|
-b |
Batch mode reads a series of commands from a file |
-C |
Enable compression |
-P |
Specify an alternate port |
-i |
Specify an identity file (private key) |
-q |
Quiet mode |
-v |
Verbose mode |
Examples and Output Explanations
To connect to an SFTP server:
sftp user@ftp.example.com
Output:
Connecting to ftp.example.com...
user@ftp.example.com's password:
sftp>
To list files on the remote server:
ls
Output:
files
file.txt
To list files on the local machine:
lls
Output:
Desktop Documents Downloads file.txt Pictures
To change directories on the remote server:
cd /path/to/remote/directory
Output:
sftp> cd /path/to/remote/directory
To change directories on the local machine:
lcd /path/to/local/directory
Output:
sftp> lcd /path/to/local/directory
To download a file from the remote server:
get file.txt
Output:
Fetching /home/user/file.txt to file.txt
/home/user/file.txt 100% 1234 1.2KB/s 00:00
To upload a file to the remote server:
put localfile.txt remotefile.txt
Output:
Uploading localfile.txt to /home/user/remotefile.txt
localfile.txt 100% 1234 1.2KB/s 00:00
To download multiple files:
mget *.txt
To upload multiple files:
mput *.txt
Differences Between ftp and sftp
The key difference between ftp
and sftp
is security. ftp
transfers data in plaintext, which makes it vulnerable to interception and attacks. In contrast, sftp
uses SSH to encrypt the data being transferred, providing a secure channel that protects the data from being intercepted or tampered with.
Due to its security advantages, sftp
is now preferred over ftp
for file transfers.
Summary
The wget
, ftp
, and sftp
commands are powerful tools for downloading and transferring files in Linux. wget
is used for non-interactive downloads, while ftp
and sftp
are used for interactive file transfers, with sftp
being the preferred option due to its enhanced security features. By mastering these commands and understanding their options, you can efficiently manage file transfers in the Linux environment.
Linux Archiving and Zipping
The gzip
, zip
, and tar
commands are essential tools in Linux for compressing and archiving files. Each tool has unique features and is used for different purposes.
The gzip Command
gzip
is a compression tool used to reduce the size of files. It does not create archives (collections of multiple files); instead, it compresses single files.
Common gzip
Options:
Option | Description |
---|---|
-d |
Decompress |
-k |
Keep the original file |
-l |
List compression information |
-r |
Recursively compress directories |
-v |
Verbose output |
-1 to -9 |
Set compression level (1 = fastest, 9 = slowest/maximum) |
Examples:
To compress a file:
gzip file.txt
To decompress a file:
gzip -d file.txt.gz
To keep the original file while compressing:
gzip -k file.txt
To recursively compress all files in a directory:
gzip -r directory/
The zip Command
zip
is a tool used for both compressing and archiving files. It can create zip archives containing multiple files and directories.
Common zip
Options:
Option | Description |
---|---|
-r |
Recursively add directories |
-d |
Delete files from the archive |
-u |
Update files in the archive |
-l |
List files in the archive |
-v |
Verbose output |
-e |
Encrypt the archive |
Examples:
To create a zip archive:
zip archive.zip file1.txt file2.txt
To unzip an archive:
unzip archive.zip
To add files to an existing archive:
zip archive.zip file3.txt
To recursively add directories to an archive:
zip -r archive.zip directory/
The tar Command
tar
is used to create archive files that can contain multiple files and directories. While tar
itself does not compress files, it is often used in combination with gzip
or bzip2
to create compressed archives (.tar.gz
or .tar.bz2
).
Common tar
Options:
Option | Description |
---|---|
-c |
Create a new archive |
-x |
Extract files from an archive |
-t |
List files in an archive |
-v |
Verbose output |
-f |
Specify the filename of the archive |
-z |
Filter the archive through gzip |
-j |
Filter the archive through bzip2 |
Examples:
To create a tar archive:
tar -cvf archive.tar file1.txt file2.txt
To extract a tar archive:
tar -xvf archive.tar
To create a compressed tar archive:
tar -czvf archive.tar.gz file1.txt file2.txt
To list the contents of a tar archive:
tar -tvf archive.tar
Differences Between gzip
and zip
gzip
compresses individual files, whilezip
compresses and archives multiple files and directories.gzip
is often used withtar
to compress tar archives, resulting in.tar.gz
files.zip
creates a single archive that contains compressed files and directories.
Differences Between gzip
, zip
, and tar
gzip
: Compresses single files. Commonly used withtar
to create compressed archives.zip
: Compresses and archives multiple files and directories in a single archive.tar
: Archives multiple files and directories but does not compress them by itself. Often used withgzip
orbzip2
for compression.
Viewing Contents of a Tar Archive Without Extracting
You can use the -t
option with tar
to list the contents of an archive without extracting it.
Example:
tar -tvf archive.tar
This command lists all files and directories in the archive.tar
file.
Summary
The gzip
, zip
, and tar
commands are essential for file compression and archiving in Linux. gzip
is used for compressing single files, zip
is used for creating compressed archives of multiple files and directories, and tar
is used for archiving multiple files and directories without compression (but can be combined with gzip
for compressed archives). Understanding the differences and common options for these commands allows you to efficiently manage and organize files in Linux.
Chapter 8
locate and find comands
The locate
and find
commands are powerful tools in Linux for searching files and directories. Each serves a different purpose and has distinct advantages and characteristics.
The locate Command
The locate
command searches for files and directories by name using a prebuilt database. This database is created and updated regularly by the updatedb
command, making locate
extremely fast for searching. However, because it relies on this database, the results might not reflect recent changes to the filesystem unless the database has been updated.
Basic usage of locate
:
locate [options] pattern
Commonly Used locate
Options:
Option | Description |
---|---|
-i |
Perform case-insensitive matching |
-r |
Use regular expressions |
-n |
Limit the number of results |
-e |
Print only existing files |
--existing |
Same as -e , print only existing files |
--regex |
Same as -r , interpret the pattern as a regex |
Examples:
To find files with "report" in their name:
locate report
To find files with "report" in their name, case-insensitively:
locate -i report
To find files using a regular expression:
locate -r 'report[0-9]*\.txt'
To update the locate
database:
sudo updatedb
This command updates the database that locate
uses, ensuring the search results are current.
The find Command
The find
command is used to search for files and directories within the filesystem based on various criteria. Unlike locate
, find
searches the directory tree in real-time, making it more versatile but generally slower.
Basic usage of find
:
find [path] [expression]
Tests
Tests are criteria used by find
to match files and directories.
Test | Description |
---|---|
-name |
Matches files with the specified name |
-iname |
Matches files with the specified name, case-insensitive |
-type |
Matches files of the specified type (f for file, d for directory) |
-size |
Matches files of the specified size |
-mtime |
Matches files modified n days ago |
-user |
Matches files owned by the specified user |
-cmin |
Matches files changed n minutes ago |
-cnewer |
Matches files changed more recently than another file |
-ctime |
Matches files changed n days ago |
-empty |
Matches empty files and directories |
Operators
Operators are used to combine multiple tests in find
.
Operator | Description |
---|---|
-and |
Logical AND |
-or |
Logical OR |
! |
Logical NOT |
Predefined Actions
Actions are operations that find
performs on the matched files and directories.
Action | Description |
---|---|
-print |
Print the matching files |
-delete |
Delete the matching files |
-exec |
Execute a command on matching files |
Examples of Using Operators and Predefined Actions:
To find files named "report.txt" and print their names:
find /path/to/search -name report.txt -print
To find files that are either named "report.txt" or "summary.txt":
find /path/to/search \( -name report.txt -or -name summary.txt \) -print
To find files that are not directories:
find /path/to/search ! -type d -print
To find files named "report.txt" and "summary.txt" and delete them:
find /path/to/search \( -name report.txt -or -name summary.txt \) -delete
To find files owned by "john" and modified in the last 7 days:
find /path/to/search -user john -and -mtime -7 -print
Size Options
Size options specify the size criteria for matching files.
Option | Description |
---|---|
+n |
Greater than n units |
-n |
Less than n units |
n |
Exactly n units |
c |
Bytes (default) |
k |
Kilobytes (1024 bytes) |
M |
Megabytes (1024 kilobytes) |
G |
Gigabytes (1024 megabytes) |
Examples of Size Options:
To find files larger than 1MB:
find /path/to/search -size +1M
To find files between 1MB and 10MB:
find /path/to/search -size +1M -size -10M
To find files smaller than 1MB:
find /path/to/search -size -1M
Using the -exec Option
The -exec
option in the find
command allows you to execute a command on each file that matches the search criteria. The {}
placeholder is used to represent the current file, and \;
is used to terminate the command.
Examples with -exec
:
To delete all .tmp
files:
find /path/to/search -name "*.tmp" -exec rm {} \;
To change permissions of all .sh
files to executable:
find /path/to/search -name "*.sh" -exec chmod +x {} \;
To move all .log
files to another directory:
find /path/to/search -name "*.log" -exec mv {} /path/to/destination/ \;
To copy all .conf
files to a backup directory:
find /path/to/search -name "*.conf" -exec cp {} /path/to/backup/ \;
To list all .txt
files with detailed information:
find /path/to/search -name "*.txt" -exec ls -l {} \;
Understanding xargs
The xargs
command is used to build and execute command lines from standard input. It is often used in conjunction with find
to handle a large number of files.
Examples with xargs
:
To delete all .tmp
files using find
and xargs
:
find /path/to/search -name "*.tmp" -print | xargs rm
To change permissions of all .sh
files to executable using find
and xargs
:
find /path/to/search -name "*.sh" -print | xargs chmod +x
To move all .log
files to another directory using find
and xargs
:
find /path/to/search -name "*.log" -print | xargs -I {} mv {} /path/to/destination/
To copy all .conf
files to a backup directory using find
and xargs
:
find /path/to/search -name "*.conf" -print | xargs -I {} cp {} /path/to/backup/
To list all .txt
files with detailed information using find
and xargs
:
find /path/to/search -name "*.txt" -print | xargs ls -l
Summary
The locate
and find
commands are essential for searching files and directories in Linux. locate
uses a prebuilt database for fast searches and is ideal for quick lookups. However, it requires the database to be updated regularly. find
is more versatile, allowing for real-time searches based on various criteria, but can be slower. The -exec
option in find
allows executing commands on matched files, and xargs
is a powerful tool to handle large numbers of files efficiently. By mastering these commands and understanding their options, you can efficiently locate and manage files in the Linux environment.
Regular Expressions
Understanding grep
The grep
command, short for "global regular expression print," is a powerful utility used to search text files for lines that match a specified pattern. It reads the file line by line and prints any lines that contain a match. grep
supports regular expressions, which allow for complex and flexible pattern matching. This makes grep
an invaluable tool for searching and analyzing text data in Unix-like systems.
Basic usage of grep
:
grep [options] pattern [file...]
Example: To search for lines containing the word "error" in a file named logfile.txt
:
grep 'error' logfile.txt
What are Regular Expressions?
Regular expressions (regex) are symbolic notations used to identify patterns in text. They enable powerful and flexible text searches, matches, and manipulations. Regular expressions are supported by many command-line tools and programming languages, making them essential for effective text processing.
Basic Regular Expressions (BRE)
Basic Regular Expressions (BRE) are the simpler form of regular expressions, supported by utilities like grep
. BRE uses a limited set of metacharacters and requires some characters to be escaped with a backslash ().
Common Metacharacters in BRE:
Metacharacter | Description | Example | Explanation |
---|---|---|---|
^ |
Matches the start of a line | ^abc |
Matches "abc" at the beginning of a line |
$ |
Matches the end of a line | abc$ |
Matches "abc" at the end of a line |
. |
Matches any single character | a.c |
Matches "abc", "a c", "a-c", etc. |
[] |
Matches any single character within the brackets | [abc] |
Matches "a", "b", or "c" |
* |
Matches zero or more occurrences of the previous character | a* |
Matches "", "a", "aa", "aaa", etc. |
\{n\} |
Matches exactly n occurrences of the previous character | a\{3\} |
Matches "aaa" |
\{n,m\} |
Matches between n and m occurrences of the previous character | a\{2,4\} |
Matches "aa", "aaa", or "aaaa" |
\? |
Matches zero or one occurrence of the previous character | a\? |
Matches "a" or "" |
\+ |
Matches one or more occurrences of the previous character | a\+ |
Matches "a", "aa", "aaa", etc. |
Examples of BRE:
^abc
matches "abc" at the beginning of a line:
echo "abcdef" | grep '^abc'
Output:
abcdef
abc$
matches "abc" at the end of a line:
echo "123abc" | grep 'abc$'
Output:
123abc
a.c
matches any character between "a" and "c":
echo "abc" | grep 'a.c'
Output:
abc
[abc]
matches any single character "a", "b", or "c":
echo "a" | grep '[abc]'
echo "b" | grep '[abc]'
echo "c" | grep '[abc]'
Output:
a
b
c
a*
matches zero or more occurrences of "a":
echo "aaab" | grep 'a*'
Output:
aaab
a\{3\}
matches exactly three occurrences of "a":
echo "aaa" | grep 'a\{3\}'
Output:
aaa
a\{2,4\}
matches between two and four occurrences of "a":
echo "aaa" | grep 'a\{2,4\}'
Output:
aaa
a\?
matches zero or one occurrence of "a":
echo "a" | grep 'a\?'
Output:
a
a\+
matches one or more occurrences of "a":
echo "aaa" | grep 'a\+'
Output:
aaa
Extended Regular Expressions (ERE)
Extended Regular Expressions (ERE) are a more powerful and flexible version of regular expressions. They were developed to address the limitations of BRE by introducing additional metacharacters and operators. ERE does not require escaping for certain characters, making the expressions more readable and easier to write. ERE is supported by utilities like egrep
or grep -E
.
Common Metacharacters in ERE:
Metacharacter | Description | Example | Explanation |
---|---|---|---|
^ |
Matches the start of a line | ^abc |
Matches "abc" at the beginning of a line |
$ |
Matches the end of a line | abc$ |
Matches "abc" at the end of a line |
. |
Matches any single character | a.c |
Matches "abc", "a c", "a-c", etc. |
[] |
Matches any single character within the brackets | [abc] |
Matches "a", "b", or "c" |
* |
Matches zero or more occurrences of the previous character | a* |
Matches "", "a", "aa", "aaa", etc. |
{n} |
Matches exactly n occurrences of the previous character | a{3} |
Matches "aaa" |
{n,m} |
Matches between n and m occurrences of the previous character | a{2,4} |
Matches "aa", "aaa", or "aaaa" |
? |
Matches zero or one occurrence of the previous character | a? |
Matches "a" or "" |
+ |
Matches one or more occurrences of the previous character | a+ |
Matches "a", "aa", "aaa", etc. |
() |
Groups expressions | `(abc | def)` |
Examples of ERE:
^abc
matches "abc" at the beginning of a line:
echo "abcdef" | grep -E '^abc'
Output:
abcdef
abc$
matches "abc" at the end of a line:
echo "123abc" | grep -E 'abc$'
Output:
123abc
a.c
matches any character between "a" and "c":
echo "abc" | grep -E 'a.c'
Output:
abc
[abc]
matches any single character "a", "b", or "c":
echo "a" | grep -E '[abc]'
echo "b" | grep -E '[abc]'
echo "c" | grep -E '[abc]'
Output:
a
b
c
a*
matches zero or more occurrences of "a":
echo "aaab" | grep -E 'a*'
Output:
aaab
a{3}
matches exactly three occurrences of "a":
echo "aaa" | grep -E 'a{3}'
Output:
aaa
a{2,4}
matches between two and four occurrences of "a":
echo "aaa" | grep -E 'a{2,4}'
Output:
aaa
a?
matches zero or one occurrence of "a":
echo "a" | grep -E 'a?'
Output:
a
a+
matches one or more occurrences of "a":
echo "aaa" | grep -E 'a+'
Output:
aaa
a|b
matches either "a" or "b":
echo "a" | grep -E 'a|b'
echo "b" | grep -E 'a|b'
Output:
a
b
(abc|def)
matches "abc" or "def":
echo "abc" | grep -E '(abc|def)'
echo "def" | grep -E '(abc|def)'
Output:
abc
def
Character Classes
Character classes in regular expressions allow you to match specific sets of characters. These sets are predefined and make it easier to work with groups of characters.
Common Character Classes:
Character Class | Description | Example | Explanation |
---|---|---|---|
[:blank:] |
Matches spaces and tabs | grep '[[:blank:]]' |
Matches spaces and tabs in the text |
[:upper:] |
Matches uppercase letters | grep '[[:upper:]]' |
Matches any uppercase letter |
[:lower:] |
Matches lowercase letters | grep '[[:lower:]]' |
Matches any lowercase letter |
[:digit:] |
Matches digits | grep '[[:digit:]]' |
Matches any digit |
[:alpha:] |
Matches alphabetic characters | grep '[[:alpha:]]' |
Matches any alphabetic character |
[:alnum:] |
Matches alphanumeric characters | grep '[[:alnum:]]' |
Matches any alphanumeric character |
[:punct:] |
Matches punctuation characters | grep '[[:punct:]]' |
Matches any punctuation character |
[:space:] |
Matches all whitespace characters | grep '[[:space:]]' |
Matches spaces, tabs, and newlines |
Examples of Character Classes:
To match spaces and tabs using [:blank:]
:
echo "hello world" | grep '[[:blank:]]'
Output:
hello world
To match uppercase letters using [:upper:]
:
echo "Hello World" | grep '[[:upper:]]'
Output:
Hello World
Summary
Regular expressions are a powerful tool for text manipulation in Linux. They allow you to identify patterns in text and perform complex searches and replacements. Basic Regular Expressions (BRE) provide a fundamental set of pattern matching capabilities, while Extended Regular Expressions (ERE) offer more advanced features and flexibility. Character classes, like [:blank:]
and [:upper:]
, further enhance your ability to match specific sets of characters. By understanding and mastering both BRE and ERE, along with character classes, you can significantly enhance your ability to manipulate and analyze text in Unix-like systems.
Chapter 9
cut,paste and join Commands
The cut
, paste
, and join
commands in Unix/Linux are powerful tools for text processing, allowing users to manipulate and merge data from text files efficiently. Each command has its specific functionality and options that make it versatile for various tasks.
cut Command
The cut
command is used to extract sections from each line of input files. It operates by specifying a delimiter and selecting the desired fields or columns of data. The cut
command can also work with fixed-length fields.
Common Options:
Option | Description |
---|---|
-b |
Selects only the bytes specified. |
-c |
Cuts based on character positions. |
-d |
Specifies a delimiter (default is tab). |
-f |
Specifies the fields to be extracted. |
--complement |
Complements the selection. |
--output-delimiter |
Sets the output delimiter for the cut fields. |
Examples:
Suppose file.txt
contains the following lines:
John,Doe,30,Engineer
Jane,Smith,25,Designer
Mike,Johnson,40,Manager
Extracting the first and third fields using a comma as a delimiter:
cut -d ',' -f 1,3 file.txt
Output:
John,30
Jane,25
Mike,40
Extracting the first 5 characters of each line:
cut -c 1-5 file.txt
Output:
John,
Jane,
Mike,
Extracting the first field using a space as a delimiter (assuming fields are space-separated):
cut -d ' ' -f 1 file.txt
Extracting bytes 2 to 6 of each line:
cut -b 2-6 file.txt
Output:
ohn,D
ane,S
ike,J
Extracting all fields except the second using a tab delimiter:
cut -d $'\t' --complement -f 2 file.txt
Note: This example assumes that fields in the file are tab-separated.
paste Command
The paste
command merges lines of files horizontally by outputting lines from each file side by side, separated by a delimiter. This command is useful for combining files where each line corresponds to the same logical row of data.
Common Options:
Option | Description |
---|---|
-d |
Specifies a delimiter to separate pasted lines. |
-s |
Serially paste one file at a time. |
Examples:
Suppose file1.txt
contains:
John
Jane
Mike
And file2.txt
contains:
Doe
Smith
Johnson
Pasting two files side by side with a tab delimiter:
paste file1.txt file2.txt
Output:
John Doe
Jane Smith
Mike Johnson
Suppose file1.txt
contains:
John
Jane
Mike
And file2.txt
contains:
Doe
Smith
Johnson
Pasting files with a comma as the delimiter:
paste -d ',' file1.txt file2.txt
Output:
John,Doe
Jane,Smith
Mike,Johnson
Suppose file1.txt
contains:
John
Jane
Mike
And file2.txt
contains:
Doe
Smith
Johnson
Pasting files with a space as the delimiter:
paste -d ' ' file1.txt file2.txt
Output:
John Doe
Jane Smith
Mike Johnson
Suppose file.txt
contains:
John
Doe
Jane
Smith
Mike
Johnson
Serially pasting lines from a single file:
paste -s file.txt
Output:
John Doe
Jane Smith
Mike Johnson
Suppose file1.txt
contains:
John
Jane
Mike
And file2.txt
contains:
Doe
Smith
Johnson
Pasting files with a custom delimiter:
paste -d '|' file1.txt file2.txt
Output:
John|Doe
Jane|Smith
Mike|Johnson
join Command
The join
command merges lines of two sorted files based on a common field. This command is similar to the SQL join operation, combining records with matching keys.
Common Options:
Option | Description |
---|---|
-1 |
Specifies the field number to join on from the first file. |
-2 |
Specifies the field number to join on from the second file. |
-t |
Specifies a delimiter (default is space). |
-o |
Formats the output. |
-a |
Prints unpairable lines from the specified file. |
-e |
Replaces empty output fields with the specified string. |
Examples:
Suppose file1.txt
contains:
A John
B Jane
C Mike
And file2.txt
contains:
A Doe
B Smith
C Johnson
Joining these files on the first field (default delimiter is space):
join file1.txt file2.txt
Output:
A John Doe
B Jane Smith
C Mike Johnson
Suppose file1.txt
contains:
Alpha,John
Beta,Jane
Gamma,Mike
And file2.txt
contains:
Alpha,Doe
Beta,Smith
Gamma,Johnson
Joining these files on the first field using a comma as the delimiter:
join -t ',' file1.txt file2.txt
Output:
Alpha,John,Doe
Beta,Jane,Smith
Gamma,Mike,Johnson
Suppose file1.txt
contains:
1A John
2B Jane
3C Mike
And file2.txt
contains:
1A Doe
2B Smith
3C Johnson
Joining these files on the first field:
join file1.txt file2.txt
Output:
1A John Doe
2B Jane Smith
3C Mike Johnson
In summary, cut
, paste
, and join
are essential commands for text manipulation in Unix/Linux. They offer a variety of options for extracting, merging, and combining data efficiently, making them invaluable for tasks involving text processing. Understanding these commands and their options enables users to perform complex data manipulations with ease.
comm, diff and patch Commands
comm Command
The comm
command is used to compare two sorted files line by line. It outputs three columns:
- Lines unique to the first file.
- Lines unique to the second file.
- Lines common to both files.
Syntax:
comm [OPTION]... FILE1 FILE2
Common Options:
Option | Description |
---|---|
-1 |
Suppress column 1 (lines unique to FILE1) |
-2 |
Suppress column 2 (lines unique to FILE2) |
-3 |
Suppress column 3 (lines common to both files) |
Example:
file1.txt
:
apple
banana
cherry
file2.txt
:
banana
cherry
date
Command:
comm file1.txt file2.txt
Output:
apple
banana
cherry
date
diff Command
The diff
command is used to compare files line by line. It shows the differences between two files.
Syntax:
diff [OPTION]... FILES
Common Options:
Option | Description |
---|---|
-u |
Output in unified format |
-c |
Output in context format |
-i |
Ignore case differences |
-w |
Ignore all white space |
Example with -c
option:
file1.txt
:
apple
banana
cherry
file2.txt
:
banana
cherry
date
Command:
diff -c file1.txt file2.txt
Output:
*** file1.txt 2024-07-11 10:00:00.000000000 +0000
--- file2.txt 2024-07-11 10:00:00.000000000 +0000
***************
*** 1,3 ****
apple
banana
cherry
--- 1,3 ----
banana
cherry
date
Here's how to interpret it the results shown above:
Header
*** file1.txt 2024-07-11 10:00:00.000000000 +0000
: Refers to the old file (file1.txt
) with its timestamp.--- file2.txt 2024-07-11 10:00:00.000000000 +0000
: Refers to the new file (file2.txt
) with its timestamp.
Change Context
***************
: Indicates the beginning of a change section.*** 1,3 ****
: Refers to lines 1 through 3 infile1.txt
before the change.--- 1,3 ----
: Refers to lines 1 through 3 infile2.txt
after the change.
Content Changes
Lines prefixed with
***
(before change):apple banana cherry
This was the content of lines 1–3 in
file1.txt
.Lines prefixed with
---
(after change):banana cherry date
This is the content of lines 1–3 in
file2.txt
.
Key Observations
Line Removed:
The lineapple
fromfile1.txt
is removed infile2.txt
.Line Added:
The linedate
is added infile2.txt
.
Using diff to create a patch file
You can also create a patch file (to be used later with the patch command) using diff
diff file1 file2 > patchfile
patch Command
The patch
command is used to apply changes to a file. It takes a diff file created by the diff
command and applies those changes to the original file.
Syntax:
patch [OPTION]... [ORIGFILE [PATCHFILE]]
Common Options:
Option | Description |
---|---|
-pNUM |
Strip NUM leading components from file names |
-R |
Reverse the effect of the patch |
-i |
Read patch from file |
-o |
Output to specified file |
Example using diff.patch
:
file1.txt
:
apple
banana
cherry
diff.patch
:
1d0
< apple
3a3
> date
Command:
patch file1.txt diff.patch
Output (file1.txt
after patch):
banana
cherry
date
These commands are very useful for file comparison and manipulation tasks in Linux environments, especially when dealing with text files and source code.
tr, sed and aspell Commands
tr Command
The tr
command in Linux is used for translating or deleting characters from the input provided. It reads from standard input and writes to standard output.
Common Options for tr
:
Option | Description |
---|---|
-d |
Delete characters from the input |
-s |
Squeeze repeated characters into a single character |
-c |
Complement the set of characters |
Examples:
Consider a file example.txt
with the following content:
hello world
hello universe
To convert all lowercase characters to uppercase, you can use:
cat example.txt | tr 'a-z' 'A-Z'
Output:
HELLO WORLD
HELLO UNIVERSE
To delete all vowels from the text:
cat example.txt | tr -d 'aeiou'
Output:
hll wrld
hll nvrse
To change the blank space between two words to a hyphen:
cat example.txt | tr ' ' '-'
Output:
hello-world
hello-universe
To change all blank spaces (including tabs) to a hyphen using [[:blank:]]
:
cat example.txt | tr '[[:blank:]]' '-'
Output:
hello-world
hello-universe
[[:blank:]]
is a character class that matches all horizontal whitespace characters, which include spaces and tabs. This is useful when you want to ensure that all types of horizontal whitespace are replaced.
sed Command
The sed
command, short for stream editor, is used to perform basic text transformations on an input stream (a file or input from a pipeline).
Common Options for sed
:
Option | Description |
---|---|
-e |
Add the script to the commands to be executed |
-f |
Add the script file |
-i |
Edit files in place |
-n |
Suppress automatic printing of pattern space |
Examples:
Consider a file example.txt
with the following content:
hello world
hello hello universe
hello everyone hello
To replace the first occurrence of the word "hello" with "hi" on each line:
sed 's/hello/hi/' example.txt
Output:
hi world
hi hello universe
hi everyone hello
To replace all occurrences of the word "hello" with "hi" using the global /g
option:
sed 's/hello/hi/g' example.txt
Output:
hi world
hi hi universe
hi everyone hi
To delete lines containing the word "everyone":
sed '/everyone/d' example.txt
Output:
hello world
hello hello universe
aspell Command
The aspell
command is a spell-checking utility in Linux. It can be used interactively to check the spelling of a document.
Common Options for aspell
:
Option | Description |
---|---|
-c |
Check a file |
-a |
Run in 'pipe mode' |
-l |
List available dictionaries |
-d |
Use a specific dictionary |
Examples:
Consider a file example.txt
with the following content:
helo wrld
hello everyone
To check the spelling of the file:
aspell check example.txt
Interactive mode will prompt corrections:
@(#) International Ispell Version 3.1.20 (but really Aspell 0.60.8)
& helo 5 0: hello, he lo, halo, help, helot
& wrld 8 0: world, word, weld, wild, wold, wrld's, WRLD, WLRD
To list available dictionaries:
aspell dicts
Output might include:
en
en_GB
en_US
fr
de
...
These commands are essential for text processing and transformation tasks in Linux, providing powerful tools for manipulating and validating text in various ways.
Chapter 10
A Gentle Guid to VIM (alias vi)
The vim
editor is a powerful text editor available in most Unix-like operating systems. To launch vim
, simply type vim
followed by the filename you wish to edit, such as vim myfile.txt
. When you open vim
, it starts in Command mode, which is the default mode. vim
operates in two primary modes: Command mode and Insert mode. Understanding how to switch between these modes is key to effectively using vim
.
In Command mode, you can navigate through the file, delete text, and perform various editing tasks. To switch from Command mode to Insert mode, you can press i
to insert text before the cursor, a
to insert text after the cursor, o
to open a new line below the current line, or O
to open a new line above the current line. For example, if your cursor is on the letter 'h' in "hello" and you press i
, you can start typing before 'h'. If you press a
, you start typing after 'h'. If you press o
, a new line opens below the current line and switches to Insert mode. If you press O
, a new line opens above the current line and switches to Insert mode. Once in Insert mode, you can type text as you normally would. To switch back to Command mode, press the Esc
key.
# Open a file
vim myfile.txt
# Insert text before the cursor
i
# Insert text after the cursor
a
# Open a new line below the current line
o
# Open a new line above the current line
O
# Switch back to Command mode from Insert mode
<Esc>
While in Command mode, basic navigation can be performed using the keys h
, j
, k
, and l
to move the cursor left, down, up, and right respectively. You can also use the arrow keys for navigation (this is much easier). For example, pressing 4j
will move the cursor down four lines. If you want to delete a character under the cursor, press x
. To delete an entire line, use the dd
command. For example, if you want to delete three lines starting from the current line, you can type 3dd
. Copying (or yanking) a line can be done with yy
, and you can paste it below the current line by pressing p
. For example, 3yy
will yank (copy) three lines, and p
will paste them below the cursor. If you make a mistake, you can undo your last change by pressing u
. To save (write) your changes to the file, use :w
, and to quit vim
, use :q
. If you want to save and quit simultaneously, you can use :wq
or the shortcut ZZ
.
# Move the cursor down four lines
4j
# Delete the character under the cursor
x
# Delete three lines starting from the current line
3dd
# Yank (copy) three lines
3yy
# Paste the copied lines below the cursor
p
# Undo the last change
u
To save your changes to the file, use the :w
command. To save and quit vim
simultaneously, you can use :wq
or the shortcut ZZ
. If you want to quit without saving, use :q!
.
# Save the file
:w
# Save and quit vim
:wq
# Save and quit vim (alternative)
ZZ
# Quit without saving
:q!
For more advanced navigation, vim
offers commands like gg
to go to the beginning of the file and G
to go to the end. You can go to a specific line by typing nG
, where n
is the line number. For example, 10G
takes you to line 10. Moving to the beginning of the current line can be done with 0
, and moving to the end of the line can be done with $
.
# Go to the beginning of the file
gg
# Go to the end of the file
G
# Go to line 10
10G
# Move to the beginning of the current line
0
# Move to the end of the current line
$
Editing in vim
can be very efficient with commands like r
to replace a character, cw
to change a word, and dw
to delete a word. For instance, if the cursor is on the letter 'h' in "hello" and you press rj
, the 'h' will be replaced with 'j', resulting in "jello". Using cw
on "hello" allows you to change the entire word, for example to "world", by typing cw world
. Using dw
will delete from the cursor position to the end of the current word. You can also select text visually by pressing v
and then moving the cursor to highlight the desired text. This selected text can be deleted, copied, or changed using d
, y
, or c
followed by a movement command. For example, d$
will delete from the cursor to the end of the line, and y2w
will yank (copy) two words.
# Replace the character under the cursor with 'j'
rj
# Change the word under the cursor to 'world'
cw world
# Delete from the cursor to the end of the word
dw
# Start visual mode to select text
v
# Delete from the cursor to the end of the line
d$
# Yank (copy) two words
y2w
Searching within vim
is straightforward. To search forward for a pattern, use /pattern
, and to search backward, use ?pattern
. For example, /hello
searches forward for the word "hello" and ?hello
searches backward. After performing a search, pressing n
will repeat the search in the same direction, while pressing N
will repeat it in the opposite direction.
# Search forward for 'hello'
/hello
# Search backward for 'hello'
?hello
# Repeat the search in the same direction
n
# Repeat the search in the opposite direction
N
When you are ready to exit vim
, you have a few options. To quit without saving, use :q!
. To save your changes and quit, use :wq
or the shortcut ZZ
, which performs the same function.
# Quit without saving
:q!
# Save and quit vim
:wq
# Save and quit vim (alternative)
ZZ
Practicing these commands will help you become proficient with vim
. Remember that pressing Esc
always returns you to Command mode, which is a useful fallback if you ever feel lost. As you get more comfortable, you can explore vim
's more advanced features, but mastering these basics will provide a solid foundation for effective text editing with vim
.
Working With Multiple Files in Vim
When working with multiple files in Vim, you can use buffers to keep several files open at once, while also taking advantage of split screens to view and edit files side by side. Let’s walk through how these tools make it easier to manage multiple files.
To start, you can open multiple files in Vim by listing them when you launch it. For example, to open file1.txt
and file2.txt
, type this at the command line:
vim file1.txt file2.txt
This command opens both files, each in a separate buffer. A buffer is where Vim stores each open file in memory, allowing you to switch between files easily. To move between buffers, use the :buffer
command followed by the buffer number. For example, if you’re viewing file1.txt
and want to switch to file2.txt
, type:
:buffer 2
You can find buffer numbers by typing:
:ls
The :ls
command shows a list of all open buffers, making it easy to see which files are available and their corresponding buffer numbers.
To open a new file in a buffer while in Vim, use:
:e file3.txt
This loads file3.txt
into a new buffer, which you can access with :buffer
commands or open in a new split screen if you want to view it alongside other files.
When you’re done with a file, you can close its buffer with the command:
:bd
This closes the buffer of the file you’re currently viewing. You can also delete a specific buffer by its number, like this:
:bd 2
You can also move forward and backward between bufferes with the :bn
(next buffer) and :bp
(previous buffer) commands.
If you want to view files side by side, you can use split screens. To open another file in a split screen, use the following command:
:split file2.txt
This command splits the window horizontally, placing file2.txt
above or below file1.txt
. To split vertically, you can use:
:vsplit file2.txt
Now, file1.txt
will be on the left and file2.txt
on the right. You can navigate between these split windows by pressing Ctrl + w
and then using the arrow keys. For example, Ctrl + w
followed by the right arrow key will move your cursor to the window on the right. This way, you can view and edit two files at the same time.
To close the split window where your cursor is currently active, use:
:q
This will close the current split. If there are unsaved changes, Vim will prompt you to save or discard them.
If you want to keep only the current split open and close all other splits, use:
:only
This command closes all other splits except the one you are currently working in, bringing you back to a single window view.
To force-close a split without saving any changes, use:
:q!
This will close the split immediately, discarding any changes.
These commands let you easily manage split screens in Vim and return to a single screen setup.
Using buffers and split screens allows you to handle multiple files efficiently in Vim. You can open files, switch between them with buffers, and view them side by side with split screens, giving you all the flexibility you need for multitasking on your files.
Table of popular vim Commands
Command | Description |
---|---|
vim myfile.txt |
Open a file |
i |
Insert text before the cursor (Insert mode) |
a |
Insert text after the cursor (Insert mode) |
o |
Open a new line below the current line (Insert mode) |
O |
Open a new line above the current line (Insert mode) |
<Esc> |
Switch back to Command mode |
h , j , k , l |
Move cursor left, down, up, right (also arrow keys) |
4j |
Move cursor down four lines |
x |
Delete character under the cursor |
3dd |
Delete three lines starting from the current line |
3yy |
Yank (copy) three lines |
p |
Paste copied lines below the cursor |
u |
Undo the last change |
:w |
Save the file |
:wq |
Save and quit vim |
ZZ |
Save and quit vim (alternative) |
:q! |
Quit without saving |
gg |
Go to the beginning of the file |
G |
Go to the end of the file |
10G |
Go to line 10 |
0 |
Move to the beginning of the current line |
$ |
Move to the end of the current line |
rj |
Replace the character under the cursor with 'j' |
cw world |
Change the word under the cursor to 'world' |
dw |
Delete from the cursor to the end of the word |
v |
Start visual mode to select text |
d$ |
Delete from the cursor to the end of the line |
y2w |
Yank (copy) two words |
/hello |
Search forward for 'hello' |
?hello |
Search backward for 'hello' |
n |
Repeat the search in the same direction |
N |
Repeat the search in the opposite direction |
Other vim commands that help with how vim appears
Command | Description |
---|---|
:set nu |
Set line numbers |
:set nonu |
Remove line numbers |
:colorscheme ctrl-d |
Colorscheme space then ctrl-d. This will provide a list of colorschemes |
:colorscheme color |
Colorscheme space then theme color. This will switch the color scheme to the color you entered |
:!bash % |
Run the current bash script in vim |
:noh |
Clear highlighting |
Creating a Bash Script, Comments, Variables and Read
A Bash script is a file containing a series of commands that are executed by the Bash shell, a popular command-line interpreter in Unix-like operating systems. These scripts are used to automate tasks, manage system operations, and perform complex sequences of commands with a single execution.
Writing a Simple Bash Script
Creating a Bash script involves writing commands in a plain text file and then executing the file. Here's an example of a simple Bash script that prints "Hello, World!" to the console:
-
Open a text editor and write the following lines:
#!/bin/bash # This is a comment echo "Hello, World!"
- The
#!/bin/bash
at the top is called a shebang. It tells the system to use the Bash interpreter to execute the script. - The
echo
command prints text to the terminal. - The line starting with
#
is a comment, which is ignored by the shell and used to add explanations or notes.
- The
-
Save the file with a
.sh
extension, for example,hello_world.sh
.
Changing Script Permissions
Before running the script, you need to change its permissions to make it executable. This can be done using the
chmod
command:
chmod 700 hello_world.sh
The 700
permission means that the file's owner has read, write, and execute permissions, while no
one else has any permissions. This ensures that only the creator can run the script.
Running a Bash Script
To run the script, navigate to the directory where the script is saved and use one of the following methods:
-
Using
./
:./hello_world.sh
The
./
indicates that the script is located in the current directory. -
Using
bash
:bash hello_world.sh
This explicitly uses the Bash interpreter to run the script.
-
Using the full path:
/path/to/your/script/hello_world.sh
This method runs the script by specifying its full path.
Comments in Bash Scripts
Comments in Bash scripts are lines that begin with #
. They are not executed by the shell and are used to
add descriptions, explanations, or notes within the script. Comments are useful for:
- Documenting what the script does.
- Explaining the purpose of specific commands or sections of the script.
- Making the script easier to understand and maintain.
For example:
#!/bin/bash
# This script prints a greeting message
echo "Hello, World!" # This line prints "Hello, World!"
Variables in Bash Scripts
Variables in Bash scripts are used to store data that can be referenced and manipulated throughout the script.
Variables make scripts more flexible and easier to manage. You can assign a value to a variable using the
=
operator and access its value by prefixing the variable name with a $
sign. The
$
sign is necessary to differentiate the variable's value from the variable's name.
IMPORTANT NOTE: Variable names need to be repesentative of the data. For example, you would using the variable firstName
to contain someones first name. Also variables in bash scripting (unless you use other libraries) contain strings which is any text within double quotes, like firstName="Scott"
. Or numbers which is just a whole number like num=43
. Finally, variable names cannot contain spaces. For example, the variable first name
must be written as first_name
or using camel case like firstName
where the first letter of each word is capitalized.
For example:
#!/bin/bash
# This script uses a variable to print a message
greeting="Hello, World!"
echo $greeting
In this script:
greeting
is a variable that stores the string "Hello, World!".echo $greeting
prints the value of thegreeting
variable to the console.
Without the $
sign, the shell would interpret greeting
as a literal string rather than the
variable's value.
Using read Command
The read
command in Linux is a simple and powerful way to get input from a user in a script. When you use read
, the command waits for the user to type something and press Enter
, and then it stores that input in a variable you can use in the rest of your script. This is especially useful in interactive scripts where you need the user’s input to make decisions or perform actions.
Let’s look at a basic example of how read
works. Suppose you want to ask the user for their name and then greet them:
echo "What is your name?"
read name
echo "Hello, $name!"
In this script:
echo "What is your name?"
displays the question to the user.read name
waits for the user to type their name and pressEnter
. The input is stored in a variable calledname
.echo "Hello, $name!"
prints a greeting that includes the user’s name.
When the script runs, the user will see “What is your name?” on the screen. They can type their name, and the script will respond with “Hello, [name]!” where [name]
is whatever they typed.
The read
command can also handle multiple pieces of input. For example, if you want to ask for both a first and last name, you can do this:
echo "Enter your first and last name:"
read first last
echo "Hello, $first $last!"
Here, read first last
allows the user to type both their first and last name separated by a space. The first word they type goes into the first
variable, and the second word goes into the last
variable.
You can also use options with read
to make it more useful. For example, the -p
option lets you display a prompt on the same line as the read
command, and the -s
option hides the user’s input, which is helpful for passwords:
read -p "Enter your username: " username
read -sp "Enter your password: " password
echo
echo "Username: $username, Password: [hidden]"
In this example:
-p "Enter your username: "
displays the prompt on the same line.-s
hides the user’s input forpassword
.- The
echo
command after theread
forpassword
is there to move to a new line after the hidden input.
The read
command makes scripts interactive and lets users provide the information you need, allowing for dynamic and responsive scripts. It’s an essential command for adding interactivity to your Linux scripts!
Understanding /bin and Adding to PATH
The /bin
directory (short for "binary") is one of the standard directories in Unix-like
systems where essential command binaries are stored. You should have a bin directory in your home directory, if not, you can create one. If you put your scripts in the bin directory you can call them but just entering the script by name (no need for ./
or bash
or a full path). To run scripts or commands from any directory you can add their directory to the system's PATH
environment variable. This allows the system to locate the executable files in the specified directories.
To add a directory to your PATH
, you can modify your shell configuration file, such as
.bashrc
or .bash_profile
. Here’s how you can add a custom directory (e.g.,
~/scripts
) to your PATH
:
-
Open your shell configuration file in a text editor:
vim ~/.bashrc
-
Add the following line at the end of the file:
export PATH="$PATH:~/scripts"
-
Save the file and reload the configuration:
source ~/.bashrc
Now, any executable files in the ~/scripts
directory can be run from any location in the terminal.
Summary
A Bash script is a powerful tool for automating tasks in Unix-like operating systems. Writing a script involves
creating a text file with a series of commands, changing its permissions to make it executable, and using comments
to document the script. Variables in Bash scripts allow you to store and manipulate data, making your scripts more
flexible and maintainable. To run a script, you can use the ./
notation, the bash
command,
or the full path. Adding directories to the PATH
environment variable enables you to run scripts and
commands from any location without specifying their full path. By understanding these fundamental concepts, you can
create efficient and effective Bash scripts to streamline your workflow.
Chapter 11
Bash Functions
Syntax Variations
Without parentheses:
function_name {
# Commands
}
With parentheses:
function_name() {
# Commands
}
Differences and Similarities
Function Keyword (Optional):
In some variations, you might see the function
keyword used to define a function. This is optional and generally not necessary in modern Bash scripting. However, when using the function
keyword, the parentheses are typically omitted:
function function_name {
# Commands
}
Parentheses:
The use of parentheses ()
is optional in Bash. They are commonly used for clarity and readability to explicitly indicate a function definition. Function definitions with parentheses are more common and align with the style of many other programming languages, making the script easier to understand for people with experience in those languages.
POSIX Compliance:
The syntax function_name() { ... }
is more aligned with POSIX standards and is preferred for writing scripts intended to be portable across different Unix-like systems. The function
keyword is not POSIX-compliant and is specific to Bash and some other shells like Zsh and Ksh.
Variable Scope:
There is no difference in how variables are scoped within the function based on the syntax used to define the function. Both styles allow the use of local variables within the function using the local
keyword.
Here's a simple example of a function that prints a greeting message:
#!/bin/bash
# Define a function
greet() {
echo "Hello, World!"
}
# Call the function
greet
In this script, the greet
function is defined to print "Hello, World!" and is then called to execute its commands. Note that functions in Bash can be defined with or without parentheses. The use of parentheses is a common convention to clearly indicate the function definition, although they are not strictly necessary if no parameters are being passed.
Returning Values from Functions
Bash functions can return status codes using the return
command. The return value is an integer between 0 and 255, where 0
typically signifies success, and any non-zero value indicates an error. Bash functions cannot return string or numeric values directly using return
. Instead, you can use echo or variable assignment to get these values out of a function.
Here’s an example of a function that returns a status code:
#!/bin/bash
# Define a function that checks if a number is positive
is_positive() {
if [ $1 -gt 0 ]; then
return 0 # Success
else
return 1 # Failure
fi
}
# Call the function with a number
is_positive 5
status=$?
if [ $status -eq 0 ]; then
echo "The number is positive."
else
echo "The number is not positive."
fi
In this script, the is_positive
function checks if a given number (passed as an argument) is positive. The function returns 0
if the number is positive and 1
otherwise. The return status is captured in the $?
variable and used to print an appropriate message.
Scoping in Bash Functions
Variables in Bash have a global scope by default, meaning they are accessible throughout the script, including inside functions. To create local variables within a function, you can use the local
keyword. Local variables are only accessible within the function where they are defined.
Here’s an example demonstrating variable scoping:
#!/bin/bash
# Global variable
message="Hello, World!"
# Define a function
print_message() {
local message="Hello, Local World!"
echo $message
}
# Call the function
print_message
# Print the global variable
echo $message
In this script:
- The global variable
message
is defined and initialized with "Hello, World!". - The
print_message
function defines a local variablemessage
with the value "Hello, Local World!". - Inside the function, the local variable is printed.
- Outside the function, the global variable is printed, showing that the local variable did not affect it.
Passing Arguments to Functions
Functions in Bash can accept arguments. These arguments are accessed using positional parameters $1
, $2
, and so on, within the function.
Here’s an example of a function that takes arguments:
#!/bin/bash
# Define a function that prints a greeting message
greet() {
echo "Hello, $1!"
}
# Call the function with an argument
greet "Alice"
In this script, the greet
function takes one argument and prints a greeting message using that argument. When calling the function with "Alice"
as the argument, it prints "Hello, Alice!".
Here is another example that takes multiple arguments. The arguments are in order so $1 = 5, $2 = 2 and $3 = 6
add(){
echo "The numbers added together are $(($1 + $2 + $3))"
}
add 5 2 6
If you don't have the correct number of arguments you will get an error. The code below would generate an error.
add(){
echo "The numbers added together are $(($1 + $2 + $3))"
}
add 5 2
If you use a number character in string bash will infer that it is a number. The code below will generate 12 as the answer.
add(){
echo "The numbers added together are $(($1 + $2 + $3))"
}
add 5 2 "5"
If you add a alpha string it will just omit it. Here it returns 7 because it does not know what to do with "scott"
add(){
echo "The numbers added together are $(($1 + $2 + $3))"
}
add 5 2 "scott"
Summary
Functions in Bash scripts are powerful tools that help organize and reuse code. They can accept arguments, return status codes, and have local variable scopes. By using functions, you can create more modular and maintainable scripts. Understanding how to define, call, and manage functions is essential for efficient Bash scripting. Functions help break down complex tasks into simpler parts, making scripts easier to read, debug, and maintain.
if, elif Statements
In Bash scripting, if
statements are used to test conditions and make decisions based on the results. They help control the flow of execution in a script.
Basic if Statement
A basic if
statement in Bash follows this syntax:
if [ condition ]; then
# Commands to execute if condition is true
fi
Example:
#!/bin/bash
number=5
if [ $number -gt 3 ]; then
echo "The number is greater than 3"
fi
In this example, the script checks if the variable number
is greater than 3 and prints a message if the condition is true.
if-else Statement
An if-else
statement allows you to execute different commands based on whether the condition is true or false.
if [ condition ]; then
# Commands to execute if condition is true
else
# Commands to execute if condition is false
fi
Example:
#!/bin/bash
number=2
if [ $number -gt 3 ]; then
echo "The number is greater than 3"
else
echo "The number is not greater than 3"
fi
In this example, the script prints a different message based on whether the number
is greater than 3.
Multiple if-else Statements (elif)
You can use multiple if-else
statements to test several conditions.
if [ condition1 ]; then
# Commands to execute if condition1 is true
elif [ condition2 ]; then
# Commands to execute if condition2 is true
else
# Commands to execute if neither condition1 nor condition2 is true
fi
Example:
#!/bin/bash
number=3
if [ $number -gt 3 ]; then
echo "The number is greater than 3"
elif [ $number -eq 3 ]; then
echo "The number is equal to 3"
else
echo "The number is less than 3"
fi
In this example, the script checks multiple conditions and prints the appropriate message based on the value of number
.
Nested if-else Statements
Nested if-else
statements are if-else
statements within another if-else
statement.
Example:
#!/bin/bash
number=4
if [ $number -gt 0 ]; then
if [ $number -lt 10 ]; then
echo "The number is between 1 and 9"
else
echo "The number is 10 or greater"
fi
else
echo "The number is zero or negative"
fi
In this example, the script first checks if the number
is greater than 0. If true, it then checks if the number
is less than 10 and prints the appropriate message based on the nested conditions.
Comparisons in Bash
In Bash, you can use various comparison operators to test conditions.
Equality (==
):
if [ "$str1" == "$str2" ]; then
echo "Strings are equal"
fi
Regex Match (=~
):
if [[ "$str" =~ ^[0-9]+$ ]]; then
echo "String contains only digits"
fi
Inequality (!=
):
if [ "$str1" != "$str2" ]; then
echo "Strings are not equal"
fi
Numeric Comparisons:
Greater than (-gt
):
if [ $num1 -gt $num2 ]; then
echo "$num1 is greater than $num2"
fi
Less than (-lt
):
if [ $num1 -lt $num2 ]; then
echo "$num1 is less than $num2"
fi
Greater than or equal to (-ge
):
if [ $num1 -ge $num2 ]; then
echo "$num1 is greater than or equal to $num2"
fi
Less than or equal to (-le
):
if [ $num1 -le $num2 ]; then
echo "$num1 is less than or equal to $num2"
fi
Equal to (-eq
):
if [ $num1 -eq $num2 ]; then
echo "$num1 is equal to $num2"
fi
Not equal to (-ne
):
if [ $num1 -ne $num2 ]; then
echo "$num1 is not equal to $num2"
fi
Checks if a file exits using (-f
). If so then outputs the contents, if not then says "No file found".
if [ -f file.txt ]; then
echo "File contents:"
cat file.txt
else
echo "No file found."
fi
Logical Operators
You can also use logical operators to combine multiple conditions.
AND (&&
):
if [ $num -gt 0 ] && [ $num -lt 10 ]; then
echo "The number is between 1 and 9"
fi
OR (||
):
if [ $num -eq 0 ] || [ $num -eq 10 ]; then
echo "The number is 0 or 10"
fi
String Comparisons
String comparisons in Bash can also be performed using various operators:
Check if a string is empty (-z
):
if [ -z "$str" ]; then
echo "String is empty"
fi
Check if a string is not empty (-n
):
if [ -n "$str" ]; then
echo "String is not empty"
fi
Check if a string starts with a specific substring:
if [[ "$str" == prefix* ]]; then
echo "String starts with 'prefix'"
fi
Comparison Operators Table
Comparison | Operator | Example | Description |
---|---|---|---|
Equality | == |
[ "$str1" == "$str2" ] |
Strings are equal |
Regex Match | =~ |
[[ "$str" =~ ^[0-9]+$ ]] |
String matches regex |
Inequality | != |
[ "$str1" != "$str2" ] |
Strings are not equal |
Numeric Greater | -gt |
[ $num1 -gt $num2 ] |
num1 is greater than num2 |
Numeric Less | -lt |
[ $num1 -lt $num2 ] |
num1 is less than num2 |
Numeric Greater or Equal | -ge |
[ $num1 -ge $num2 ] |
num1 is greater than or equal to num2 |
Numeric Less or Equal | -le |
[ $num1 -le $num2 ] |
num1 is less than or equal to num2 |
Numeric Equal | -eq |
[ $num1 -eq $num2 ] |
num1 is equal to num2 |
Numeric Not Equal | -ne |
[ $num1 -ne $num2 ] |
num1 is not equal to num2 |
String Empty | -z |
[ -z "$str" ] |
String is empty |
String Not Empty | -n |
[ -n "$str" ] |
String is not empty |
String Starts With | == prefix* |
[[ "$str" == prefix* ]] |
String starts with 'prefix' |
Checks if file exits | -f |
[[ -f file.txt ]] |
Checks if file.txt exits |
Logical AND | && |
[ $num -gt 0 ] && [ $num -lt 10 ] |
Both conditions are true |
Logical OR | || |
[ $num -gt 10 ] || [ $num -lt 5 ] |
Only one condition needs to be true for this condtion to evaluate as true |
Summary
Bash provides powerful constructs to handle conditional execution using if
, if-else
, and nested if-else
statements. Various comparison operators like ==
, =~
, !=
, -gt
, -lt
, and logical operators &&
and ||
help in forming complex conditions. Understanding these constructs and operators allows you to write more efficient and readable Bash scripts.
Chapter 12
Loops
In Bash scripting, loops are used to repeat a series of commands until a specific condition is met. There are several types of loops available in Bash: for
, while
, and until
loops. These loops can also contain if-else
statements to add conditional logic within the loop.
for Loop
A for
loop iterates over a list of items and executes a block of code for each item.
Syntax:
for var in list; do
# Commands
done
Example:
#!/bin/bash
for num in 1 2 3 4 5; do
echo "Number: $num"
done
This script iterates over the numbers 1 to 5 and prints each number.
while Loop
A while
loop executes a block of code as long as the specified condition is true.
Syntax:
while [ condition ]; do
# Commands
done
Example:
#!/bin/bash
count=1
while [ $count -le 5 ]; do
echo "Count: $count"
count=$((count + 1))
done
This script prints the count from 1 to 5.
until Loop
An until
loop is similar to a while
loop but executes the block of code as long as the specified condition is false.
Syntax:
until [ condition ]; do
# Commands
done
Example:
#!/bin/bash
count=1
until [ $count -gt 5 ]; do
echo "Count: $count"
count=$((count + 1))
done
This script prints the count from 1 to 5, stopping when the count is greater than 5.
Nesting if-else
Statements in Loops
You can nest if-else
statements within loops to add conditional logic to your loops.
Example with for
Loop:
#!/bin/bash
for num in 1 2 3 4 5; do
if [ $num -eq 3 ]; then
echo "Found three!"
else
echo "Number: $num"
fi
done
In this script, the for
loop iterates over the numbers 1 to 5. When the number is equal to 3, it prints "Found three!" Otherwise, it prints the number.
Example with while
Loop:
#!/bin/bash
count=1
while [ $count -le 5 ]; do
if [ $count -eq 3 ]; then
echo "Found three!"
else
echo "Count: $count"
fi
count=$((count + 1))
done
This script prints the count from 1 to 5. When the count is equal to 3, it prints "Found three!" Otherwise, it prints the count.
Example with until
Loop:
#!/bin/bash
count=1
until [ $count -gt 5 ]; do
if [ $count -eq 3 ]; then
echo "Found three!"
else
echo "Count: $count"
fi
count=$((count + 1))
done
This script prints the count from 1 to 5, stopping when the count is greater than 5. When the count is equal to 3, it prints "Found three!" Otherwise, it prints the count.
Nested Loops
You can also nest loops within other loops to perform more complex iterations.
Example:
#!/bin/bash
for i in 1 2 3; do
for j in a b c; do
echo "Combination: $i$j"
done
done
This script prints all combinations of numbers 1 to 3 with letters a to c.
Summary
Bash provides various looping constructs like for
, while
, and until
loops to perform repetitive tasks efficiently. These loops can be enhanced with nested if-else
statements to introduce conditional logic within the loops. Understanding how to use these loops and conditional statements allows you to write more complex and dynamic Bash scripts.
Arrays
Arrays in Bash scripting are a powerful way to store and manage multiple pieces of related data. Think of an array as a collection of items, like a list of favorite songs or the names of your friends. Each item in the array has a specific position or "index" that lets you access it quickly. In Bash, arrays are easy to create and work with, and they can store strings, numbers, or a combination of both.
To create an array in Bash, you simply assign values using parentheses. For example, let’s create an array of fruits:
fruits=("apple" "banana" "cherry" "date")
In this example, the array fruits
contains four items. The first item is "apple," the second is "banana," and so on. In programming, arrays are zero-indexed, which means the first item is at position 0, the second at position 1, and so forth. So, if we want to access "banana," we would use index 1, like this:
echo ${fruits[1]}
This command will output "banana." You can access any element in an array by using the array name followed by the index in square brackets, with a dollar sign before it.
You can also change an item in the array by specifying its index and giving it a new value. Suppose we want to change "date" to "dragonfruit." We’d do it like this:
fruits[3]="dragonfruit"
Now, if we print the entire array, "date" is replaced with "dragonfruit." To print all the items in an array at once, use the following command:
echo ${fruits[@]}
This will print out all the items: "apple banana cherry dragonfruit." The [@]
symbol lets Bash know we want to access all elements.
Sometimes, you’ll need to know the total number of items in an array. Bash provides an easy way to do this by using ${#arrayname[@]}
. For example:
echo ${#fruits[@]}
This command will output 4
, showing there are four items in the fruits
array.
Finally, you might want to loop through each item in an array to process them one by one. You can do this with a for
loop like so:
for fruit in "${fruits[@]}"
do
echo "I love $fruit"
done
This loop goes through each item in the fruits
array and prints out "I love apple," "I love banana," and so on. Loops like this are handy when you want to perform the same action on each item in an array.
Arrays in Bash make it easy to handle lists of related data, and as you practice, you’ll find they can help simplify and organize your scripts.
Chapter 13
Strings and Numbers
Computer programs are all about working with data. In past chapters, we have focused on processing data at the file level. However, many programming problems need to be solved using smaller units of data such as strings and numbers. In this chapter, we will look at several shell features used to manipulate strings and numbers. The shell provides a variety of parameter expansions that perform string operations.
Parameter Expansion
Though parameter expansion came up earlier in this course, we did not cover it in detail because most parameter expansions are used in scripts rather than on the command line. We have already worked with some forms of parameter expansion, such as shell variables. The shell provides many more. It's always good practice to enclose parameter expansions in double quotes to prevent unwanted word splitting, unless there is a specific reason not to. This is especially true when dealing with filenames, as they can often include embedded spaces and other assorted nastiness.
Basic Parameters
The simplest form of parameter expansion is reflected in the ordinary use of variables. For example, $a
becomes whatever the variable a
contains when expanded. Simple parameters may also be surrounded by
braces, as in ${a}
. This has no effect on the expansion but is required if the variable is adjacent to
other text, which may confuse the shell. For example, attempting to create a filename by appending the string
_file
to the contents of the variable a
will result in nothing because the shell will try
to expand a variable named a_file
rather than a
. This problem can be solved by adding
braces around the “real” variable name, as in ${a}_file
.
Example:
a="foo"
echo "$a_file" # Outputs nothing because it looks for a variable named a_file
echo "${a}_file" # Outputs foo_file
Expansions to Manage Empty Variables
Several parameter expansions are intended to deal with nonexistent and empty variables. These expansions are handy for handling missing positional parameters and assigning default values to parameters.
${parameter:-word}
: Results in the value ofword
ifparameter
is unset or empty. Ifparameter
is not empty, the expansion results in the value ofparameter
.
Example:
foo=
echo ${foo:-"substitute value if unset"} # Outputs "substitute value if unset"
foo=bar
echo ${foo:-"substitute value if unset"} # Outputs "bar"
${parameter:=word}
: Results in the value ofword
ifparameter
is unset or empty and also assignsword
toparameter
. Ifparameter
is not empty, the expansion results in the value ofparameter
.
Example:
foo=
echo ${foo:="default value if unset"} # Outputs "default value if unset" and assigns it to foo
echo $foo # Outputs "default value if unset"
foo=bar
echo ${foo:="default value if unset"} # Outputs "bar"
${parameter:?word}
: Causes the script to exit with an error ifparameter
is unset or empty, sending the contents ofword
to standard error.
Example:
foo=
echo ${foo:?"parameter is empty"} # Outputs an error message and exits
foo=bar
echo ${foo:?"parameter is empty"} # Outputs "bar"
${parameter:+word}
: Results in nothing ifparameter
is unset or empty, but substitutes the value ofword
ifparameter
is not empty.
Example:
foo=
echo ${foo:+"substitute value if set"} # Outputs nothing
foo=bar
echo ${foo:+"substitute value if set"} # Outputs "substitute value if set"
Expansions That Return Variable Names
The shell can return the names of variables in some situations. For example, ${!prefix*}
and
${!prefix@}
return the names of existing variables with names beginning with prefix
. Both
forms perform identically.
Example:
echo ${!BASH*} # Outputs names of all variables starting with "BASH"
String Operations
There is a large set of expansions that can be used to operate on strings. Many of these expansions are particularly well suited for operations on pathnames.
${#parameter}
: Expands into the length of the string contained byparameter
.
Example:
foo="This string is long."
echo "'$foo' is ${#foo} characters long." # Outputs "'This string is long.' is 20 characters long."
${parameter:offset}
and${parameter:offset:length}
: Used to extract portions of the string contained inparameter
, starting atoffset
characters from the beginning and continuing to the end of the string, unlesslength
is specified.
Example:
foo="This string is long."
echo ${foo:5} # Outputs "string is long."
echo ${foo:5:6} # Outputs "string"
${parameter#pattern}
and${parameter##pattern}
: Remove a leading portion of the string contained inparameter
defined bypattern
, with the former removing the shortest match and the latter removing the longest match.
Example:
foo=file.txt.zip
echo ${foo#*.} # Outputs "txt.zip"
echo ${foo##*.} # Outputs "zip"
${parameter%pattern}
and${parameter%%pattern}
: Remove text from the end of the string contained inparameter
.
Example:
foo=file.txt.zip
echo ${foo%.*} # Outputs "file.txt"
echo ${foo%%.*} # Outputs "file"
${parameter/pattern/string}
: Performs a search-and-replace operation on the contents ofparameter
. In the normal form, only the first occurrence ofpattern
is replaced, while the//
form replaces all occurrences.
Example:
foo=JPG.JPG
echo ${foo/JPG/jpg} # Outputs "jpg.JPG"
echo ${foo//JPG/jpg} # Outputs "jpg.jpg"
echo ${foo/#JPG/jpg} # Outputs "jpg.JPG"
echo ${foo/%JPG/jpg} # Outputs "JPG.jpg"
Case Conversion
Bash supports the uppercase/lowercase conversion of strings with four parameter expansions and two declare command
options. These conversions are useful for normalizing user input for database lookups, ensuring consistent data
entry. For example, ${parameter,,}
converts all characters in parameter
to lowercase,
${parameter,}
changes only the first character to lowercase, ${parameter^^}
converts all
characters to uppercase, and ${parameter^}
changes only the first character to uppercase.
Example:
foo="aBc"
echo "${foo,,}" # Outputs "abc"
echo "${foo,}" # Outputs "aBc"
echo "${foo^^}" # Outputs "ABC"
echo "${foo^}" # Outputs "ABc"
Arithmetic Evaluation and Expansion
Arithmetic expansion allows performing various arithmetic operations on integers using the basic form
$((expression))
. The shell supports integer constants in different bases, such as decimal, octal, and
hexadecimal. Unary operators, simple arithmetic operators, and more complex assignment operators provide convenient
shorthand for arithmetic tasks. Notably, the increment (++
) and decrement (--
) operators,
derived from the C programming language, increase or decrease the value of their parameters by one, with a subtle
difference between prefix and postfix usage.
Example:
echo $((2 + 3)) # Outputs "5"
echo $((5 / 2)) # Outputs "2" (integer division)
echo $((5 % 2)) # Outputs "1" (modulo operation)
foo=1
echo $((foo++)) # Outputs "1", then foo becomes 2
echo $foo # Outputs "2"
echo $((++foo)) # Outputs "3"
Bit Operations
Bit operators manipulate numbers at the bit level, often for setting or reading bit-flags. These include bitwise
negation (~
), left and right bitwise shifts (<<
and >>
), and
bitwise AND, OR, and XOR (&
, |
, ^
). Corresponding assignment operators,
such as <<=
, exist for all but bitwise negation.
Example:
echo $((1 << 2)) # Outputs "4" (1 shifted left by 2 bits)
echo $((4 >> 1)) # Outputs "2" (4 shifted right by 1 bit)
Logic and Comparison Operators
The (( ))
compound command supports a variety of comparison operators, including less than
(<
), greater than (>
), equal to (==
), not equal to (!=
),
logical AND (&&
), and logical OR (||
). The ternary operator
(expr1?expr2:expr3
) performs a stand-alone logical test, acting as a compact if/then/else statement.
Example:
a=0
((a < 1 ? ++a : --a))
echo $a # Outputs "1"
((a < 1 ? ++a : --a))
echo $a # Outputs "0"
Practical Example
To demonstrate the efficiency of parameter expansion, we modified the longest-word script from the previous chapter
to use ${#j}
in place of `$(echo -n $j
| wc -c)`, resulting in a significant performance improvement. The original script took 3.618 seconds to scan the text file, while the new version using parameter expansion took only 0.06 seconds.
#!/bin/bash
# longest-word3: find longest string in a file
for i; do
if [[ -r "$i" ]]; then
max_word=
max_len=0
for j in $(strings $i); do
len="${#j}"
if (( len > max_len )); then
max_len="$len"
max_word="$j"
fi
done
echo "$i: '$max_word' ($max_len characters)"
fi
done
In conclusion, mastering these shell features enhances your ability to manipulate strings and numbers efficiently, improving the performance and readability of your scripts.
Troubleshooting Bash Scripts
As our scripts become more complex, it's crucial to address what happens when things go wrong. This chapter examines common errors in scripts and techniques to track down and eradicate these issues.
Syntactic Errors
One general class of errors is syntactic. These involve mistyping elements of shell syntax, causing the shell to stop executing the script. Here's an example script to demonstrate common types of errors:
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
As written, this script runs successfully:
[me@linuxbox ~]$ trouble
Number is equal to 1.
Missing Quotes
Let's edit the script by removing the trailing quote from the argument following the first echo
command:
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1.
else
echo "Number is not equal to 1."
fi
Running the script results in:
[me@linuxbox ~]$ trouble
/home/me/bin/trouble: line 10: unexpected EOF while looking for matching `"' /home/me/bin/trouble: line 13: syntax error: unexpected end of file
The line numbers reported by the error messages are not where the missing quote was removed but much later in the
program. The shell continues looking for the closing quote until it finds one, immediately after the second
echo
command, confusing subsequent syntax. To avoid this, use an editor with syntax highlighting, like
vim
with the command :syntax on
.
Missing or Unexpected Tokens
Another common mistake is forgetting to complete a compound command, such as if
or while
.
For example, removing the semicolon after the test in the if
command:
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ] then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
Running the script results in:
[me@linuxbox ~]$ trouble
/home/me/bin/trouble: line 9: syntax error near unexpected token `else'
/home/me/bin/trouble: line 9: `else'
The error occurs later than the actual problem. The if
command's test list includes the word
then
due to the missing semicolon, causing syntax errors.
Unanticipated Expansions
Errors can occur intermittently due to the results of an expansion. For example, changing number
to an
empty variable:
#!/bin/bash
# trouble: script to demonstrate common errors
number=
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
Running the script results in:
[me@linuxbox ~]$ trouble
/home/me/bin/trouble: line 7: [: =: unary operator expected
Number is not equal to 1.
The test command fails due to the empty number
variable, resulting in [ = 1 ]
, which is
invalid. This can be corrected by adding quotes around the first argument in the test command:
[ "$number" = 1 ]
Then, the expansion results in [ "" = 1 ]
, which is valid.
Logical Errors
Logical errors do not prevent a script from running but cause it to produce incorrect results. Common types include:
- Incorrect conditional expressions: Misconfigured
if/then/else
logic. - “Off by one” errors: Loop counters starting from incorrect values.
- Unanticipated situations: Unexpected data or expansions causing failures.
Defensive Programming
Verify assumptions by carefully evaluating the exit status of programs and commands. For example, consider this script:
cd $dir_name
rm *
If dir_name
does not exist, the script will delete files in the current working directory. Improve it by
quoting dir_name
and checking if cd
is successful:
cd "$dir_name" && rm *
Further, check that dir_name
contains an existing directory:
[[ -d "$dir_name" ]] && cd "$dir_name" && rm *
Terminate the script if the directory does not exist:
# Delete files in directory $dir_name
if [[ ! -d "$dir_name" ]]; then
echo "No such directory: '$dir_name'" >&2
exit 1
fi
if ! cd "$dir_name"; then
echo "Cannot cd to '$dir_name'" >&2
exit 1
fi
if ! rm *; then
echo "File deletion failed. Check results" >&2
exit 1
fi
Watch Out for Filenames
Unix allows nearly any character in filenames, which can cause problems. For example, a filename starting with
-
can be interpreted as an option. Prevent this by using ./*
:
rm ./*
Portable Filenames
To ensure portability, limit filenames to the POSIX Portable Filename Character Set: uppercase and lowercase letters, numerals, period, hyphen, and underscore.
Verifying Input
A program must handle any input it receives. Use specific tests to verify valid input. For example, to verify a menu selection:
[[ $REPLY =~ ^[0-3]$ ]]
This returns a zero exit status only if REPLY
is a numeral between 0 and 3.
Design is a Function of Time
Design effort varies with the time available. Quick scripts for single use may need minimal checks, while production scripts require thorough development and testing.
Testing
Testing is crucial in software development. Use stubs to verify program flow and modify scripts to make tests safe. For example:
if [[ -d $dir_name ]]; then
if cd $dir_name; then
echo rm * # TESTING
else
echo "cannot cd to '$dir_name'" >&2
exit 1
fi
else
echo "no such directory: '$dir_name'" >&2
exit 1
fi
exit # TESTING
Test Cases
Develop good test cases to reflect edge and corner cases. For example, test the dir_name
script with:
dir_name
contains an existing directory.dir_name
contains a nonexistent directory.dir_name
is empty.
Debugging
Debugging involves finding out what a script is actually doing. Isolate problem areas by commenting out sections of code:
if [[ -d $dir_name ]]; then
if cd $dir_name; then
rm *
else
echo "cannot cd to '$dir_name'" >&2
exit 1
fi
# else
# echo "no such directory: '$dir_name'" >&2
# exit 1
fi
Tracing
Tracing shows the program's flow. Add informative messages or use the -x
option:
#!/bin/bash -x
# trouble: script to demonstrate common errors
number=1
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
Enable tracing for selected parts with set -x
and set +x
:
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
set -x # Turn on tracing
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
set +x # Turn off tracing
Examining Values During Execution
Display variable contents during execution with echo
statements:
#!/bin/bash
# trouble: script to demonstrate common errors
number=1
echo "number=$number" # DEBUG
set -x # Turn on tracing
if [ $number = 1 ]; then
echo "Number is equal to 1."
else
echo "Number is not equal to 1."
fi
set +x # Turn off tracing
Summing Up
This chapter covered common script problems and debugging techniques. Debugging is a skill developed through experience, involving constant testing and effective use of tracing to find and fix bugs.