后浪笔记一零二四

前提: 环境变量和普通变量的区别, 环境变量被export过了的,普通变量则没有。 子shell可以获取环境变量,但是不能获取普通变量。 注意:子shell对全局变量的改变,不会被反映到父shell中。子shell甚至无法使用export命令改变父shell中全局变量的值。

unset my-variable可以删除环境变量和普通变量,但是在子shell中删除环境变量无法反映到父shell中。

所有的系统环境变量均使用大写字母,这是bash shell的标准惯例。 自己创建的环境变量和普通变量,都应该使用小写字母,以避免覆盖系统环境变量。

1. let (Evaluate arithmetic expression, 和(())运算符一样)

类似,$(())和(())操作符 let ARG [ARG...], Evaluate each ARG as an arithmetic expression. Evaluate is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error. The following list of operators is grouped into levels of equal- precedence(相等优先级) operators. The levels are listed in order of decreasing precedure (优先级依次降低).

  • id++, id-- variable post-increment, post-decrement.
  • ++id, --id variable pre-increment, pre-decrement.
  • -,+ unary minus, plus
  • !, ~ logical and bitwise negation
  • ** exponentiation
  • *,/,% multiplication, division, remainder
  • +,- addition, subtraction
  • <<, >> left and right bitwise shifts
  • <=,>=,<,> comparison
  • ==, != equality,inequality
  • & bitwise AND
  • ^ bitwise XOR
  • | bitwise OR
  • && logical AND
  • || logical OR
  • expr?expr:expr conditional operator
  • =,*=,/=,%=,+=,-=,<<=,>>=,&=,^=,|= assignment

Shell variables are allowed as operand. The name of the variable is replaced by its value (coerced被胁迫的 to a fixed-width integer) within an expression. The variable need not have its integer arribute turned on to be used in an expression.

Operators are evaluated in order of precedence. Sub-expression in parentheses are evaluated first and may override the precedence rules above.

Exit Status: If the last ARG evaluates to 0, let return 1; let returns 0 otherwise.

Numerical Constants: A shell script interpretes a number as decimal(base 10), unless that number has a special prefix or notation. A number preceded by a 0 is octal(base 8). A number preceded by 0x is hexadecimal(base 16). A number with an embedded # evaluates as BASE#NUMBER (with range and notational restrictions)。进制转换。

#!/bin/bash
let "dec = 32"
echo "decimal number = $dec"
# Octal: numbers preceded by '0'
let "oct = 032"
echo "octal number = $oct"
# Hexadecimal: numbers preceded by '0x' or '0X'
let "hex = 0x32"
echo "hexadecimal number = $hex"
# Other bases: BASE#NUMBER
# BASE between 2 and 64.
let "bin = 2#111100111001101"
echo "binary number = $bin"
let "b32 = 32#77"
echo "base-32 number = $b32"
let "b64 = 64#@_"
echo "base-64 number = $b64"
# This notation only works for a limited range (2 - 64) of ASCII characters.
# 10 digits + 26 lowercase characters + 26 uppercase characters + @ + _

2. declare 设置变量名和属性

Declare variables and give them attributes. If no NAMEs are given, display the attributes and values of all variables.

Options: -f restrict action or display to function names and definitions -F restrict display to function names only (plus line number and sourcce file when debugging) -g create global variables when used in a shell function; otherwise ignored -p display the attributes and value of each NAME

Options which set attributes: -a to make NAMEs indexed arrays (if supported) -A to make NAMEs associative arrays (if supported) -i to make NAMEs have the integer attribute -l to convert NAMEs to lower case on assignment -n make NAME a reference to the variable named by its value -r to make NAMEs readonly -t to make NAMEs have the trace attribute -u to convert NAMEs to upper case on assignment -x to make NAMEs export

Using ‘+’ instead of ‘-’ turns off the given attribute.

Variables with the integer attribute have arithmetic evaluation (see the let command) performed when the variable is assigned a value.

When used in a function, declare makes NAMEs local, as with the local command. The -g option suppresses this behavior.

