var_name="runoob",变量名和等号之间不能有空格,因为空格通常用于分隔命令和参数$var_name、${var_name},加大括号是为了帮助解释器识别变量的边界。$ 相当于从变量中取值(解引用),不加 $ 则表示变量本身readonly var_name,变量值不可被改变unset var_name,删除后不能再次使用,不能删除只读变量'或双引号"定义,var_name='zmy' var_name="zmy"。ℹ️单引号中的任何字符都会原样输出,其中的变量是无效的,单引号字符串内不能出现一个单独的单引号(转义也不行)但可成对出现,作为字符串拼接使用:
var1='zmy_'$var_name'_flm' # 输出 zmy_runoob_flmvar2='zmy_$var_name_flm' # 输出 zmy_$var_name_flmvar1="Hi, "$var_name"! \n" # 输出 Hi, runoobvar2="Hi, ${var_name}! \n" # 输出 Hi, runoobstring="runoob is a great site"echo `expr index "$string" io` # 输出 4declare -i my_int=42# 使用 (( )) 算术表达式(推荐)a=2((a++)) # a 自增 1 → a=3((a--)) # 自减((a += 1)) # 等价于 a = a + 1((a = a + 1))# 使用 $(( )) 算术扩展a=2a=$((a + 1)) # a=3a=$((a * 2)) # a=6# 使用 let 命令(较老,不推荐)a=2let a=a+1let "a += 1" # 带空格时需加引号my_array=(1 2 3 4 5 6)declare -A my_array, my_array['name']='zmy',my_array['age']=30# 获取数组的某个值value=${my_array[n]}# 使用 @ 或 * 获取数组中所有元素${my_array[@]}${my_array[*]}# 使用 ! 获取数组中所有键${!my_array[@]}${!my_array[*]}# 获取数组元素的个数length=${#my_array[@]}; length=${#my_array[*]}# 获取单个元素的长度length=${#my_array[n]}# 判断关联数组中是否存在键if [[ -n "${my_array[$key]+exists}" ]]; then echo "$key 存在"fiif [[ -v "my_array[$key]" ]]; then echo "$key 存在"fi# 判断普通数组中是否存在值[[ "${my_array[*]}" =~ "$value" ]] && echo "存在" || echo "不存在"mapfile 是一个强大的内置命令,用于将文件或标准输入的内容按行读入数组。它等价于 readarray,语法和功能完全一致。# 如果不指定数组名,数据将默认存储到 MAPFILE 数组中。mapfile [选项] 数组名 < 输入源# 或mapfile [选项] 数组名 文件名-n count 最多读取 count 行-O origin 从数组索引 origin 开始赋值(默认 0)-s count 跳过前 count 行-t 删除每行末尾的换行符(默认行为)-d DELIM 指定行分隔符(默认是换行符)-u fd 从文件描述符 fd 读取(默认 0)-C callback 每读 callback 行调用一次命令-c quantum 与 -C 搭配,指定调用频率,每读取 quantum 行执行一次回调(包括当前行)⚠️
回调是在读取过程中触发,不是读取完成后 每次回调时,数组只包含当前已读取的行 执行回调时,会传递两个参数 $1: 当前正在读取的行号,从 0 开始,$2: 当前正在读取的行内容利用回调时的数组长度(等于 $1参数)
$0 脚本名称$1-$9 第1-9个位置参数${10} 第10个参数(需要大括号)$# 参数个数$@ 所有参数,每个都是独立字符串,如果 "$@" 则以 "$1" "$2" ... "$n" 的形式输出所有参数$* 所有参数,作为一个字符串,如果是 "$*" 则以 "$1 $2 ... $n" 的形式输出所有参数$$ 当前进程PID$! 最后一个后台进程的PID$? 上一个命令的退出状态码$_ 上一个命令的最后一个参数$- 当前shell选项标记!! 上一条命令$BASH Bash的完整路径$BASH_VERSION Bash版本$BASH_VERSINFO[0-6] Bash版本信息数组$BASH_SOURCE 当前执行的源文件(脚本)路径$BASH_SUBSHELL 子shell层级$LINENO 当前在脚本中的行号$FUNCNAME 当前函数名(数组,[0] 是当前函数)$BASH_COMMAND 当前正在执行的命令$PIPESTATUS 管道中每个命令的退出状态数组$SECONDS 脚本运行秒数$RANDOM 随机数(0-32767)$REPLY read命令默认读取的变量$OPTARG getopts的选项参数$OPTIND getopts的选项索引$COLUMNS 终端列数$LINES 终端行数$UID 当前用户UID$EUID 当前有效用户UID$GROUPS 用户所属组数组$BASH_XTRACEFD 用于set -x输出的文件描述符$BASH_LINENO 函数调用栈的行号数组$BASH_ARGC 函数参数个数数组$BASH_ARGV 函数参数值数组$IFS 内部字段分隔符(默认是空格、制表符、换行)$GLOBIGNORE 通配符忽略模式$BASH_REMATCH 正则表达式匹配结果数组$BASH_ALIASES 别名数组$BASH_CMDS 命令哈希表# 这是一个注释:是空命令,内容不会执行:<<EOF(EOF也可以使用其他符号:COMMENT ' !)注释内容注释内容注释内容EOF: '这是注释的部分。可以有多行内容。'echo, "当前目录: $PWD", *.txt{}b. 波浪号展开 ~c. 参数展开 $d. 命令替换 $()e. 算术展开 $(( ))f. 单词分割g. 文件名展开 * ? [...]parameter 是数字,则是参数扩展;如果 parameter 是字符串,则是变量扩展;如果 parameter 是数组,遵循数组的扩展规则;parameter 还可以是 @, *, #, ?, - 等,参考特殊参数的扩展。# 无引号:Shell 扩展echo *.txt # Shell 扩展# 单引号:完全字面echo '*.txt' # 输出: *.txt# 双引号:变量扩展,但通配符不扩展echo "$HOME/*.txt" # 输出: /home/user/*.txtℹ️除了
${variable:=word}和${variable::=word}(强制修改变量为word无论原变量是否为空,Bash 4.4+ 新增)之外,其他变量扩展不会修改变量的值,仅是返回扩展结果
直接扩展和间接扩展 a=b; b=123;
echo ${a} 基本扩展,输出结果为 becho ${!a} 间接参数扩展,输出结果为变量 b 的值 123,${!var}将参数扩展为变量的值,在处理变量名作为字符串时很有用b 是一个名称引用(nameref),则不会发生间接扩展,还是输出 b变量引用
${variable} 或 $variable 直接引用变量的值设置默认值
${variable:-word} - 如果变量 variable 已被设置且非空,则展开为变量的值;否则,展开为 word。${variable:=word} - 类似于 ${variable:-word},但是还会将 word 的值赋给变量 variable。${variable:+word} - 如果变量 variable 已被设置且非空,则展开为 word;否则,什么也不做。${variable:?word} - 如果变量 variable 已被设置且非空,则展开为变量的值;否则,打印错误消息至标准错误并退出 shell,错误消息包含 word字符删除
? 匹配任何一个字符。* 匹配任意数量的字符(包括零个字符)。[...] 匹配括号内的任何一个字符。例如,[abc] 匹配 'a'、'b' 或 'c'。{a,b,c} 匹配 a 或 b 或 c。ℹ️
pattern必须能够匹配开头(对于%)或者结尾(对于#),如果只匹配了中间部分则无法删除
${variable/pattern/string} 替换变量值 variable 的第一次出现的 pattern 为 string。${variable//pattern/string} 替换变量值 variable 中所有出现的 pattern 为 string。${variable/#pattern/string}:如果变量 variable 值以 pattern 开头,则将其替换为 string${variable/%pattern/string}:如果变量 variable 值以 pattern 结尾,则将其替换为 stringℹ️其中
/string部分可省略,表示替换为空,即删除,例如${url//:*}删除:之后的所有内容
子字符串截取
${variable:start:length} - 截取变量值 variable 的子字符串,从索引 start 开始(从0开始计数),长度为 length 字符。${variable:start} - 截取变量值 variable 的子字符串,从索引 start 开始(从0开始计数)直到末尾。大小写转换
${variable,,} - 将变量值 variable 转换为小写。${variable^^} - 将变量值 variable 转换为大写。${parameter^pattern} 和 ${parameter^^pattern} 用于将变量值中的匹配部分转换为大写,分别转换第一个匹配和所有匹配。${parameter,pattern} 和 ${parameter,,pattern} 用于将变量值中的匹配部分转换为小写,分别转换第一个匹配和所有匹配。${variable@operator}operator 取值:U 全大写u 首字母大写L 全小写K 显示变量的赋值语句格式,字符串会被引号包裹Q 转义字符生成E 转义字符展开P 提示符展开A 显示变量的声明语句K 数组变量名和值k 数组变量名和值a 返回变量属性值, 表示为一系列标志:-:变量既没有被引号引用,也不是数组。q:变量被单引号引用。Q:变量被双引号引用。x:变量是被解释的。X:变量是被不被解释的。@:变量是数组或者关联数组。A:变量是被赋值的(assigned)。欢迎大家关注我的微信公众号【扶锐随笔】