Linux shell programming study notes 22: Summary of usage of () $() (())

I have been learning Linux Shell programming recently, and I am still a little unclear on the usage of symbols such as () (()) [] [[]], so I decided to sort it out again. Today, let’s sort out the usage of () $() (()).

1 single parentheses ()

1.1 Subshell (command group)


The commands in brackets will open a new subshell and execute them sequentially, so the variables in brackets cannot be used by the rest of the script. Multiple commands in parentheses are separated by semicolons. The last command does not need a semicolon. There is no need for spaces between each command and the parentheses.

1.1.1 bash

$ bash
[csdn ~]$ i=1; echo $i;(let i+=5; echo $i); echo $i
1
6
1
[csdn ~]$ 

 

1.1.2 In zsh

# csdn @ edu in ~ [16:08:09] 
$ i=1; echo $i;(let i+=5; echo $i); echo $i
1
6
1

In the above example, the variable i is initially 1 when executing the command i=1; echo $i

When executing the command (let i+=5; echo $i);, a subshell will be created for execution, in which the variable value i becomes 6

Finally, the command echo $i is executed. The value of variable i in the parent shell does not inherit the changes in the subshell and is still 1.


1.2 Used to define and initialize arrays

like:

a=(1 2 3 4 a b c d)        

The array a is defined and the element values ​​in it are initialized.

1.3 Used for conditional judgment

1.3.1 bash