Exist Status: Returns success unless an invalid option is supplied or a variable assignment error occurs.

#!/bin/bash
# 声明变量
declare -A color

# 定义颜色
color[red]="\e[1;31m"
color[green]="\e[1;32m"
color[yellow]="\e[1;33m"
color[blue]="\e[1;34m"
color[purple]="\e[1;35m"
color[bc_red]="\e[41m"
color[bc_green]="\e[42m"
color[bc_yellow]="\e[43m"
color[bc_blue]="\e[44m"
color[bc_purple]="\e[45m"
color[exit]="\e[0m"

color_red(){
      echo -e "${color[red]}$@${color[exit]}"
}

color_yellow(){
      echo -e "${color[yellow]}$@${color[exit]}"
}

color_green(){
      echo -e "${color[green]}$@${color[exit]}"
}

color_blue(){
      echo -e "${color[blue]}$@${color[exit]}"
}
color_purple(){
      echo -e "${color[purple]}$@${color[exit]}"
}
color_red "hello!"

color_yellow "hello!"
color_green "hello!"

color_blue "hello!"
color_purple "hello!"

# 多维数组
declare -A arr
arr[0,0]=0
arr[0,1]=1
arr[1,0]=2
arr[1,1]=3
echo "${arr[0,0]} ${arr[0,1]}"

3. 局部变量

Variables visible only within a code block or function。 使用local关键字来定义局部变量

4. Environmental variables(export过的变量称为环境变量)

Every time a shell starts, it creates shell variables that correspond to(和..对应的) its own environmental variables. Updating or adding new environmental variables causes the shell to update its environment, and all the shell’s child processed (the command it executes) inherit this environment.(注意,只能继承环境变量,普通变量不能继承)

The space allotted to(分配给) the environment is limited. Creating too many environmental variables or ones that use up excessive(过多) space may cause problems

A script can export variables only to child process. Child processes cannot export variables back to the parent processes that spawned them.

5. 位置参数

Auguments passed to the script from the command line: $0, $1, $2, $3…

$0 is the name of the script itself, $1 is the first argument, $2 the second, $3 the third, and so forth. After $9, the arguments must be enclosed in brackets, for example, ${10}, ${11}, ${12}.

The special variable $* and $@ denote(表示) all the positional parameters. $*变量会将命令行上提供的所有参数当做一个单词保存。这个单词包含了命令行中出现的每一个参数值。基本上$*变量会将这些参数视为一个整体,而不是多个个体。 另一方面,$@变量会将命令行上提供的所有参数当做同一字符串中的多个独立的单词。这样你就能够便利所有的参数值,得到每个参数。

Bracket notation(符号) for positional parameters leads to a fairly(相当) simple way of referencing the last argument passed to a script on the command-line. This also requires indirect referencing.

args=$#         # Number of args passed
lastarg=${!args}  # 使用间接引用
# Note: This is an *indirect reference* to $args ...
# {}里面不能使用$

Some scripts can perform different operations, depending on which name they are invoked with. For this to work, the script needs to check $0, the name it was invoked by. There must also exist symbolic links to all the alternate names of the script.

If a script expects a command-line parameter but is invoked without one, this may cause a null variable assignment, generally an undesirable result. One way to prevent this is to append an extra character to both sides of the assignment statement using the expected positional parameter.

variable1_=$1_   # Rather than variable1=$1
# This will prevent an error, even if positional parameter is absent
# The extra character can be stripped off later, like so
variable1=${variable1_/_/}

# A better method is parameter substitution:
#  ${1:-$DefaultVal}

Encapsulating “!” within double quotes gives an error when used from the command line. This is interpreted as a history command. Within a script, though, this proble does not occur, since the Bash histroy mechanism is disabled then.

Of more concern is the apparently inconsistent behavior of \ within double quotes, and especially following an echo -e command.

$ echo hello\!
hello!
$ echo "hello\!"
hello\!
$ echo x\ty
xty
$ echo "x\ty"
x\ty
$ echo -e x\ty
xty
$ echo -e "x\ty"
x        y

5.1 使用shift命令移动命令行参数

