I. Parentheses, round brackets ()
1. Single parentheses ()
- Command groupThe commands inside parentheses will execute sequentially in a new subshell, so variables inside the parentheses cannot be used by the rest of the script. Multiple commands inside the parentheses are separated by semicolons; the last command may omit the semicolon, and there is no need for spaces between commands and parentheses.
- Command substitutionEquivalent to `cmd`. When the shell scans the command line and finds the $(cmd) structure, it executes cmd once, obtains its standard output, and places that output into the original command. Some shells do not support it, such as tcsh.
- Used to initialize arraysExample: array=(a b c d)
2. Double parentheses (( ))
- Integer expansion. This expansion performs integer arithmetic and does not support floating point. The ((exp)) structure expands and evaluates the value of an arithmetic expression. If the expression result is 0, it returns an exit status of 1, or "false"; if the expression has a non-zero value, it returns exit status 0, or "true". If used as a logical test, the expression exp is 1 when true and 0 when false.
- As long as the operators and expressions inside the parentheses follow C language operation rules, they can be used in $((exp)), even the ternary operator. When performing operations in different bases (such as binary, octal, hexadecimal), the output results are automatically converted to decimal. For example: echo $((16#5f)) gives 95 (hexadecimal to decimal).
- Simply using (( )) can also redefine variable values, e.g., a=5; ((a++)) can redefine $a to 6.
- Commonly used for arithmetic comparisons. Variables inside double parentheses do not need the $ prefix. Multiple expressions inside are supported, separated by commas. As long as the expressions inside the parentheses conform to C language rules. For example, you can directly use for((i=0;i<5;i++)); if not using double parentheses, it would be for i in `seq 0 4` or for i in {0..4}. Another example: you can directly use if (($i<5)); if not using double parentheses, it would be if [ $i -lt 5 ].
II. Brackets, square brackets []
1. Single square brackets []
- [ is an internal command of bash, and [ and test are equivalent. If we do not specify an absolute path, usually the command we use is bash's built-in command. In the if/test structure, the left bracket is the command token that calls test, and the right bracket closes the conditional test. This command treats its arguments as a comparison expression or as a file test, and returns an exit status based on the comparison result. The right bracket is not strictly necessary in the if/test structure, but newer versions of Bash require it.
- In test and [], the only available comparison operators are == and !=; both are used for string comparison and cannot be used for integer comparison. For integer comparison, only forms like -eq, -gt are allowed. Neither string nor integer comparison supports the greater-than or less-than signs. If you really want to use them for string comparison, you can use the escaped form. For example, comparing "ab" and "bc": [ ab \< bc ] is true, meaning it returns status 0. Logical AND and logical OR in [ ] are represented by -a and -o.
- Character range. Used as part of a regular expression to describe a matching character range. Regular expressions cannot be used inside square brackets when they are used for test purposes.
- In the context of an array structure, square brackets are used to reference the index of each element in the array.
2. Double square brackets [[ ]]
- [[ is a keyword in the bash programming language. It is not a command; the [[ ]] structure is more versatile than the [ ] structure. Between [[ and ]], no filename expansion or word splitting occurs, but parameter expansion and command substitution do occur.
- It supports pattern matching for strings; with the =~ operator, it even supports shell regular expressions. When comparing strings, the right side can be treated as a pattern rather than just a string, e.g., [[ hello == hell? ]] is true. In [[ ]], no quotes are needed when matching strings or wildcards.
- Using the [[ ... ]] conditional test construct instead of [ ... ] can prevent many logic errors in scripts. For example, the &&, ||, < and > operators work properly in the [[ ]] construct, but if they appear in [ ], an error will be reported. For example, you can directly use if [[ $a != 1 && $a != 2 ]]; if not using double brackets, it would be if [ $a -ne 1] && [ $a != 2 ] or if [ $a -ne 1 -a $a != 2 ].
- Bash treats the expression inside the double square brackets as a single element and returns an exit status code.
if ($i<5)
if [ $i -lt 5 ]
if [ $a -ne 1 -a $a != 2 ]
if [ $a -ne 1] && [ $a != 2 ]
if [[ $a != 1 && $a != 2 ]]
for i in $(seq 0 4);do echo $i;done
for i in `seq 0 4`;do echo $i;done
for ((i=0;i<5;i++));do echo $i;done
for i in {0..4};do echo $i;done
III. Braces, curly brackets {}
1. Common usage
(1) Brace expansion. (Globbing) expands filenames inside braces. Within braces, whitespace is not allowed unless it is quoted or escaped. First type: expands a comma-separated list of files inside braces, e.g., touch {a,b}.txt results in a.txt b.txt. Second type: expands a sequential list of files separated by double dots (..) inside braces, e.g., touch {a..d}.txt results in a.txt b.txt c.txt d.txt
# ls {ex1,ex2}.sh
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
(2) Code block, also known as an internal group. This structure actually creates an anonymous function. Unlike commands in parentheses, commands inside braces do not run in a new subshell, so the rest of the script can still use variables inside the braces. Commands inside braces are separated by semicolons, and the last one must also have a semicolon. There must be a space between the first command and the left brace in {}.
2. Several special substitution constructs
${var:-string}
${var:+string}
${var:=string}
${var:?string}
1. ${var:-string} and ${var:=string}: If variable var is empty, then string is used on the command line to replace ${var:-string}; otherwise, if var is not empty, the value of var is used to replace ${var:-string}. The substitution rule for ${var:=string} is the same as ${var:-string}, except that when var is empty, ${var:=string} replaces it with string and also assigns string to var. A very common use of ${var:=string} is to check whether a variable has been assigned, and if not, assign a default value to it.
2. The substitution rule for ${var:+string} is the opposite of the above. That is, it is replaced by string only when var is not empty; if var is empty, it is not replaced, or equivalently, it is replaced by the value of var, which is empty. (Because var is empty at this point, the two statements are equivalent.)
3. The substitution rule for {var:?string}: If variable var is not empty, then use the value of var to replace ${var:?string}; if var is empty, output string to standard error and exit the script. We can use this feature to check whether a variable has been set.
Supplementary expansionIn the above five substitution constructs, string does not have to be a constant; it can be the value of another variable or the output of a command.
3. Four pattern matching substitution constructs
Pattern matching memory aid:
# removes the left side (on the keyboard, # is to the left of $) % removes the right side (on the keyboard, % is to the right of $)
A single symbol in # and % is the smallest match, while two identical symbols are the largest match.
${var%pattern}
${var%%pattern
${var#pattern}
${var##pattern}
- First pattern: ${variable%pattern}. In this pattern, the shell searches variable to see if it ends with the given pattern. If so, it removes the shortest matching pattern on the right from the contents of variable on the command line.
- Second pattern: ${variable%%pattern}. In this pattern, the shell searches variable to see if it ends with the given pattern. If so, it removes the longest matching pattern on the right from the contents of variable on the command line.
- Third pattern: ${variable#pattern}. In this pattern, the shell searches variable to see if it starts with the given pattern. If so, it removes the shortest matching pattern on the left from the contents of variable on the command line.
- Fourth pattern: ${variable##pattern}. In this pattern, the shell searches variable to see if it ends with the given pattern. If so, it removes the longest matching pattern on the right from the contents of variable on the command line.
- In all these four modes, the value of variable is never changed. Among them, only when the * matching symbol is used in the pattern do % and %%, # and ## differ. The pattern in the structure supports wildcards: * represents zero or more arbitrary characters, ? matches exactly one arbitrary character, [...] matches the characters inside the brackets, and [!...] does not match the characters inside the brackets.
# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}
# echo ${var##*s}
e
# echo ${var##test}
case
4. String extraction and replacement
${var:num}
${var:num1:num2}
${var/pattern/pattern}
${var//pattern/pattern}
- First mode: ${var:num}. In this mode, the shell extracts all characters from the num-th character to the end of var. If num is positive, extraction starts from position 0 on the left; if num is negative, the substring is extracted starting from the right, but you must add a space after the colon, or use a number, or enclose the entire num in parentheses, such as ${var: -2}, ${var:1-3}, or ${var:(-2)}.
- Second mode: ${var:num1:num2}, where num1 is the position and num2 is the length. This means extracting a substring of length $num2 starting from position $num1 in the $var string. Negative numbers are not allowed.
- Third mode: ${var/pattern/pattern} means replacing the first occurrence of pattern matched in the var string with another pattern.
- Fourth mode: ${var//pattern/pattern} means replacing all occurrences of pattern matched in the var string with another pattern.
[root@centos ~]# var=/home/centos
[root@centos ~]# echo $var
/home/centos
[root@centos ~]# echo ${var:5}
/centos
[root@centos ~]# echo ${var: -6}
centos
[root@centos ~]# echo ${var:(-6)}
centos
[root@centos ~]# echo ${var:1:4}
home
[root@centos ~]# echo ${var/o/h}
/hhme/centos
[root@centos ~]# echo ${var//o/h}
/hhme/cenths
IV. Brackets after the $ symbol
- (1) ${a} is the value of variable a. The braces can be omitted when no ambiguity is caused.
- (2) $(cmd) is command substitution, which has the same effect as `cmd`. The result is the output of the shell command cmd. However, some Shell versions do not support $() command substitution, such as tcsh.
- (3) $((expression)) has the same effect as `expr expression`. It calculates the numeric value of the mathematical expression exp. As long as exp complies with C language operation rules, even ternary operators and logical expressions can be evaluated.
V. Usage
-
1. Executing multiple commands
- (1) Single parentheses, (cmd1;cmd2;cmd3): start a new subshell to execute commands cmd1, cmd2, cmd3 sequentially, separated by semicolons. The last command does not need a trailing semicolon.
- (2) Single braces, { cmd1;cmd2;cmd3; }: execute commands cmd1, cmd2, cmd3 sequentially in the current shell, separated by semicolons. The last command must be followed by a semicolon, and there must be a space between the first command and the left brace.
Pair{}and()In that regard, a redirection operator inside the parentheses only affects that single command, while a redirection operator outside the parentheses affects all commands in the parentheses.
Original source: http://blog.csdn.net/taiyang1987912/article/details/39551385