Parentheses in the shell (parentheses, square brackets, curly braces/curly braces)

1. Parentheses, parentheses ()

 

1. Single parentheses ()

    ①Command group. Commands in parentheses will be executed sequentially in a new subshell, so variables in parentheses cannot be used by the rest of the script. Multiple commands in parentheses are separated by semicolons. The last command can be without a semicolon, and there is no need to have spaces between each command and the parentheses.
    ②Command substitution. Equivalent to `cmd`, the shell scans the command line once and finds the $(cmd) structure, executes the cmd in $(cmd) once, gets its standard output, and puts this output into the original command. Some shells do not support it, such as tcsh.
    ③ used to initialize the array. Such as: array=(abcd)
  • Command substitution $(cmd)

The command substitution $(cmd) is similar to the symbol `cmd` (note that this is not a single quote, on a US keyboard, ` is the key below ESC)

$ ls
a b c
$ echo $ (ls)
a b c
$ echo `ls`
a b c

 

Let's analyze the command echo $(ls) in order to understand what the so-called command substitution means:
The shell scans the command line once, finds the $(cmd) structure, executes the cmd in $(cmd) once, and gets its standard output , and then put this output into the $(ls) position in the original command echo $(ls), that is, replace $(ls), and then execute the echo command.
As follows:
echo $(ls) is replaced by echo abc
Here it should be noted that the error output of the command in $(cmd) will not be replaced, only the standard output will be replaced:
$ var=$(cat d) # ##File d does not exist in the current directory
cat: d: No such file or directory
$ echo $var

$### Apparently the value of the var variable is empty

 

2. Double parentheses (( ))

    ①Integer expansion. This extended calculation is an integer calculation and does not support floating point. The ((exp)) construct expands and evaluates an arithmetic expression, returning an exit status code of 1 if the result of the expression is 0, or "false", and a non-zero value returned by an expression The exit status code will be 0, or "true". If it is a logical judgment, the expression exp is 1 if it is true, and 0 if it is false.
    ②As long as the operators and expressions in parentheses conform to the C language operation rules, they can be used in $((exp)), even ternary operators. When performing operations with different carry (such as binary, octal, and hexadecimal), the output results are all automatically converted into decimal. For example: echo $((16#5f)) The result is 95 (hexadecimal to decimal)
    ③ Simply use (( )) to redefine variable values, such as a=5; ((a++)) can redefine $a to 6

    ④ Variables in double brackets can be prefixed without the $ sign. Multiple expressions within parentheses are supported separated by commas.

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

 

  • POSIX standard extended computation: $((exp))

This calculation is a C-compliant operator, that is, as long as the C-compliant operator can be used in $((exp)), even the ternary operator.
Note: This extended calculation is an integer calculation and does not support floating-point type. If it is a logical judgment, the expression exp is true, it is 1, and it is 0 if it is false.

$ echo $((3+2))
5
$ echo $((3>2))
1
$ echo $((25<3 ? 2:3))
3
$ echo $ var

$ echo $ ((var = 2 + 3))
5
$ echo $ var
5
$ echo $ ((var ++))
5
$ echo $ var
6
$

 

b) Square brackets, square brackets []

 

1. Single brackets []

    ①The internal command of bash, [ and test are equivalent. If we don't specify the absolute path, we usually use the commands that come with bash. The left square bracket in the if/test structure is the command identifier for calling test, and the right square bracket is used to close the conditional judgment. This command takes its argument as a comparison expression or as a file test, and returns an exit status code based on the result of the comparison. The closing bracket is not required in the if/test structure, but it is required in the new version of Bash.
    ②The only comparison operators available in Test and [] are == and !=, both of which are used for string comparison, but not for integer comparison. Integer comparison can only use the form of -eq, -gt. Neither string comparisons nor integer comparisons support the greater-than sign and the less-than sign. If you really want to use it, you can use the escaped form for string comparison. If you compare "ab" and "bc": [ ab < bc ], the result is true, that is, the return status is 0. Logical AND and logical OR in [ ] are expressed using -a and -o.
    ③ character range. Used as part of a regular expression to describe a range of characters to match. Regular expressions cannot be used within square brackets for test purposes.
    ④ In the context of an array structure, square brackets are used to refer to the number of each element in the array.

 

2. Double brackets [[ ]]

    ①[[ is a keyword in the bash programming language. Not a command, the [[ ]] construct is more general than the [ ] construct. All characters between [[ and ]] do not have filename expansion or word splitting, but parameter expansion and command substitution will occur.
    ② Supports pattern matching of strings, and even supports regular expressions of the shell when using the =~ operator. String comparisons can use the right-hand side as a pattern, not just a string, such as [[ hello == hell? ]], which results in true. [[ ]] matches strings or wildcards without quotes.
    ③Using the [[...]] conditional judgment structure instead of [...] can prevent many logical errors in the script. For example, the &&, ||, < and > operators can normally exist in the [[ ]] conditional judgment structure, but if they appear in the [ ] structure, an error will be reported.
    ④bash treats the expression in double square brackets as a single element and returns an exit status code.

 

3) Braces, curly braces {}

 

1. Conventional usage.

    ①Brace expansion. (globbing) will expand the filename in curly braces. Within curly braces, whitespace is not allowed unless the whitespace is quoted or escaped. The first: expands the comma-separated list of files in curly braces. For example, touch {a,b}.txt results in a.txt b.txt. The second: expands the sequential file list separated by dots (..) in braces, such as: touch {a..d}.txt The result is a.txt b.txt c.txt d.txt

bogon:/home/bash # ls {ex1,ex2}.sh
ex1.sh  ex2.sh
bogon:/home/bash # ls {ex{1..3},ex4}.sh
ex1.sh  ex2.sh  ex3.sh  ex4.sh
bogon:/home/bash # ls {ex[1-3],ex4}.sh
ex1.sh  ex2.sh  ex3.sh  ex4.sh

 

    ② The code block, also known as the inner group, this structure actually creates an anonymous function. Unlike commands in parentheses, commands in curly brackets do not open a new subshell to run, that is, the rest of the script can still use the variables in the brackets. The commands in parentheses are separated by semicolons, and the last one must also have a semicolon. There must be a space between the first command of {} and the opening parenthesis.

   

2) Several special replacement structures: ${var:-string}, ${var:+string}, ${var:=string}, ${var:?string}

      A, ${var:-string} and ${var:=string}: If the variable var is empty, use string to replace ${var:-string} on the command line, otherwise when the variable var is not empty, Then replace ${var:-string} with the value of variable var; the replacement rule for ${var:=string} is the same as ${var:-string}, the difference is ${var:=string } If var is empty, replace ${var:=string} with string and assign string to variable var: ${var:=string} A very common usage is to judge whether a variable is assigned a value or not. If so, assign it a default value.
B. The replacement rule of ${var:+string} is the opposite of the above, that is, only when var is not empty, it will be replaced with string. If var is empty, it will not be replaced or replaced with the value of variable var, that is, empty value. (Because the variable var is empty at this time, these two statements are equivalent)
C, ${var:?string} The replacement rule is: if the variable var is not empty, replace ${var with the value of the variable var :?string}; if the variable var is empty, output string to standard error and exit from the script. We can use this feature to check if the value of a variable is set.
Supplementary expansion: In the above five replacement structures, string is not necessarily constant, but the value of another variable or the output of a command can be used.

 

3) Four pattern matching replacement structures: ${var%pattern}, ${var%%pattern}, ${var#pattern}, ${var##pattern}

The first pattern: ${variable%pattern}, in this pattern, the shell looks in the variable to see if it ends with a given pattern pattern, if so, remove the shortest match on the right from the contents of the variable from the command line Pattern
The second pattern: ${variable%%pattern}, in this pattern, the shell looks in the variable to see if it ends with a given pattern pattern, if so, remove the contents of the variable from the command line, the rightmost Long matching pattern The
third pattern: ${variable#pattern} In this pattern, the shell looks in the variable to see if it starts with the given pattern pattern, if so, remove the contents of the variable from the command line to the left The shortest matching pattern The
fourth pattern: ${variable##pattern} In this pattern, the shell looks in the variable to see if it ends with a given pattern pattern, if so, remove the contents of the variable from the command line The longest matching pattern on the right
does not change the value of the variable in any of the four patterns. Among them, only when the * matching symbol is used in the pattern, there is a difference between % and %%, and # and ##. The pattern in the structure supports wildcards, * means zero or more arbitrary characters, ? means zero or one arbitrary character, [...] means matching the characters inside the brackets, [!...] means not matching the brackets characters inside

bogon:/home/bash # var=testcase
bogon:/home/bash # echo $var
testcase
bogon:/home/bash # echo ${var%s*e}
test ca
bogon:/home/bash # echo $var
testcase
bogon:/home/bash # echo ${var%%s*e}
at
bogon:/home/bash # echo ${var#?e}
stcase
bogon:/home/bash # echo ${var##?e}
stcase
bogon:/home/bash # echo ${var##*e}

bogon:/home/bash # echo ${var##*s}
e
bogon:/home/bash # echo ${var##test}
case

 

  • The prototype of the variable in the shell: ${var}

The common variable form is $var, such as

$ var = test
$ echo $ var
test

 

But when you want to display the variable value plus random characters (I use AA here), an error occurs, as follows:

$ echo $ varAA

$

 

At this time, you should use the prototype of the variable: ${var}, that is, add a brace to limit the scope of the variable name, as follows

$ echo $ {var} AA
testAA
$

 

With this feature, we can easily write a program to change suffix names in batches, I named it mymv, and the program is as follows:

#!/bin/bash

tail=$1
for filename in `ls`
do
mv $filename ${filename}.$tail
done

 

The program needs to provide a suffix name, such as c, which means changing to a C program file with the suffix c, see the following test:

$ ls
a b c
$ mymv c
$ ls
a.c b.c c.c
$

 

It seems that the program runs very well, but this is an imperfect program. There are 2 problems to pay attention to:
A. There are no subdirectories in the directory. If there is a directory, assuming it is dir, it will also be changed to dir.c , which is obviously not what we want and should fix this program to recognize directories.


B, it does not help to process the parameters of the program, the program should be friendly enough, and it should be able to handle when the user does not give a suffix name, like the above will directly add a dot (.) to the file, which is obviously not what we want. need.

Since our purpose is to specify ${var}, this is enough, so there will be no further modifications to the above program.

  • A string of commands to execute () and {}

() and {} both execute a series of commands, but there are differences:
A, () just reopen a subshell to execute
a series of commands B, {} execute a series of commands in the current shell
C, Both () and {} put a series of commands in parentheses, and the commands are separated by ;
D, the last command of () can use semicolon
E, the last command of {} uses semicolon
F, There must be a space between the first command of {} and the opening bracket
G, each command in () does not have to have a space with the bracket
H, redirection of a command in () and {} brackets only affects the commands, but redirection outside the parentheses affects all commands within the parentheses

Let's look at a few examples:

$ var = test
$ (var=notest; echo $var) ###The value of the variable var is notest, which is valid in a subshell
notest
$ echo $var ###The value in the parent shell is still test
test
$ { var=notest; echo $var;} ###Note that there should be a space between the left parenthesis and var
notest
$ echo $var ###The value of the var variable in the parent shell becomes note
notest
$ { var1=test1;var2=test2;echo $var1>a;echo $var2;} ###The output of test1 is redirected to file a,
test2 ### and test2 output is still output to standard output.
$ cat a
test1
$ { var1=test1;var2=test2;echo $var1;echo $var2;}>a ###The standard output of the commands in parentheses are all redirected to file a
$ cat a
test1
test2

 

Here is an example of a step:

(
    echo "1"
    echo "2"
) | awk '{print NR, $ 0}'

 

  • Several special substitution constructs: ${var:-string},${var:+string},${var:=string},${var:?string}

A, ${var:-string} and ${var:=string}
If the variable var is empty, use string to replace ${var:-string} on the command line, otherwise when the variable var is not empty, then Replace ${var:-string} with the value of the variable var
like:

$ echo $newvar

$ echo ${newvar:-a}
a
$ echo $newvar ###The value of the variable newvar is still empty, but ${newvar:-a} is replaced with a in the previous command line

$ newvar = b
$ echo ${newvar:-a} ###When the value of variable newvar is not empty, ${newvar:-b} in this command line is replaced by $newvar, that is, b
b
$

 

The replacement rule for ${var:=string} is the same as ${var:-string}, the difference is that if ${var:=string} is empty, replace ${var:=string with string } at the same time, assign string to variable var:

$ echo $newvar

$ echo ${newvar:=a}
a
$ echo $newvar ###The variable newvar is assigned to a, and ${newvar:=a} is replaced with a
a
$ echo ${newvar:=b} ###The variable newvar is not empty (its value has been assigned as a), then ${newvar:=b} is replaced with the value of newvar (that is, b)
a
$ echo $newvar
a

 

A very common usage of ${var:=string} is to determine whether a variable is assigned a value, and if not, assign a default value to it.
Such as setting the default editor:
PHP code:
echo You use editor: ${EDITOR:=/bin/vi}

B,${var:
+string} The replacement rule of ${var:+string} is the opposite of the above, that is, only when var is not empty, it will be replaced with string, and if var is empty, it will not be replaced or replaced with The value of the variable var, that is, the null value. (Because the variable var is empty at this time, the two statements are equivalent)

$ echo $newvar
a
$ echo ${newvar:+b}
b
$ echo $newvar
a
$ newvar =
$ echo ${newvar:+b}

$

 

C,${var:?string}
The replacement rule is: if the variable var is not empty, replace ${var:?string} with the value of the variable var; if the variable var is empty, output the string to the standard error , and exit from the script. We can use this feature to check if the value of a variable is set.

$ newvar =
$ echo ${newvar:? does not set the value of newvar}
bash: newvar: newvar value not set
$ newvar = a
$ echo ${newvar:? does not set the value of newvar}
a
$

 

Supplementary expansion: In the above five replacement structures, string is not necessarily constant, but the value of another variable or the output of a command can be used.

$ echo ${var:-`date`} Mar 6 02:10:39 CST 2005
$ echo ${var:-$(date)} Mar 6 02:11:46 CST 2005
$ a=test
$ echo ${var:-$a}
test
$

 

  • Four pattern matching replacement structures: ${var%pattern}, ${var%%pattern}, ${var#pattern}, ${var##pattern}

The meanings of these four structures are: ${var%pattern} and ${var%%pattern} indicate matching from the far right (ie the end), ${var#pattern} and ${var##pattern} from the far left (i.e. the beginning of) matches. Where ${var%pattern} and ${var#pattern} are the shortest matches, and ${var%%pattern} and ${var##pattern} are the longest matches. Only when wildcards are used in the pattern can there be the longest and shortest match, otherwise there is no longest and shortest match.

The pattern in the structure supports wildcards, * means zero or more arbitrary characters, ? means zero or one arbitrary character, [...] means matching the characters inside the brackets, [!...] means not matching the brackets characters inside.

$ var = aabbbccbbdbb
$ echo ${var%b}
aabbbccbbdb
$ echo ${var%%b}
aabbbccbbdb
$ echo ${var#a}
abbbccbbdbb
$ echo ${var##a}
abbbccbbdbb
$ echo ${var%*b}
aabbbccbbdb
$ echo ${var%%*b}

$ echo ${var#a*}
abbbccbbdbb
$ echo ${var##a*}

$

 

The above is a simple example of the usage of four pattern matching replacement structures.

  • Other (see Parameter Expansion in man bash)
${parameter/pattern/string}
              Pattern substitution.  The pattern is expanded to produce a pat‐
              tern  just  as in pathname expansion.  Parameter is expanded and
              the longest match of pattern against its value is replaced  with
              string.   If  pattern  begins with /, all matches of pattern are
              replaced  with  string.   Normally  only  the  first  match   is
              replaced.  If pattern begins with #, it must match at the begin‐
              ning of the expanded value of parameter.  If pattern begins with
              %,  it must match at the end of the expanded value of parameter.
              If string is null, matches of pattern are deleted and the / fol‐
              lowing pattern may be omitted.  If parameter is @ or *, the sub‐
              stitution operation is applied to each positional  parameter  in
              turn,  and the expansion is the resultant list.  If parameter is
              an array variable subscripted with  @  or  *,  the  substitution
              operation  is  applied  to each member of the array in turn, and
              the expansion is the resultant list.

 

Summarize:

The brackets in the shell have their special usage, which are summarized as follows:

 

1. The parentheses ${a} after the symbol $
are the value of the variable a. The curly brackets can be omitted if there is no ambiguity. The
$(cmd) command is replaced, and the result is the output of the shell command cmd, which has the same effect as `cmd`, However, some Shell versions do not support command substitution in the form of $(), such as tcsh.
$((exp)) has the same effect as `expr exp`, and calculates the value of the mathematical expression exp, where exp only meets the operation rules of the C language. Yes, even ternary operators and logical expressions can be evaluated.

 

2. Multiple command execution
(cmd1;cmd2;cmd3) Open a new subshell and execute the commands cmd1, cmd2, cmd3 in sequence, separate each command with a semicolon, and there can be no semicolon after the last command.
{ cmd1;cmd2 ;cmd3;} Execute the commands cmd1, cmd2, cmd3 in sequence in the current shell, separate each command with a semicolon, there must be a semicolon after the last command, and the first command and the opening bracket must be separated by a space.
For {} and (), the redirection character in parentheses affects only that command, while the redirection character outside the brackets affects all commands in the brackets.

 

3. Special usage of double parentheses
(()) Enhances the usage of parentheses and is often used for arithmetic operation comparisons. Variables in double parentheses can be prefixed without the $ symbol, as long as the expressions in parentheses conform to the C language operation rules, multiple expressions are supported The expressions are separated by commas.
For example, you can use for((i=0;i<5;i++)) directly. If double brackets are not used, it is for i in `seq 0 4` or for i in {0..4} .For
another example, if (($i<5)) can be used directly, if double brackets are not used, it is if [ $i -lt 5 ].
[[]] Enhances the usage of square brackets, which is often used for string comparison. Main For conditional testing, expressions in double brackets can use C language syntax
such as &&, ||, <, >. For example, if [[ $a != 1 && $a != 2 ]] can be used directly, if not applicable Double brackets, then if [ $a -ne 1] && [ $a != 2 ] or if [ $a -ne 1 -a $a != 2 ].

 

Taken from: Parentheses in the shell (parentheses, square brackets, curly braces/curly braces)

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327030709&siteId=291194637