在使用shift命令时,默认情况下它会将每个参数变量向左移动一个位置。所以,变量$3的值会移动到$2中,变量$2的值会移动到$1中,而变量$1的值则会被删除(注意,变量$0的值,也就是程序名,不会改变)

这是遍历命令行参数的另一个好方法,尤其是在你不知道到底有多少个参数时。你可以只操作第一个参数,移动参数,然后继续操作第一个参数。

$ cat test 
#!/bin/bash
# demonstrating the shift command
echo
count=1
while [ -n "$1" ]
do
	echo "Parameter #$count = $1"
	count=$[ $count + 1 ]
	shift #还可以一次移动多个位置,例如:shift 2
done

$ ./test rich barbara katie jessica

Parameter #1 = rich
Parameter #2 = barbara
Parameter #3 = katie
Parameter #4 = jessica

使用shift命令时要小心。如果某个参数被移出,它的值就被丢弃了,无法再恢复。

5.2 使用getopt命令

命令格式:getopt optstring parameters optstring是这个过程的关键所在。它定义了命令行有效的选项字母,还定义了哪些选项字母需要参数值。

1
2
$ getopt ab:cd -a -b test1 -cd test2 test3
 -a -b test1 -c -d -- test2 test3

optstring定义了四个有效选项字母:a,b,c和d。冒号被放在了字母b后面,因为b选项需要一个参数值。当getopt命令运行时,它会检查提供的参数列表(-a -b test1 -cd test2 test3),并基于提供的optstring进行解析。注意,它会自动将-cd选项分成两个单独的选项,并插入双破折线来分割行中的额外参数。

如果指定了一个不在optstring中的选项,默认情况下,getopt命令会产生一条错误消息。

1
2
3
$ getopt ab:cd -a -b test1 -cde test2 test3
getopt: invalid option -- e
-a -b test1 -c -d -- test2 test3

如果想忽略这条错误信息,可以在命令后加-q选项。注意,getopt命令选项必须出现在optstring之前。

在脚本中使用getopt: 用getopt命令生成的格式化后的版本来替代已有的命令行选项和参数。用set命令能够做到,因为set命令能够处理shell中的各种变量。set -- $(getopt -q ab:cd "$@")

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ cat test 
#!/bin/bash
# Extract command line options & values with getopt

set -- $(getopt -q ab:cd "$@")
#
echo 
while [ -n "$1" ]
do
	case "$1" in
	-a) echo "Found the -a option" ;;
	-b) param="$2"
	    echo "Found the -b option, with parameter value $param"
	    shift ;;
	-c) echo "Found the -c option" ;;
	--) shift
	    break ;;
	*)  echo "$1 is not an option";;
	esac
	shift
done
#
count=1
for param in "$@"
do 
	echo "Parameter #$count: $param"
	count=$[ $count + 1 ]
done

$ ./test -a -b test1 -cd test2 test3 test4

Found the -a option
Found the -b option, with parameter value 'test1'
Found the -c option
-d is not an option
Parameter #1: 'test2'
Parameter #2: 'test3'
Parameter #3: 'test4'

5.3 使用更高级的getopts

getopts是內建命令。与getopt不同,getopt将命令行上选项和参数处理后只生成一个输出,而getopts命令能够和已有的shell参数变量配合默契。每次调用getopts时,它一次只处理命令行上检测到的一个参数。处理完所有的参数后,它会退出并返回一个大于0的退出状态码。getopts optstring variable。optstring和getopt的optstring一样。但是要去掉错误消息,需要在optstring之前加一个冒号。getopts命令会将当前参数保存在命令行中定义的variable中。getopts命令使用了两个环境变量,OPTARG用来保存选项的参数值,OPTIND保存了参数列表中getopts正在处理的参数位置。这样你就能在处理完选项之后继续处理其他命令行参数了。

$ cat test 
#!/bin/bash
# simple demonstration of the getopts command
#
echo
while getopts :ab:c opt
do
    case "$opt" in
    # getopts命令在解析命令行选项时会移除开头的单破折线
    a) echo "Found the -a option" ;;
    b) echo "Found the -b option, with value $OPTARG" ;;
    c) echo "Found the -c option" ;;
    *) echo "Unknown option: $opt" ;;
    esac
