shell脚本变量详解
什么是变量
顾名思义,变量就是程序设计语言中的一个可以变化的量,当然,可以变化的是变量的值。几乎所有的程序设计语言都有定义变量,并且其涵义也大同小异。从本质上讲,变量就是在程序中保存用户数据的一块内存空间,而变量名就是这块内存空间的地址。在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的变量名却保持不变。
变量命名
在Shell中,变量名可以由字母、数字或者下划线组成,并且只能以字母或者下划线开头。对于变量名的长度,Shell没有做出明确的规定。因此,用户可以使用任意长度的字符串来作为变量名。但是,为了提高程序的可读性,建议用户使用相对较短的字符串作为变量名。在一个设计良好的程序中,变量的命名有着非常大的学问。通常情况下,用户应该尽可能选择有明确意义的英文单词作为变量名,尽量避免使用拼音或者毫无意义的字符串作为变量名。这样的话,用户通过变量名就可以了解该变量的作用。
变量的类型
根据数据类型分类
什么是弱类型语言、强类型语言?
declare
命令参数详解
参数 | 功能描述 | 示例 |
---|---|---|
- | 指定变量的属性(如 -i , -r , -a , -x )。 | declare -i COUNT=10 (定义整数变量) |
+ | 取消变量的属性(与 - 相反)。 | declare +x VAR (取消环境变量属性) |
-p | 显示变量的属性和值(若未指定变量名,则显示所有变量)。 | declare -p PATH (显示 PATH 变量的属性和值) |
-i | 将变量定义为整数类型,支持算术表达式。计算失败时返回 0。 | declare -i A=5+3; echo $A (输出 8) |
-r | 将变量声明为只读(等同于 readonly ),不可修改或删除。 | declare -r PI=3.14; PI=3 (报错:只读变量不可修改) |
-a | 将变量声明为数组(默认支持,无需显式声明)。 | declare -a FRUITS=("apple" "banana"); echo ${FRUITS[1]} (输出 banana) |
-f | 显示所有自定义函数的名称和函数体(若指定函数名,则只显示该函数)。 | declare -f (显示所有函数) |
-x | 将变量设置为环境变量(等同于 export ),使其在子进程中可用。 | declare -x DB_HOST=localhost (设置环境变量) |
部分代码示例:
#声明整数型变量
[root@kittod ~]# declare -i ab
[root@kittod ~]# ab=33
[root@kittod ~]# echo $ab
33
#改变变量属性
[root@kittod ~]# declare -i ef
[root@kittod ~]# ef=1
[root@kittod ~]# echo $ef
1
[root@kittod ~]# ef="wer"
[root@kittod ~]# echo $ef
0
[root@kittod ~]# declare +i ef
[root@kittod ~]# ef="wer"
[root@kittod ~]# echo $ef
wer
#设置变量只读
[root@kittod ~]# declare -r ab
[root@kittod ~]# ab=22
-bash: ab: readonly variable
[root@kittod ~]# echo $ab
33
#声明数组变量
[root@kittod ~]# declare -a cd='([0]="a" [1]="b" [2]="c")'
[root@kittod ~]# echo ${cd[1]}
b
[root@kittod ~]# echo ${cd[@]}
a b c
根据作用域分类
1、环境变量
环境变量也可称为全局变量,可以在创建它们的shell及其派生出来的任意子进程shell中使用(su - 切换用户会读取新的环境变量),环境变量又可分为自定义环境变量和bash内置的环境变量。
(1)自定义环境变量
一般是指用export(shell脚本基础中详细解释)内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,即该环境变量只在当前shell和子shell中有效。如果希望永久保存环境变量,可以在配置文件中设置。
①用户的环境变量配置(non-login shell)
/.bash_profile或/.bashrc
②全局环境变量的配置(login shell)
/etc/bashrc、/etc/profile文件或者/etc/profile.d目录中定义。
注意:按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用命令export导出。有一些环境变量,比如HOME,PATH,SHELL,UID,USER等,在用户登录前就已经被/bin/login程序设置好了,通常环境变量被定义并保存在用户家目录下的.bash_profile文件或全局的配置文件/etc/profile中。
(2)bash内置的环境变量
shell内置的环境变量是所有的shell程序都可以使用的变量。shell程序在运行时,都会接收一组变量来确定登录用户名、命令路径、终端类型、登录目录等,这组变量就是环境变量。环境变量会影响到所有的脚本的执行结果。
以下是一些常见的 Bash 内置环境变量:
变量名 | 描述 |
---|---|
HOME | 用户的主目录路径。 |
PATH | 用于指定命令的搜索路径,多个路径之间用冒号(: )分隔。 |
PWD | 当前工作目录的绝对路径。 |
OLDPWD | 上一个工作目录的绝对路径。 |
USER | 当前登录的用户名。 |
UID | 当前用户的 ID 号。 |
SHELL | 用户当前使用的 shell 程序的路径。 |
TERM | 终端类型,用于确定终端的功能和特性,常见的值有 xterm 、vt100 等。 |
LANG | 系统的语言环境设置,影响字符编码、排序规则等。 |
LC_ALL | 用于覆盖 LANG 变量,设置整个本地化环境。 |
PS1 | 命令行提示符的设置字符串,用于定义命令行的显示格式。 |
PS2 | 当命令未结束,需要继续输入时显示的提示符,默认为 > 。 |
IFS | 内部字段分隔符,用于分割命令输出或变量值的字符串,默认为空格、制表符和换行符。 |
BASH_VERSION | 当前 Bash shell 的版本号。 |
HISTSIZE | 历史命令记录的最大数量。 |
HISTFILESIZE | 历史命令文件的最大大小。 |
注:可使用env查看环境变量
局部变量
函数中区别(代码示例)
[root@kittod ~]# vim vartest.sh
#!/bin/bash
#定义函数
func()
{
#输出全局变量v1的值
echo "global variable v1 is $v1"
#定义局部变量v1
local v1=2
#输出局部变量v1的值
echo "local variable v1 is $v1"
}
#定义全局变量v1
v1=1
#调用函数
func
#输出全局变量v1的值
echo "global variable v1 is $v1"
[root@kittod ~]# chmod a+x vartest.sh
[root@kittod ~]# ./vartest.sh
global var v1 is 1
local var v1 is 2
global var v1 is 1
变量的定义
1、变量定义示例:变量名=变量值
#定义变量a
a=1
#定义变量b
b="hello"
#定义变量c
c="hello world"
#定义备份路径
bak_dir=/data/backup
#把一个命令的结果赋值变量
变量名=`ls`
变量名=$(ls)
[root@localhost ~]# a= 3
-bash: 3: 未找到命令
[root@localhost ~]# b =4
-bash: b: 未找到命令
stu_name="zhang san"
2、位置参数和预定义变量
以下是一些常见的 Bash 预定义变量:
变量名 | 描述 |
---|---|
$0 | 当前脚本或命令的名称。 |
$1 - $9 | 脚本或函数的位置参数,$1 是第一个参数,$2 是第二个参数,以此类推。 |
$# | 传递给脚本或函数的参数数量。 |
$@ | 表示所有的位置参数,是一个包含所有参数的列表,在引用时会将每个参数作为独立的字符串处理。 |
$* | 与 $@ 类似,但它将所有参数作为一个字符串处理,参数之间用 IFS 的第一个字符分隔。 |
$$ | 当前进程的 PID(进程 ID)。 |
$? | 上一个命令或函数的退出状态码,0 表示成功,非 0 表示失败。 |
$- | 当前 shell 的选项标志,是一个包含当前 shell 启用的选项的字符串。 |
$! | 最后一个在后台运行的进程的 PID。 |
shell中的引用(部分特殊符号)

