Shell Scripts 2
read Console Input
Syntax
1 | read [options] [arguments] |
Options:
-p: Specifies the prompt to display when reading input.-t: Specifies the time (in seconds) to wait for input. If-tis not added, it waits indefinitely.
Arguments:
- Variable: Specifies the name of the variable where the input will be stored.
Below is an example demonstrating how to use the read command to read user input and store it in a variable:
1 |
|
In the example above, the read command is used to read the user’s name and age. The -p option specifies the prompt, and the -t option sets the timeout. After entering the name and age in the command line, the program stores the input values in the respective variables and outputs them. If the user does not input the age within the specified time, the age value will be empty.
Output after running the script:
1 | Please enter your name: John |
If the user does not enter the age within 5 seconds, the output will be:
1 | Please enter your name: John |
Functions
System Functions
basename
basename is a command used to get the base file name of a given path.
Here is the syntax of basename:
1 | basename [path] [suffix] |
Parameter Explanation:
path: The path from which to extract the base file name. This can be a file or directory path.suffix: An optional parameter specifying the suffix to remove. If provided,basenamewill remove the suffix from the path.
Note that the basename command returns the base file name of the given path without the path information.
Example usage:
1 | basename /path/to/file.txt |
Output:
1 | file.txt |
1 | basename /path/to/file.txt .txt |
Output:
1 | file |
In the example, the first command returns the base file name file.txt from the path /path/to/file.txt, and the second command removes the .txt suffix, returning file.
dirname
dirname is a command used to get the directory name of a given path.
Here is the syntax of dirname:
1 | dirname [path] |
Parameter Explanation:
path: The path from which to extract the directory name. This can be a file or directory path.
Note that the dirname command returns the directory name of the given path, excluding the file name or the last path component.
Example usage:
1 | dirname /path/to/file.txt |
Output:
1 | /path/to |
In the example, the command returns the directory name /path/to from the file path /path/to/file.txt.
Custom Functions
Here is the syntax for defining custom functions:
1 | [function] function_name[()] |
The parts enclosed in square brackets in the syntax represent optional items.
function(optional): A keyword used to declare a function. In most cases, the keyword can be omitted, and the function can be declared directly using the function name and parentheses.function_name: The name you assign to the function, which can be customized.(): Parentheses around the function’s parameter list. If the function does not accept any parameters, the parentheses can be omitted.function_code_block: The actual code of the function, which includes a series of commands and logic.return return_value(optional): Specifies the return value of the function. Thereturnkeyword can be followed by an integer value, which represents the status code returned after the function executes. If thereturnstatement is omitted, the function defaults to returning the execution status of the last command.
Note: To ensure proper execution of functions in the script, it is recommended to place the function definitions at the top of the script or before they are called.
Here is an example demonstrating how to define a function that calculates the sum of two input parameters:
1 |
|
In the example script, we define a function called sum_numbers that calculates the sum of two input parameters. The read command is used to accept two numbers from the user and store them in the variables input1 and input2. Then, we call the sum_numbers function and pass the user input as parameters to calculate and output the result.
Example execution result:
1 | Please enter the first number: 5 |
Note that the read command is used to receive user input, and the -p option is used to specify the prompt. The user input is then passed to the function through $input1 and $input2.
Additional Explanation
local is a keyword used to declare local variables within a function. In Bash scripts, the local keyword restricts the scope of a variable to the current function, preventing it from affecting variables with the same name outside the function.
Here is the syntax for the local keyword:
1 | local variable_name |
Where variable_name is the name of the local variable you wish to declare within the function.
Variables declared with the local keyword are only visible inside the function and do not affect variables with the same name outside the function. This helps prevent conflicts between local and global variables and avoids polluting the namespace.
Example:
1 |
|
Output when executing the above script:
1 | Outside function variable: Global Variable |
As seen in the example, the variable my_var declared with the local keyword is only visible inside the function and does not affect the same-named variable outside the function.
Introduction to Regular Expressions
Regular expressions are patterns made up of characters and special symbols, used to describe and match strings that follow a specific rule. They can be used to search, filter, and manipulate text that matches a particular pattern.
By using tools like grep, sed, and awk in Linux, along with regular expressions, you can easily search for, match, and replace text that meets specific patterns, providing powerful text processing and filtering capabilities.
Here are some common uses and patterns:
Character Matching:
.: Matches any single character.[abc]: Matches any one character from the character set, such asa,b, orc.[^abc]: Negates the character set, matching any character except those in the set.[0-9]: Matches any digit from 0 to 9.
Repetition Matching:
*: Matches the preceding character zero or more times.+: Matches the preceding character one or more times.?: Matches the preceding character zero or one time.{n}: Matches the preceding character exactlyntimes.{n,}: Matches the preceding character at leastntimes.{n,m}: Matches the preceding character betweennandmtimes.
Boundary Matching:
^: Matches the start of a line.$: Matches the end of a line.\b: Matches the boundary of a word.
Grouping and Referencing:
(pattern): Groups patterns together.\n: References the nth matched group.
Special Character Matching:
\d: Matches a digit character.\w: Matches a word character (alphanumeric + underscore).\s: Matches a whitespace character.\S: Matches a non-whitespace character.
Escaping Special Characters:
- Use the backslash
\to escape special characters and match them literally. - Example:
\.matches a literal dot.rather than any character.
- Use the backslash
Logical Operations:
|: Logical OR, matches any one of the patterns.
Here are some common regular expression usage examples:
Match Numbers:
\d+- Example:
123,4567,9 - Description: Matches one or more consecutive digits.
- Example:
Match Letters:
[a-zA-Z]+- Example:
abc,Hello,World - Description: Matches one or more consecutive letters (both uppercase and lowercase).
- Example:
Match Words:
\b\w+\b- Example:
Hello,world,123 - Description: Matches a word composed of one or more alphanumeric characters, where
\bindicates the word boundary.
- Example:
Match Email Addresses:
\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b- Example:
[email protected],[email protected] - Description: Matches a valid email address, including the username, domain name, and top-level domain.
- Example:
Match Dates:
\b\d{4}-\d{2}-\d{2}\b- Example:
2021-05-20,1990-12-31 - Description: Matches dates in the format
YYYY-MM-DD.
- Example:
Match URLs:
\bhttps?://\S+\b- Example:
https://www.example.com,http://google.com - Description: Matches URLs starting with
http://orhttps://.
- Example:
These examples only showcase a small portion of regular expression applications. In practice, regular expressions are incredibly powerful and can be used for more complex pattern matching, such as matching repeated characters or characters within specific ranges.
When using regular expressions, you can adjust and combine them based on the specific needs and text content you are working with. Additionally, different text processing tools may have slightly different support for regular expressions, so it’s advisable to consult the relevant tool’s documentation for more details and advanced usage.
Text Processing Tools
cut
cut is a commonly used command-line tool in Linux and other Unix-like operating systems for extracting fields (columns) from text files or standard input.
The basic syntax of the cut command is as follows:
1 | cut [options] file |
Common options include:
-c: Specifies the character range to extract, which can be individual character positions, character ranges, or multiple character ranges. For example,-c 1-5,7extracts the 1st through 5th characters and the 7th character.-f: Specifies the range of fields (columns) to extract, separated by a delimiter. For example,-f 1,3extracts the 1st and 3rd columns.-d: Specifies the delimiter for fields. The default delimiter is a tab.--complement: Inverts the extraction, meaning it extracts everything except the specified character range or fields.
Here are some examples:
Extract specific characters from a file:
1
cut -c 1-5,8 file.txt
This extracts the 1st through 5th characters and the 8th character from each line in the file
file.txt.Extract specific fields from a file:
1
cut -f 1,3 -d "," file.csv
This extracts the 1st and 3rd columns from a CSV file
file.csv, where fields are separated by commas.Extract a range of fields from a file:
1
cut -f 2-4 -d " " file.txt
This extracts columns 2 through 4 from a space-separated file
file.txt.
The cut command also supports additional options and features such as -s (which prevents displaying lines with missing specified fields) and -b (which extracts by byte positions). You can view the full documentation for cut by using the man cut command in the terminal.
awk
awk is a powerful text processing tool based on pattern matching and action rules to process text. Below is the basic usage of awk, options, examples, and commonly used built-in variables:
Basic Usage:
1 | awk 'pattern { action }' file |
patternis the pattern used to match lines to process.actionis the operation executed on the matched lines.
Options:
-F <char>: Specifies the field separator, with the default being space.-v var=value: Defines a variable and assigns a value to it.-f <script file>: Specifies a file containingawkscript.
Examples:
Print each line of a file:
1
awk '{ print }' file.txt
Print the 1st and 3rd columns of a file:
1
awk '{ print $1, $3 }' file.txt
Filter and print based on a condition:
1
awk '$2 > 10 { print }' file.txt
Calculate the sum of the 1st column:
1
awk '{ sum += $1 } END { print sum }' file.txt
Common Built-in Variables:
NR: The number of the current processed line.1
awk '{ print NR, $0 }' file.txt
NF: The number of fields in the current line.1
awk '{ print NF, $0 }' file.txt
FNR: The number of the current line in the current file.1
awk '{ print FNR, $0 }' file1.txt file2.txt
FS: The field separator.1
awk 'BEGIN { FS = ":" } { print $1, $3 }' file.txt
OFS: The output field separator.1
awk 'BEGIN { OFS = "," } { print $1, $2 }' file.txt
This is just the basic usage of awk along with some common built-in variables. awk offers much more functionality and flexibility for more complex text processing and data manipulation. You can use the man awk command to view the full documentation and more detailed usage instructions.
BEGIN and END Blocks:
BEGIN and END are special patterns in awk used to perform actions before or after processing text.
BEGINBlock: TheBEGINblock runs before processing any input. It is typically used for initializing variables, setting parameters, or performing other pre-processing tasks. TheBEGINblock is executed only once.Example:
1
awk 'BEGIN { print "Processing started" } { print $0 }' file.txt
ENDBlock: TheENDblock runs after all input has been processed. It is typically used to summarize, compute results, or output summary information. TheENDblock is executed only once.Example:
1
awk '{ sum += $1 } END { print "Total:", sum }' file.txt
In the above example, the BEGIN block prints a starting message before input is processed, and the END block prints the total after processing all input.
Note that the BEGIN and END blocks are optional and can be used as needed, providing flexibility for performing operations before and after text processing.
Comprehensive Application Example
Archive Files
In practical production applications, it is often necessary to archive and back up important data.
Here is an example of a script that performs daily archive backups of a specified directory:
1 |
|
Script explanation:
- The user inputs the directory name to be backed up.
- The current date is obtained and used as the archive date.
- The archive file name is constructed using the directory name and the archive date.
- The
tarcommand is used to archive and back up the specified directory, with the-czfoption to compress the archive file and save it as a.tar.gzformat. - Output the backup completion message, including the archived directory and file name.
Although the above script can already achieve the required functionality, improvements are needed in input and output checks and feedback. For example, before running the script, it is necessary to ensure that the /root/archive directory exists and has appropriate write permissions.
Here is an improved version of the script:
1 |
|
Improvement explanation:
- Added checks for directory existence and non-emptiness to prevent backing up non-existent or empty directories.
- Used the
-poption to create the archive directory, and it will not report an error if the directory already exists. - Checked the return value of the archiving command to ensure that no errors occurred during the backup process.
- Error messages are output to the standard error stream, and the script exits using
exit 1. - Used the variable
$?to check the return value of the previous command.
Send Message to a User Quickly
Here is an example of a script that sends a message quickly to a specified user:
1 |
|
Script explanation:
- Checks the number of arguments to ensure that both a username and a message are provided.
- Retrieves the username and message content.
- Checks if the user is logged in by using the
whocommand to check the list of logged-in users and usinggrepfor matching. - Checks if the user has messaging enabled by checking the
/etc/messaging_enabled_users.txtfile. This file path can be adjusted according to actual needs. - Checks if the message content is empty using
-zto check if the message variable is empty. - The message sending section can be implemented based on specific needs, such as using a messaging command or sending an email.
- Outputs a message sent confirmation.
Here is an improved version of the script:
1 |
|
Improvement explanation:
- Provides more detailed error messages to inform users of the specific cause of errors.
- Stores the message functionality enabled status in a variable to avoid reading the file each time.
- Stores the enabled users file path in the
$enabled_users_filevariable for easier modification. - Uses the
evalcommand to execute the message sending command, supporting variables in the message content. - Checks the return value of the message sending command to ensure the sending process was successful.
- Error messages are output to the standard error stream, and the script exits using
exit 1.
- Title: Shell Scripts 2
- Author: LHT
- Created at : 2023-01-17 04:04:00
- Link: https://blog.327774.xyz/2023/01/16/linux/shell/Shell Scripts 2/
- License: This work is licensed under CC BY-NC-SA 4.0.