done
$ ./test  -ab test1 -c

Found the -a option
Found the -b option, with value test1
Found the -c option

使用shift命令和OPTIND值来移动参数,使得$@只包含额外参数部分

$ cat test 
#!/bin/bash
# simple demonstration of the getopts command
#
echo
while getopts :ab:cd opt
do
    case "$opt" in
    # getopts命令在解析命令行选项时会移除开头的单破折线
    a) echo "Found the -a option" ;;
    b) echo "Found the -b option, with value $OPTARG" ;;
    c) echo "Found the -c option" ;;
    d) echo "Found the -d option" ;;
    *) echo "Unknown option: $opt" ;;
    esac
done
#
shift $[ $OPTIND - 1 ]
#
echo 
count=1
for param in "$@"
do
    echo "Parameter $count: $param"
    count=$[ $count + 1 ]
done
$ ./test -a -b test1 -d test2 test3 test4

Found the -a option
Found the -b option, with value test1
Found the -d option

Parameter 1: test2
Parameter 2: test3
Parameter 3: test4

6. 变量替换(parameter substitution)

有: if 变量被声明了 && 变量的值不为nil; then it is set; fi 无: if 变量被声明了; then it is not set; fi

  1. ${parameter-default}, ${parameter:-default} 如果参数没有设置,就返回-后面的默认值。

  2. ${parameter=default},${parameter:=default} 如果参数没有设置过,就将它的值设置为默认值。

  3. ${parameter+alt_value},${parameter:+alt_value} If parameter set, use alt_value, else use null string.

  4. ${parameter?err_msg},${parameter:?err_msg} if parameter set, use it, else print err_msg with an exit status of 1.