[root@kittod ~]# echo "current user is: $USER"
current user is: root
[root@kittod ~]# echo 'current user is: $USER'
current user is: $USER
[root@kittod ~]# echo "current user is: `whoami`"
current user is: root
[root@kittod ~]# echo 'current user is: `whoami`'
current user is: `whoami`
变量的运算
expr
命令的基本语法及其现代替代方式
expr
用于计算表达式的值,语法为:
expr 表达式
例如:
expr 2 + 3 # 输出5
expr 5 \* 2 # 注意:乘号需要转义为\*
反引号(`
)的作用
反引号用于命令替换,即将命令的输出结果替换到当前位置。
例如,若要将expr
的计算结果赋值给变量,需用反引号包裹expr
命令:
result=`expr 2 + 3`
echo $result # 输出5
等价于更现代的$()
语法:
result=$(expr 2 + 3)
echo $result # 输出5
常见错误示例
错误写法:
# 错误1:用反引号包裹表达式内部
result=expr `2 + 3` # 错误!Bash会尝试执行"2 + 3"命令# 错误2:未正确转义特殊字符
result=$(expr 2 * 3) # 错误!*会被解释为通配符
正确写法:
result=$(expr 2 \* 3) # 正确:用\*转义乘号
推荐替代方案
expr
语法繁琐(需转义运算符),现代 Bash 推荐使用$(( ))
进行算术扩展:
result=$((2 + 3)) # 无需转义,更简洁
result=$((2 * 3)) # 正确:乘号无需转义
echo $((result / 2)) # 直接计算并输出
总结表格
需求 | 正确语法示例 | 说明 |
---|---|---|
直接计算并打印结果 | expr 2 + 3 | 输出 5 |
将结果赋值给变量 | result=$(expr 2 + 3) | 使用$() 或反引号包裹整个expr 命令 |
复杂表达式计算 | result=$((2 + 3 * 4)) | 推荐$(( )) 语法,无需转义运算符 |
关键区别
语法 | 用途 | 示例 |
---|---|---|
expr ... | 计算表达式的值 | expr 5 - 2 → 3 |
`expr ...` | 获取expr 的结果并替换到命令中 | echo $(expr 5 - 2) → "3" |
$(( ... )) | 算术扩展,更强大的表达式计算 | echo $((5 - 2)) → "3" |
合理使用这些语法可以避免不必要的错误,提高脚本的可读性和效率。
基本测试语法

算数运算符
运算符 | 描述 | 示例 |
---|---|---|
+ | 加法 | expr 5 + 3 结果为 8 |
- | 减法 | expr 5 - 3 结果为 2 |
* | 乘法 | expr 5 \* 3 结果为 15(注意在 Bash 中乘法运算符需要转义,(())无需转义 |
/ | 除法 | expr 5 / 3 结果为 1(整数除法,结果取整) |
% | 取模(取余数) | expr 5 % 3 结果为 2 |
++ | 自增 | a=5; ((a++)) 后,a 的值变为 6 |
-- | 自减 | a=5; ((a--)) 后,a 的值变为 4 |
在 Bash 中,也可以使用 (( ))
来进行更简洁的算数运算,例如 ((a = 5 + 3))
,这种方式不需要使用 expr
命令,并且支持更多的算数运算特性。同时,还可以使用 let
命令来进行算数运算,如 let a=5+3
,效果与 (( ))
类似。
赋值运算符
运算符 | 等价形式 | 示例 (a=5 ) | 结果 |
---|---|---|---|
= | 直接赋值 | a=10 | a=10 |
+= | 加后赋值 | ((a += 3)) | a=8 |
-= | 减后赋值 | ((a -= 3)) | a=2 |
*= | 乘后赋值 | ((a *= 3)) | a=15 |
/= | 除后赋值 | ((a /= 3)) | a=1 |
%= | 取模后赋值 | ((a %= 3)) | a=2 |
比较运算符
数值比较
运算符 | 描述 | 示例 (a=5; b=3 ) | 结果 |
---|---|---|---|
-eq | 等于 | [ $a -eq $b ] && echo true | false |
-ne | 不等于 | [ $a -ne $b ] && echo true | true |
-gt | 大于 | [ $a -gt $b ] && echo true | true |
-lt | 小于 | [ $a -lt $b ] && echo true | false |
-ge | 大于等于 | [ $a -ge $b ] && echo true | true |
-le | 小于等于 | [ $a -le $b ] && echo true | false |
(()):
[root@kittod ~]# (( 2!=3 ));echo $?
0
[root@kittod ~]# ((2!=3));echo $?
0
[root@kittod ~]# ((2=3));echo $?
-bash: ((: 2=3: attempted assignment to non-variable (error token is
"=3")
1
[root@kittod ~]# ((2==3));echo $?
1
[root@kittod ~]# ((2>3));echo $?
1
[root@kittod ~]# ((2<3));echo $?
0[[]]:
[root@kittod ~]# [[ 2 != 3 ]];echo $?
0
[root@kittod ~]# [[ 2 != 2 ]];echo $?
1
[root@kittod ~]# [[ 2!=2 ]];echo $? 未写空格,导致出错
0[]:
[root@kittod ~]# [ 2 -ne 3 ];echo $?
0
[root@kittod ~]# [ 2 -ne 2 ];echo $?
1test:
[root@kittod ~]# test 2 -eq 3;echo $?
1
[root@kittod ~]# test 2 -eq 2;echo $?
0
字符串比较
运算符 | 描述 | 示例 (str1="abc"; str2="def" ) | 结果 |
---|---|---|---|
= | 等于 | [ "$str1" = "$str2" ] | false |
!= | 不等于 | [ "$str1" != "$str2" ] | true |
-z | 字符串为空 | [ -z "$str1" ] | false |
-n | 字符串非空 | [ -n "$str1" ] | true |
操作符 | 功能描述 | 示例 | 返回值($? ) |
---|---|---|---|
-z | 检查字符串长度是否为 0(空字符串) | [ -z "" ] | 0 (成功) |
-z | 检查变量是否为空 | str=""; [ -z "$str" ] | 0 (成功) |
-z | 检查命令输出是否为空 | output=$(ls /nonexistent); [ -z "$output" ] | 0 (成功) |
文件测试运算符
结果都是true/false,两个表格存在重复。
操作符 | 功能 | 示例 |
---|---|---|
-e | 文件或目录存在 | [ -e "path" ] |
-f | 是普通文件 | [ -f "file.txt" ] |
-d | 是目录 | [ -d "dir" ] |
-r | 有读权限 | [ -r "file.txt" ] |
-w | 有写权限 | [ -w "file.txt" ] |
-x | 有执行权限 | [ -x "script.sh" ] |
-s | 文件大小不为 0 | [ -s "data.log" ] |
-O | 用户拥有该文件 | [ -O "$HOME/file" ] |
-N | 文件自上次读取后被修改 | [ -N "config.ini" ] |
f1 -nt f2 | 文件 f1 比 f2 新 | [ "new.txt" -nt "old.txt" ] |
f1 -ot f2 | 文件 f1 比 f2 旧 | [ "old.txt" -ot "new.txt" ] |
运算符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位 (Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-s file | 检测文件是否为空(文件大小是否大于 0),不为空返回 true。 | [ -s $file ] 返回 true。 |
测试代码示例:
test:
[root@kittod ~]# test -f file;echo $?
1
[root@kittod ~]# touch file
[root@kittod ~]# test -f file;echo $?
0
[root@kittod ~]# test -f file1;echo $?
1
[root@kittod ~]# test -x file;echo $?
1
[root@kittod ~]# ll
total 4
-rw-------. 1 root root 1263 Dec 16 19:11 anaconda-ks.cfg
-rw-r--r--. 1 root root 0 Apr 25 22:14 file
[root@kittod ~]# chmod +x file
[root@kittod ~]# test -x file;echo $?
0[]:
[root@kittod ~]# [ -f file ];echo $?
0
[root@kittod ~]# [ -f file1 ];echo $?
1
[root@kittod ~]# [ -w file1 ];echo $?
1
[root@kittod ~]# ll
total 4
-rw-------. 1 root root 1263 Dec 16 19:11 anaconda-ks.cfg
-rwxr-xr-x. 1 root root 0 Apr 25 22:14 file
[root@kittod ~]# [ -w file ];echo $?
0[[]]:
[root@localhost test3]# ll
total 0
-rw-r--r--. 1 root root 0 Feb 20 10:35 file
[root@localhost test3]# [[ -f file ]];echo $?
0
[root@localhost test3]# [[ -f file1 ]];echo $?
1
[root@localhost test3]# [[ -x file1 ]];echo $?
1路径用变量来代替
注意:如果测试的文件路径是用变量来代替,变量一定要加引号[root@localhost test3]# echo $filepath 该变量值为空
[root@localhost test3]# test -f $filepath;echo $?
0
[root@localhost test3]# test -f "$filepath";echo $?
1但是当变量不为空时正常:
[root@free etc]# echo $path
/etc
[root@free etc]# test -d $path;echo $?
0
练习:
read -p "input a filename:" filename
test -z $filename && echo "you must input a filename" && exit 0
test ! -e $filename && echo "the file $filename do not exist" && exit 0
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
echo "the $filename is a $filetype"
echo "and the permissons are: $perm"
布尔运算符,逻辑运算符
一、逻辑运算符(用于条件判断)
运算符 | 描述 | 语法示例 | 说明 | |
---|---|---|---|---|
&& | 逻辑与(短路与) | cmd1 && cmd2 | 如果 cmd1 成功(返回 0),则执行 cmd2 ;否则跳过 cmd2 。 | |
|| | 逻辑或(短路或) | cmd1 || cmd2 |
| |
! | 逻辑非 | ! cmd | 反转 cmd 的退出状态(成功变失败,失败变成功)。 |
二、测试命令中的布尔组合
1. [ ]
语法(传统测试)
运算符 | 描述 | 语法示例 | 说明 | ||
---|---|---|---|---|---|
-a | 逻辑与 | [ condition1 -a condition2 ] | 同时满足两个条件时返回真。注意:在 [[ ]] 中无效,建议用 && 。 | ||
-o | 逻辑或 | [ condition1 -o condition2 ] | 满足任一条件时返回真。注意:在 [[ ]] 中无效,建议用 ` | `。 | |
! | 逻辑非 | [ ! condition ] | 条件不成立时返回真。 |
2. [[ ]]
语法(增强型测试)
运算符 | 描述 | 语法示例 | 说明 |
---|---|---|---|
&& | 逻辑与 | [[ condition1 && condition2 ]] | 更现代的写法,支持短路求值(前一个条件为假时不再执行后一个)。 |
|| | 逻辑或 | [[ condition1 || condition2 ]] | 更现代的写法,支持短路求值(前一个条件为真时不再执行后一个)。 |
! | 逻辑非 | [[ ! condition ]] | 条件不成立时返回真。 |
代码示例:
[root@kittod ~]# cat luoji.sh
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
[root@kittod ~]# bash luoji.sh
返回 false
返回 truetest:
[root@kittod ~]# ll
total 0
-rw-r--r--. 1 root root 0 Apr 26 15:42 ceshi
-rw-r--r--. 1 root root 0 Apr 26 15:42 file
[root@kittod ~]# test -f file && echo 1 || echo 0
1
[root@kittod ~]# test -f file1 && echo 1 || echo 0
0
[root@kittod ~]# ! test -f file;echo $?
1
注:命令1 && 命令2,如果命令1执行不成功,则命令2不执行。
命令3 || 命令4,如果命令3成功,不执行命令4;如果命令3不成功,则执行命令4[]:
[root@kittod ~]# [ -f ceshi && -f file ];echo $?
-bash: [: missing `]'
2
[root@kittod ~]# [ -f ceshi || -f file ];echo $?
-bash: [: missing `]'
-bash: -f: command not found
127
[root@kittod ~]# [ -f file ] && [ -f ceshi ];echo $?
0
[root@kittod ~]# [ -f file ] || [ -f ceshi ];echo $?
0
[root@kittod ~]# [ -f file ] || [ -d ceshi ];echo $?
0
[root@kittod ~]# [ -f file1 ] || [ -d ceshi ];echo $?
1[[]]:
[root@kittod ~]# touch file
[root@kittod ~]# touch ceshi
[root@kittod ~]# [[ -f file && -f ceshi ]];echo $?
0
[root@kittod ~]# [[ -f file || -f ceshi ]];echo $?
0
[root@kittod ~]# [[ -f file && -d ceshi ]];echo $?
1(()):
[root@kittod ~]# ((2>3&&3>4));echo $?
1
[root@kittod ~]# ((2<3&&3<4));echo $?
0
变量扩展表达式
变量扩展表达式汇总表
表达式 | 说明 | 示例 (parameter="hello_world.txt" ) | 结果 |
---|---|---|---|
${parameter} | 返回变量的内容。 | ${parameter} | hello_world.txt |
${#parameter} | 返回变量内容的长度(按字符)。 | ${#parameter} | 15 |
${parameter:offset} | 从位置 offset 开始提取子串到结尾(位置从 0 开始)。 | ${parameter:6} | world.txt |
${parameter:offset:length} | 从位置 offset 开始提取长度为 length 的子串。 | ${parameter:6:5} | world |
${parameter#word} | 从开头删除最短匹配的 word 子串(贪心匹配)。 | ${parameter#*.} | txt |
${parameter##word} | 从开头删除最长匹配的 word 子串(非贪心匹配)。 | ${parameter##*.} | txt |
${parameter%word} | 从结尾删除最短匹配的 word 子串。 | ${parameter%.*} | hello_world |
${parameter%%word} | 从结尾删除最长匹配的 word 子串。 | ${parameter%%_*} | hello |
${parameter/pattern/string} | 使用 string 替换第一个匹配的 pattern 。 | ${parameter/_/-} | hello-world.txt |
${parameter//pattern/string} | 使用 string 替换所有匹配的 pattern 。 | ${parameter//_/-} | hello-world.txt |
${parameter/#pattern/string} | 仅替换开头匹配的 pattern 。 | ${parameter/#hello/hi} | hi_world.txt |
${parameter/%pattern/string} | 仅替换结尾匹配的 pattern 。 | ${parameter/%.txt/.md} | hello_world.md |
特殊情况说明
-
负偏移:
offset
为负数时,表示从字符串末尾倒数:${parameter: -4} # 从倒数第4个字符开始到结尾 → ".txt"
-
模式匹配规则:
word
和pattern
支持通配符(如*
、?
)。#
和%
用于删除匹配的内容,而/
用于替换。
-
空变量处理:
var="" ${var:-default} # 若var为空,返回default → "default" ${var:=default} # 若var为空,设置var为default并返回 → "default"
常见应用场景
需求 | 表达式示例 | 说明 |
---|---|---|
提取文件名扩展名 | ${filename##*.} | 从开头删除最长匹配的 *. ,剩下扩展名(如 txt )。 |
提取文件名(不含扩展名) | ${filename%.*} | 从结尾删除最短匹配的 .* ,剩下文件名(如 hello_world )。 |
替换路径中的目录名 | ${path//old/new} | 将路径中所有 old 替换为 new (如 /old/dir → /new/dir )。 |
截取子串 | ${str:3:5} | 提取从位置 3 开始的 5 个字符(如 hello → llo )。 |
注意事项
-
空格敏感:
${parameter: offset:length}
(带空格)会导致错误,必须写成${parameter:offset:length}
。 -
模式与正则:
这些表达式使用的是通配符模式(如*
匹配任意字符),而非正则表达式。若需正则,可使用[[ $var =~ regex ]]
。 -
变量不存在:
若变量未定义,直接使用${var}
会报错,建议用${var:-default}
提供默认值。
通过这些变量扩展表达式,你可以在 Bash 中高效地处理字符串、路径和文件名,而无需依赖外部命令(如 sed
、awk
)。
示例代码
截取字符串:
[root@localhost ~]# str1="hello world"
#返回变量长度
[root@localhost ~]# echo ${#str1}
11
#变量截取
#指定起始位置,一直到结束
[root@localhost ~]# echo ${str1:1}
ello world
#指定长度,不指定起始位置默认从开头开始
[root@localhost ~]# echo ${str1::3}
hel
#指定起始位置和长度
[root@localhost ~]# echo ${str1:1:3}
ell
#从右边第几个字符开始,及字符的个数
[root@localhost ~]# echo ${str1:0-1:1}
d
#输出右边的几个字符
[root@localhost ~]# echo ${str1:0-5}
world
[root@localhost ~]# echo ${str1: -5}
world
#提取完整字符串
[root@localhost ~]# echo ${str1:-5}
hello world删除字符串:
#获取后缀名tar.gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename#*.}
[root@localhost ~]# echo $file
tar.gz
#获取后缀名.gz
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename##*.}
[root@localhost ~]# echo $file
gz
#截取testfile.tar
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%.*}
[root@localhost ~]# echo $file
testfile.tar
#截取testfile
[root@localhost ~]# filename=testfile.tar.gz
[root@localhost ~]# file=${filename%%.*}
[root@localhost ~]# echo $file
testfile