Grammar and characteristics
The command syntax of bash is a superset of the Bourne shell command syntax. A large number of Bourne shell scripts can be executed in bash without modification. Only those scripts that reference Bourne special variables or use Bourne's built-in commands need to be modified. Many bash command syntax comes from Korn shell (ksh) and C shell (csh), such as command line editing, command history, directory stack, $RANDOM and $PPID variables, and POSIX command substitution syntax: $(...). As an interactive shell, press the TAB key to automatically complete the partially entered program name, file name, variable name, etc.
Alibaba Cloud Simple Application Server: Anti COVID-19 SME Enablement Program
$300 coupon package for all new SMEs and a $500 coupon for paying customers.
When using the'function' keyword, Bash's function declarations are not compatible with Bourne/Korn/POSIX scripts (Korn shell has the same problem). But Bash also accepts Bourne/Korn/POSIX function declaration syntax. Because of many differences, Bash scripts rarely run in Bourne or Korn interpreters unless the script is written to maintain compatibility at all times. However, with the popularity of Linux, this approach is becoming less and less. But in POSIX mode, Bash is more POSIX-compliant.
The grammar of bash has made a lot of extensions for the shortcomings of the Bourne shell. Some of them are listed here.
Brace expansion
Bracket expansion is a feature borrowed from the C shell, which produces a series of specified strings (in the original order from left to right). These strings do not need to be existing files.
$ echo a{p,c,d,b}e
ape ace ade abe
$ echo {a,b,c}{d,e,f}
ad ae af bd be bf cd ce cf
Bracket expansion should not be used in portable shell scripts, because the Bourne shell produces different results.
#! /bin/sh
# Traditional shell does not produce the same result
echo a{p,c,d,b}e # a{p,c,d,b}e
When brace expansion is used together with wildcards, the brace expansion is parsed first, and then the wildcards are parsed normally. Therefore, you can use this method to obtain a series of JPEG and PEG files in the current directory.
ls *.{jpg,jpeg,png} # First expand to *.jpg *.jpeg *.png, and then parse wildcards
echo *.{png,jp{e,}g} # echo displays the expansion result; brace expansion can be nested.
In addition to enumerating alternatives, you can also use ".." to specify a range of characters or numbers in the curly brace expansion. The newer version of Bash accepts an integer as the third parameter, specifying the increment.
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo file{1..4}.txt
file1.txt file2.txt file3.txt file4.txt
$ echo {a..e}
a b c d e
$ echo {1..10..3}
1 4 7 10
$ echo {a..j..3}
a d g j
When brace expansion and variable expansion are used together, the variable expansion is resolved after the brace expansion. Sometimes it is necessary to use the built-in eval function
$ start=1; end=10
$ echo {$start..$end} # Due to the parsing order, the desired result cannot be obtained
{1..10}
$ eval echo {$start..$end} # First analyze the variable expansion
1 2 3 4 5 6 7 8 9 10
Use integer
The difference from the Bourne shell is that bash can perform integer operations without generating additional processes. Bash uses the ((...)) command and $[...] variable syntax to achieve this goal:
VAR=55 # Assign the integer 55 to the variable VAR
((VAR = VAR + 1)) # Add 1 to the variable VAR. Note that there is no'$'
((++VAR)) # Another way to add 1 to VAR. Use C language style prefix increment
((VAR++)) # Another way to add 1 to VAR. Use C language style suffix to increase
echo $((VAR * 22)) # Multiply VAR by 22 and send the result to the command
echo $[VAR * 22] # Same as above, but outdated usage
The ((...)) command can be used in conditional statements, because its exit status is 0 or non-zero (in most cases 1), it can be used to determine whether it is true or not:
if((VAR == Y * 3 + X * 2))
then
echo yes
fi
((Z> 23)) && echo Yes
The ((...)) command supports the following comparison operators:'==','!=','>','<','>=', and'<='.
Bash cannot perform floating point operations in its own process. Currently the only unix shells with this capability are Korn shell and Z shell.
Input and output redirection
Bash has an I/O redirection syntax that the traditional Bourne shell lacks. Bash can redirect standard output and standard error at the same time, which requires the following syntax:
command &> file
This is simpler than the equivalent Bourne shell syntax "command> file 2>&1". After version 2.05b, bash can redirect standard input to a string (called a here string) with the following syntax:
command <<< "string to be read as standard input"
If the string contains spaces, you need to wrap the string in quotation marks.
Example: Redirect standard output to file, write data, close file, reset standard output.
# Generate a copy of the standard output (file descriptor 1) file descriptor 6
exec 6>&1
# Open the file "test.data" for writing
exec 1>test.data
# Generate some content
echo "data:data:data"
# Close the file "test.data"
exec 1>&-
# Make standard output point to FD 6 (reset standard output)
exec 1>&6
# Close FD6
exec 6>&-
Open and close files
# Open the file test.data for reading
exec 6<test.data
# Read the file until the end of the file
while read -u 6 dta
do
echo "$dta"
done
# Close the file test.data
exec 6<&-
Grab the output of external commands
# Run'find' and save the result in VAR
# Search for file names ending in "h"
VAR=$(find. -Name "*h")
Regular expression in process
Bash 3.0 supports regular expressions in the process, using the following syntax:
[[ string =~ regex ]]
The regular expression syntax is the same as described in the regex(7) man page. When a regular expression matches a string, the exit status of the above command is 0, and if it does not match, it is 1. The sub-expression enclosed in parentheses in the regular expression can access the shell variable BASH_REMATCH, as follows:
if [[ abcfoobarbletch =~'foo(bar)bl(.*)' ]]
then
echo The regex matches!
echo $BASH_REMATCH - outputs: foobarbletch
echo ${BASH_REMATCH[1]} - outputs: bar
echo ${BASH_REMATCH[2]} - outputs: etch
fi
The performance of using this syntax is better than spawning a new process to run the grep command, because the regular expression matching is done within the bash process. If the regular expression or string contains spaces or shell keywords, (such as'*' or'?'), it needs to be wrapped in quotation marks. This is no longer necessary in the beginning of Bash 4.