7. 变量替换扩展(parameter substitution expand)

  1. ${#var} String length, for an array, ${#array} is the length of the first element in the array. 例外:
  • ${#*} and ${#@} give the number of positional parameters.
  • For an array, ${#array[*]} and ${#array[@]} give the number of elements in the array.
  1. ${var#Pattern}, ${var##Pattern} ${var#Pattern} 从前匹配,最小匹配,并删除 ${var##Pattern} 从前匹配,最大匹配,并删除
#!/bin/bash
echo `basename $PWD`  # Basename of current working directory
echo "${PWD##*/}"     # Basename of current working directory
echo
echo `basename $0`    # Name of script
echo $0               # Name of script
echo "${0##*/}"       # Name of script
echo 
filename=test.data
echo "${filename##*.}"  # Extension of filename
  1. ${var%Pattern},${var%%Pattern}
  • ${var%Pattern} 从后匹配,最小匹配,并删除
  • ${var%%Pattern} 从后匹配,最大匹配,并删除
#!/bin/bash
# rfe.sh: Renaming file extensions
#         rfe old_extention new_extension
# Example:
# To rename all *.git files in working directory to *.jpg,
#         rfe git jpg

E_BADARGS=65

case $#  in
  0|1)               # The vertical bar means "or" in this context
  echo "Usage: `basename $0` old_file_suffix new_file_suffix"
  exit $E_BADARGS    # if 0 or 1 arg, then bail out.
esac

for filename in *.$1
# Traverse list of files ending with 1st argument
do 
  mv $filename ${filename%$1}$2
  # Strip off part of filename matching 1st argument,
  #+ then append 2nd argument
done
exit 0

8.变量展开和子串替换, variable expansion / substring replacement

  1. ${var:pos} Variable var expanded, starting from offset pos

  2. ${var:pos:len} Expansion to a max of len characters of variable var, from offset pos

  3. ${var/Pattern/Replacement} First match of Pattern, within var replaced with Replacement

  4. ${var//Pattern/Replacement} Global replacement. All matches of Pattern, within var replaced with Replacement.

  5. ${var/#Pattern/Replacement} If prefix of var matches Pattern, then substitute Replacement for Pattern. Must match at beginning of string.

  6. ${var/%Pattern/Replacement} If suffix of var matches Pattern, then substitute Replacement for Pattern. Must match at end of string.

#  ----------------------------------------------------
#  Must match at beginning / end of string,
#+ otherwise no replacement results.
#  ----------------------------------------------------
v0=abc1234zip1234abc
v1=${v0/#123/000}       # Matches, but not at beginning.
echo "v1 = $v1"         # abc1234zip1234abc
                        # NO REPLACEMENT.
v2=${v0/%123/000}       # Matches, but not at end.
echo "v2 = $v2"         # abc1234zip1234abc
                        # NO REPLACEMENT.
  1. ${!varprefix*}, ${!varprefix@} Matches names of all previously declared variables beginning with varprefix.
# This is a variation on indirect reference, but with a * or @
xyz23=whatever
xyz24=

a=${!xyz*}     # Expands to *names* of declared variables
# ^ ^   ^        + beginning with "xyz".
echo "a = $a"  # a = xyz23 xyz24
a=${!xyz@}     # Same as above
echo "a = $a"  # a = xyz23 xyz24

echo "---"

abc23=something_else
b=${!abc*}
echo "b = $b"  # b = abc123
c=${!b}        # Now, the more familiar type of indirect reference.
echo $c        # something_else

间接引用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash

# Indirect variable referencing.
# This has a few of the attributes of references in C++.


a=letter_of_alphabet
letter_of_alphabet=z

echo "a = $a"           # Direct reference.

echo "Now a = ${!a}"    # Indirect reference.
#  The ${!variable} notation is more intuitive than the old
#+ eval var1=\$$var2

echo

t=table_cell_3
table_cell_3=24
echo "t = ${!t}"                      # t = 24
table_cell_3=387
echo "Value of t changed to ${!t}"    # 387
# No 'eval' necessary.

#  This is useful for referencing members of an array or table,
#+ or for simulating a multi-dimensional array.
#  An indexing option (analogous to pointer arithmetic)
#+ would have been nice. Sigh.

exit 0

# See also, ind-ref.sh example.
  1. 特殊用法$‘string’
$ echo $'\x41'
A

9. 转义

Escaping is a method of quoting single characters. The escape(\) preceding a character tells the shell to interpret that character literally.

注意: With certain commands and utilities, such as echo and sed, escaping a character may have the opposite(相反) effect - it can toggle on a special meaning for that character.

Special meanings of certain escaped character: used with echo and sed.

  1. \n means newline
  2. \r means return
  3. \t means tab
  4. \v means vertical tab
  5. \b means backspace
  6. \0xx translates to the octal(八进制) ASCII equivalent off 0nn, where nn is a string of digits

The $’…’ quoted string-expansion(字符串扩展) construct is a mechanism that uses escaped octal or hex values to assign ASCII characters to variables, e.g., quote=$’\042’. 在ASCII中,042表示双引号。

echo -e "\n"
echo -e "\taa"

# The $'\X' construct makes the -e optioin unnecessary.
echo $'\n'   # Newline.
echo $'\t'aa

# Quote (") framed by tabs. Note that '\nnn' is an octal value.
echo $'\t \042 \t'
# It also works with hexadecimal values
echo $'\t \x22 \t'

# Assigning ASCII characters to a variable.
quote=$'\042'
# Concatenating ASCII chars in a variable.
# 137 is octal ASCII code for '_'.
triple_underline=$'\127\137\137'
# 101,102,103 are octal A,B,C.
ABC=$'\101\102\103\010'

Deleting key-presses

#!/bin/bash
#!/bin/bash

key="no value yet"
while true; do
	clear
	echo "Bash Extra Keys Demo. Keys to try:"
	echo 
	echo "* Insert, Delete, Home, End, Page_Up and Page_Down"
	echo "* The four arrow keys"
	echo "* Tab, enter, escape, and space key"
	echo "* The letter and number keys, etc."
	echo
	echo "d = show date/time"
	echo "q = quit"
	echo "==============================="
	echo

	if [ "$key" = $'\x1b\x4f\x48' ]; then
		key=$'\x1b\x5b\x31\x7e'
	fi
	if [ "$key" = $'\x1b\x4f\x46' ]; then
		key=$'\x1b\x5b\x34\x7e'
	fi
	
	case "$key" in
	$'\x1b\x5b\x32\x7e')  # Insert
		echo Insert Key
   	;;
	$'\x1b\x5b\x33\x7e')  # Delete
		echo Delete Key
	;;
	$'\x1b\x5b\x31\x7e')  # Home_key_num_7
		echo Home Key
	;;
	$'\x1b\x5b\x34\x7e')  # End_key_num_1
		echo End Key
	;;
	$'\x1b\x5b\x35\x7e')  # Page_Up
		echo Page_Up
	;;
	$'\x1b\x5b\x36\x7e')  # Page_Down
		echo Page_Down
	;;
	$'\x1b\x5b\x41')      #Up_arrow
		echo Up arrow
	;;
	$'\x1b\x5b\x42')      #Down_arrow
		echo Down arrow
	;;
	$'\x1b\x5b\x43')      #Right_arrow
		echo Right arrow
	;;
	$'\x1b\x5b\x44')      #Left_arrow
		echo Left arrow
	;;
	$'\x09')              #Tab
		echo Tab Key
	;;
	$'\x0a')              #Enter
		echo Enter Key
	;;
	$'\x1b')              #Escape
		echo Escape Key
	;;
	$'\x20')              # Space
		echo Space Key
	;;
	d)
		date
	;;
	q)
		echo Time to quit...
		echo
		exit 0
	;;
	*)
		echo You pressed: \'"$Key"\'
	;;
	esac
	echo
	echo "=================================="
	
	unset K1 K2 K3
	read -s -N1 -p "Press a key: "
	K1="$REPLY"
	read -s -N2 -t 0.001
	K2="$REPLY"
	read -s -N1 -t 0.001
	K3="$REPLY"
	key="$K1$K2$K3"

