Shell 变量是 Shell 脚本中的一个重要组成部分,它们允许你存储和操作数据。以下按章节详细介绍 Shell 的变量。
1. 变量的定义与赋值
Shell 变量的定义和赋值非常简单,只需使用=
符号将值赋予变量名:
variable_name=value
注意:
- 变量名不能有空格,且不能以数字开头。
- 赋值语句中不能有空格,例如
name = value
是错误的。
示例:
name="John"
age=30
2. 变量的引用
要引用变量的值,需要在变量名前加上$
符号:
echo $variable_name
示例:
echo $name # 输出 "John"
echo $age # 输出 "30"
注意:
- 如果你需要在复杂的字符串中引用变量,建议使用花括号将变量名包裹起来以避免歧义:
echo "Hello, ${name}!"
3. 变量的作用域
Shell 变量有两种作用域:
3.1. 局部变量
默认情况下,所有在当前 Shell 会话中定义的变量都是局部变量,只有在当前 Shell 或脚本中可见,子进程不可访问这些变量。
示例:
foo="local_value"
bash -c 'echo $foo' # 子 Shell 中不可见,输出为空
3.2. 环境变量
如果你希望某个变量可以被子进程(例如 Shell 脚本中的另一个命令)访问,则需要将其导出为环境变量:
export variable_name
示例:
export PATH="/usr/local/bin:$PATH"
bash -c 'echo $PATH' # 子 Shell 中可见
4. 特殊变量
Shell 提供了一些预定义的特殊变量,用于获取特定的状态或信息:
$0
: 当前脚本或命令的名称$1, $2, ..., $n
: 传递给脚本或函数的参数$#
: 参数的个数$@
: 传递给脚本或函数的所有参数(作为独立的字符串处理)$*
: 传递给脚本或函数的所有参数(作为单个字符串处理)$?
: 上一个命令的退出状态$$
: 当前 Shell 进程的 PID$!
: 最近执行的后台命令的 PID
示例:
#!/bin/bash
echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"
echo "Total arguments: $#"
5. 位置变量与参数传递
在执行脚本时,可以通过命令行向脚本传递参数,这些参数通过位置变量(如 $1
, $2
等)获取。
./script.sh arg1 arg2
在脚本中:
echo "Argument 1: $1"
echo "Argument 2: $2"
6. 变量的操作
Shell 提供了很多操作变量的方式,常见的有字符串操作、算术操作和数组操作。
6.1. 字符串操作
可以通过以下方式操作字符串:
获取字符串长度:
${#variable}
str="Hello" echo ${#str} # 输出 5
子字符串提取:
${variable:position:length}
echo ${str:1:3} # 输出 "ell"
替换子字符串:
${variable/pattern/replacement}
str="apple orange apple" echo ${str/apple/banana} # 替换第一个出现的 "apple" 为 "banana" echo ${str//apple/banana} # 替换所有出现的 "apple" 为 "banana"
6.2. 算术操作
Shell 允许使用 let
、$(( ))
、expr
来进行简单的算术运算:
a=5
b=3
let sum=a+b
echo $sum # 输出 8
echo $((a * b)) # 输出 15
6.3. 数组操作
Bash 支持一维数组,数组中的元素可以通过索引访问:
arr=(10 20 30)
echo ${arr[0]} # 输出 10
echo ${arr[@]} # 输出所有元素
echo ${#arr[@]} # 输出数组长度
7. 变量的删除
可以通过 unset
命令删除变量:
unset variable_name
删除后,变量将不再有效。
示例:
unset name
echo $name # 不会输出任何内容
8. 只读变量
通过 readonly
命令将变量设置为只读,一旦设置,该变量将无法再修改:
readonly variable_name
示例:
readonly pi=3.1415
pi=3.14 # 报错:无法修改只读变量
9. 变量的默认值
使用默认值机制,可以确保变量在未定义时具有一个默认值:
- 如果变量未定义,则使用默认值:
${variable:-default}
- 如果变量未定义或为空,则使用默认值:
${variable:=default}
- 如果变量未定义,则输出错误并退出:
${variable:?error_message}
- 如果变量已定义,则替换其值:
${variable:+new_value}
示例:
name=${name:-"Default Name"} # 如果 $name 未定义,赋值为 "Default Name"
10. 小结
Shell 变量是 Shell 编程的基础工具,通过变量,可以有效地存储、传递、操作数据。熟练掌握 Shell 变量的定义、作用域、操作和一些特殊的处理方式,可以极大提高编写 Shell 脚本的效率。
在 Shell 编程中,##
和 %%
是字符串操作中非常有用的符号,它们用于模式匹配和字符串截取。它们属于参数扩展的一部分,允许我们根据指定的模式修改或操作变量的值。现在,我来补充这部分内容。
11. 字符串模式匹配操作
Shell 提供了一些模式匹配符来进行字符串的删除操作,主要包括 #
、##
、%
和 %%
。这些符号用于匹配和截取字符串的前缀或后缀。
11.1. 删除字符串的前缀
#
:从变量开头删除最短匹配的字符串。##
:从变量开头删除最长匹配的字符串。
示例:
filename="path/to/my/file.txt"
# 删除最短匹配的前缀
echo ${filename#*/} # 输出 "to/my/file.txt"
# 删除最长匹配的前缀
echo ${filename##*/} # 输出 "file.txt"
解释:
#*/
:删除最短匹配的前缀,这里删除的是第一个/
及其之前的部分。##*/
:删除最长匹配的前缀,这里删除的是最后一个/
及其之前的部分。
11.2. 删除字符串的后缀
%
:从变量末尾删除最短匹配的字符串。%%
:从变量末尾删除最长匹配的字符串。
示例:
filename="path/to/my/file.txt"
# 删除最短匹配的后缀
echo ${filename%.*} # 输出 "path/to/my/file"
# 删除最长匹配的后缀
echo ${filename%%.*} # 输出 "path/to/my/file"
解释:
%.*
:删除最短匹配的后缀,这里删除的是第一个.
及其之后的部分。%%.*
:删除最长匹配的后缀,这里删除的是最后一个.
及其之后的部分。
12. 字符串替换操作
除了简单的删除前缀和后缀,Shell 还提供了一些符号用于字符串替换。主要是 /
和 //
。
${variable/pattern/replacement}
:替换第一个匹配到的子字符串。${variable//pattern/replacement}
:替换所有匹配到的子字符串。
示例:
string="I love apples and apples are great"
# 替换第一个出现的 "apples"
echo ${string/apples/oranges} # 输出 "I love oranges and apples are great"
# 替换所有出现的 "apples"
echo ${string//apples/oranges} # 输出 "I love oranges and oranges are great"
13. 默认值机制和变量检查
Shell 中可以通过参数扩展来设置变量的默认值或者检查变量是否已定义。
${variable:-default}
:如果变量未定义或为空,则使用默认值。${variable:=default}
:如果变量未定义或为空,则赋值为默认值,并将默认值赋给变量。${variable:+replacement}
:如果变量已定义且不为空,则返回replacement
,否则返回空字符串。${variable:?error_message}
:如果变量未定义或为空,则输出错误信息并退出脚本。
示例:
# 如果 name 未定义或为空,使用默认值 "John"
echo ${name:-"John"} # 如果 $name 未定义,输出 "John"
# 如果 name 未定义或为空,赋值为 "John" 并输出
echo ${name:="John"}
# 如果 name 已定义且不为空,输出 "defined"
echo ${name:+defined}
# 如果 name 未定义或为空,输出错误信息并退出脚本
echo ${name:?"Error: name is not defined"}
14. 小结
在 Shell 编程中,#
、%
、/
、:
等符号提供了灵活的字符串操作方法,帮助我们进行模式匹配、字符串删除、替换和默认值设置。这些操作符可以提高 Shell 脚本的灵活性和可维护性,尤其是在处理文件路径、参数检查和字符串替换时非常有用。
最后编辑:严锋 更新时间:2025-05-09 15:48