[csdn ~]$ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
bash: syntax error near unexpected token `;'
[csdn ~]$ i=1;while (test $i -lt 10); do echo $i; let i++; done
1
2
3
4
5
6
7
8
9

1.3.2 In zsh

# csdn @ edu in ~ [19:00:25] C:1
$ i=1; if (test $i -lt 0); then; echo 'i<0'; else; echo 'i>=0'; fi
i>=0

# csdn @ edu in ~ [19:00:46] 
$ i=1;while (test $i -lt 10); do echo $i; let i++; done          
1
2
3
4
5
6
7
8
9

# csdn @ edu in ~ [19:00:52] 
$ i=1;while (test $i < 10); do echo $i; let i++; done
zsh: no such file or directory: 10

# csdn @ edu in ~ [19:02:11] 
$ i=1;while (test $i != 10); do echo $i; let i++; done
1
2
3
4
5
6
7
8
9

2 $(): command substitution

Similar to ` ` (backtick mark), they are both used for command substitution, that is, first complete the command line in () (small expansion mark) or ` ` (backtick mark), and then replace the standard output result.

2.1 In bash

[csdn ~]$ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
/home/csdn \\n path: / \\n /home/csdn
[csdn ~]$ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo `pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd`
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo $(pwd;echo "\\n"; (cd /;echo path:;pwd); echo "\\n"; pwd)
/home/csdn \n path: / \n /home/csdn
[csdn ~]$ echo $(pwd;echo -e "\\n"; (cd /;echo path:;pwd); echo -e "\\n"; pwd)
/home/csdn path: / /home/csdn
[csdn ~]$ 

In the above example, we first execute the pwd command to display the current directory path: /home/csdn

return commandecho '\\n'comereturn

Then open a subshell and execute the command:  (cd /;echo path:;pwd); The command cd / will change the current directory is /, and then use pwd to display the current directory path: /

Then we execute the command echo '\\n' to change the line

Finally, use pwd to display the current directory path: /home/csdn

However, the echo '\\n' command does not implement line breaks, and the -e option still does not work.

2.2 In zsh

# csdn @ edu in ~ [17:21:47] 
$ echo $(pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd)
/home/csdn 
 path: / 
 /home/csdn

# csdn @ edu in ~ [17:22:07] 
$ echo `pwd;echo '\\n'; (cd /;echo path:;pwd); echo '\\n'; pwd`
/home/csdn path: / /home/csdn

The same command is executed correctly in zsh, and line breaks also take effect.

Note: Some shells do not support this usage, such as tcsh.

3 Double parentheses (()): integer operations, base conversion

3.1 Integer operations and comparisons

3.1.1 In bash

# csdn @ edu in ~ [22:20:39] 
$ bash
[csdn ~]$ echo $((3+5))
8
[csdn ~]$ echo $((8 > 6))
1
[csdn ~]$ echo $((5+3 > 6))
1
[csdn ~]$ 

3.1.2 In zsh

[csdn ~]$ zsh

# csdn @ edu in ~ [22:19:50] 
$ echo $((3+5))      
8

# csdn @ edu in ~ [22:20:11] 
$ echo $((8 > 6))
1

# csdn @ edu in ~ [22:20:27] 
$ echo $((3+5 > 6))
1

# csdn @ edu in ~ [22:20:39] 

3.2 Base conversion

$(( )) can convert other bases into decimal numbers and display them. Usage is as follows:

$((N#x))

Among them, N is the base, and x is a certain value in the base. After the command is executed, the value of the base number converted into decimal can be obtained.
 

3.2.1 In bash

$ bash
[csdn ~]$ echo $((2#1000))
8
[csdn ~]$ echo $((8#1000))
512
[csdn ~]$ echo $((16#1000))
4096
[csdn ~]$ echo $((16#1000 - 1000))
3096
[csdn ~]$ echo $((16#1000 - 1000  > 2000)) 
bash: 16#1000 - 1000  > 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
[csdn ~]$ echo $(((16#1000 - 1000)  > 2000)) 
bash: (16#1000 - 1000)  > 2000: syntax error: operand expected (error token is " > 2000")
[csdn ~]$ echo $(( $(16#1000 - 1000)  > 2000)) 
bash: 16#1000: command not found
bash:  > 2000: syntax error: operand expected (error token is " > 2000")
[csdn ~]$ i=1000; $((16#$i-1000 > 2000))
bash: 1: command not found
[csdn ~]$ i=1000; $((16#${i}-1000 > 2000))
bash: 1: command not found

[csdn ~]$ echo $((16#1000  > 2000)) 
bash: 16#1000  > 2000: syntax error: invalid arithmetic operator (error token is " > 2000")
[csdn ~]$ 

In bash, base conversion, base conversion and operation can be completed successfully, but base conversion and comparison are unsuccessful.

3.2.2 In zsh

# csdn @ edu in ~ [15:08:45] C:1
$ echo $((2#1000))
8

# csdn @ edu in ~ [15:08:52] 
$ echo $((8#1000))
512

# csdn @ edu in ~ [15:09:00] 
$ echo $((16#1000))
4096

# csdn @ edu in ~ [15:09:06] 
$ echo $((16#1000 - 1000))
3096

# csdn @ edu in ~ [15:11:31] 
$ echo $((16#1000 - 1000  > 2000)) 
1

In zsh, base conversion, base conversion and operation, base conversion, operation and comparison can be completed smoothly.​ 

In this regard, zsh performs better than bash.

3.3 Using variables in (())

3.3.1 In bash

# csdn @ edu in ~ [15:24:06] 
$ bash
[csdn ~]$ i=5;echo $((i+9))
14
[csdn ~]$ i=12; echo $((8#i+9))
bash: 8#i: value too great for base (error token is "8#i")
[csdn ~]$ i=12; echo $((8#${i}+9))
19
[csdn ~]$ i=12; echo $((8#$i+9))
19
[csdn ~]$ i=12; echo $((8#$i+9 > 10))
1
[csdn ~]$ 

3.3.2 In zsh

 csdn @ edu in ~ [15:22:38] 
$ i=5; echo $((i+9))
14

# csdn @ edu in ~ [15:23:00] 
$ i=12; echo $((8#i+9))
zsh: bad math expression: operator expected at `i+9'

# csdn @ edu in ~ [15:23:23] C:1
$ i=12; echo $((8#${i}+9)) 
19

# csdn @ edu in ~ [15:23:34] 
$ i=12; echo $((8#${i}+9 > 10))
1

In bash and zsh, there is generally no need to add the $ prefix when using variables in (( )). (( )) will automatically parse the variable name, which makes the code more concise and in line with programmers' writing habits.

But there are exceptions. for example:

i=12; echo $((8#i+9))

Neither bash nor zsh can recognize the variable i, so we need to use $i or ${i} to mark the variable i.

3.4 Summary

shell type Integer operations Compare Arithmetic & Comparison Base conversion Base conversion & arithmetic & comparison
bash ×
zsh

3.5 Note

(( )) can only be used for integer arithmetic, not decimals (floating point numbers) or strings. To perform decimal operations, use the bc command.

Guess you like

Origin blog.csdn.net/Purpleendurer/article/details/134275544