done
exit $?

10. 整数类型

Integer variables in older versions of Bash were signed long(32-bit) integers, in the range of -2147483648 to 2147483647. An operation that took a variable outside these limits gave an erroneous result.

echo $BASH_VERSION    # 1.14
a=2147483646
echo "a = $a"         # a = 2147483646
let "a+=1"            # Increment "a".
echo "a = $a"         # a = 2147483647
let "a+=1"            # Increment "a" again, past the limit
echo "a = $a"         # a = -2147483648
# As of version >= 2.05b, Bash supports 64-bit integers.

# Bash does not understand floating point arithmetic. It treats numbers containing a decimal point as strings
a=1.5

let "b = $a + 1.3"  # Error.
# t2.sh: let: b = 1.5 + 1.3: syntax error in expression.
echo "b = $b"       # b=1
# so need use bc in scripts that need floating point calculations or math library functions.
  1. 位运算(bitwise operation) Their chief use seems to be manipulating and testing values read from ports or sockets.

bitwise operators(位运算操作符): « : bitwise left shift (multiple by 2 for each shift position) «= : left-shift-equal(let “var «= 2” results in var left-shifted 2 bits)

: bitwise right shift (divides by 2 for each shift position) = : right-shift-equal(inverse of «=) & : bitwise AND &= : bitwise AND-equal | : bitwise OR |= : bitwise OR-equal ~ : bitwise NOT ^ : bitwise XOR ^= : bitwise XOR-equal

  1. 逻辑运算 logical(boolean) operators(逻辑运算): ! : NOT && : AND || : OR

  2. 操作符的优先级

    Operator Meaning Comments
    var++ var– post-increment, post-decrement C-style operators
    ++var –var pre-increment, pre-decremnet
    ! ~ negation logical / bitwise, inverts sense of following operator
    ** exponentiation arithmetic operation
    * / % multiplication, division, modulo arithmetic operation
    + - addition, subtraction arithmetic operation
    « » left, right shift bitwise
    -z -n unary comparison string is/is-not null
    -e -f -t -x, etc. unary comparison file-test
    < -lt > -gt <= -le >= -ge compound comparison string and integer
    -nt -ot -ef compound comparison file-test
    == -eq != -ne equality / inequality test operators, string and integer
    & AND bitwise
    ^ XOR exclusive OR, bitwise
    OR
    && -a AND logical, compound comparison
    -o
    ?: trinary operator C-style
    = assignment (do not confuse with equality test)
    *= /= %= += -= «= »= &= combination assignment time-equal, divide-equal,mod-equal,etc.
    , comma links a sequence of operations
  3. 数组变量

mytest=(one two three four five)
# 访问数组的第一个元素
echo $mytest
# 访问数组的第三个元素
echo ${mytest[2]}
# 显示整个数组变量
echo ${mytest[*]}
# 修改第三个元素的值
mytest[2]=seven
  1. expr命令 expr命令支持的操作符:

    操作符 描述
    ARG1 | ARG2 如果ARG1既不是null也不是零值,返回ARG1;否则返回ARG2
    ARG1 & ARG2 如果没有参数是null或零值,返回ARG1;否则返回0
    ARG1 < ARG2 如果ARG1小于ARG2,返回1;否则返回0
    ARG1 <= ARG2 如果ARG1小于或等于ARG2,返回1;否则返回0
    ARG1 = ARG2 如果ARG1等于ARG2,返回1;否则返回0
    ARG1 != ARG2 如果ARG1不等于ARG2,返回1;否则返回0
    ARG1 >= ARG2 如果ARG1大于或等于ARG2,返回1;否则返回0
    ARG1 > ARG2 如果ARG1大于ARG2,返回1;否则返回0
    ARG1 + ARG2 返回ARG1和ARG2的算术运算和
    ARG1 - ARG2 返回ARG1和ARG2的算术运算差
    ARG1 \* ARG2 返回ARG1和ARG2的算术运算积, *会被shell错误解释(被错误认为是通配符),所以需要转义
    ARG1 / ARG2 返回ARG1被ARG2除的算术商
    ARG1 % ARG2 返回ARG1被ARG2除的算术余数
    STRING : REGEXP 如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
    match STRING REGEXP 如果REGEXP匹配到了STRING中的某个模式,返回该模式匹配
    substr STRING POS LENGTH 返回起始位置为POS(从1开始计数),长度为LENGTH个字符的子字符串
    index STRING CHARS 返回在STRING中找到CHARS字符串的位置;否则,返回0
    length STRING 返回字符串STRING的数值长度
    + TOKEN 将TOKEN解释成字符串,即使是个关键字
    (EXPRESSION) 返回EXPRESSION的值
  2. 执行浮点运算(bc) bc指的就是bash计算器(bash computer)。bc能够识别:数字,变量,注释(以#或C语言中的/* */),表达式,分支语句(if-then语句等),函数。

$ bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
scale
0
3.44 / 5
0
3.44 * 3
10.32

scale=4
3.44 / 5
.6880
quit

scale变量的默认值是0。在scale值被设置前,bash计算器的除法运算的结果不包含小数位。

$ bc -q
56 / 4
14
# 对变量的支持
var1=10
var1 * 4
40
# 对语句的支持
print var1
quit

-q参数可以不显示bash计算器冗长的欢迎信息。

在脚本中使用bc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 基本格式: variable=$(echo "options; expression" | bc)
# 第一部分options允许你设置变量(例如scale变量)。如果你需要不止一个变量,可以用分号将其分开。
# expression参数定义了通过bc执行的数学表达式
$ cat test9
#!/bin/bash
var1=$(echo "scale=4; 3.44 / 5" | bc)
echo the answer is $var1
$ chmod u+x test9
$ ./test9
The answer is .6880

# 在脚本中定义两个变量,并把它们作为expression的组成部分。
$ cat test10
#!/bin/bash
var1=100
var2=45
var4=$(echo "scale=4; $var1 / $var2" | bc)
echo The answer for this is $var3
$ ./test10
The answer for this is 2.2222

# 使用内联输入重定向
$ cat test12
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ($var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5

本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image