在Shell脚本编程中,将命令结果赋值给变量是一项常见且重要的操作,它允许脚本动态获取系统信息、文件内容或命令输出,并基于这些结果进行后续处理,以下是几种常见的赋值方法及其详细说明。

反引号(`)赋值
反引号是较早的命令替换方式,它会先执行反引号内的命令,然后将命令的标准输出替换为整个表达式,将当前日期赋值给变量:
date_now=`date +%Y-%m-%d` echo "今天是:$date_now"
注意:反引号内不能再嵌套反引号,否则会导致语法错误,且在复杂命令中可读性较差。
$() 赋值
是更现代且推荐的命令替换语法,支持嵌套且不易与单引号混淆,获取系统负载并赋值:
load_avg=$(uptime | awk -F'load average:' '{print $2}')
echo "系统负载:$load_avg"
的优势在于可以清晰嵌套,

nested_result=$(echo "当前时间:$(date)") echo "$nested_result"
$(< filename) 赋值
如果需要将整个文件内容赋值给变量,可以使用 $(< 文件名) 的简写形式,它比 $(cat 文件名) 更高效,因为避免了启动 cat 进程:
file_content=$(< /etc/hosts) echo "文件内容:$file_content"
read 命令赋值
read 命令可以从标准输入读取一行数据并赋值给变量,常与命令管道结合使用,读取第一块硬盘的名称:
disk_info=$(lsblk | head -n 2 | tail -n 1) read disk_name <<< "$disk_info" echo "硬盘名称:$disk_name"
或直接通过管道赋值:
echo "hello world" | read var1 var2 echo "$var1, $var2" # 输出: hello, world
命令选项赋值
如果命令需要选项参数,可以通过变量拼接实现,使用 grep 搜索特定内容:

search_key="error" log_file="/var/log/syslog" grep_result=$(grep "$search_key" "$log_file") echo "搜索结果:$grep_result"
多行结果赋值
对于多行命令结果,可以直接赋值给变量,变量会保留换行符,列出所有用户:
user_list=$(cat /etc/passwd | cut -d: -f1) echo "用户列表:$user_list"
赋值时的注意事项
- 引号使用:如果命令结果包含空格或特殊字符,建议用双引号包裹变量,
result="$(ls -l)"。 - 错误处理:若命令可能失败,可通过
set -e或if判断 变量处理错误。 - 变量作用域:默认情况下,Shell变量是全局的,若需局部变量,可在函数内使用
local关键字。
性能对比
| 方法 | 适用场景 | 性能 | 可读性 | 嵌套支持 |
|---|---|---|---|---|
| 反引号(`) | 简单命令替换 | 一般 | 较差 | 不支持 |
| 复杂命令、嵌套 | 较高 | 优秀 | 支持 | |
| $(< filename) | 读取 | 最高 | 优秀 | 不支持 |
| read 命令 | 交互式输入或管道处理 | 一般 | 一般 | 需配合管道 |
相关问答FAQs
Q1: 为什么推荐使用 $() 而不是反引号?
A1: $() 语法更清晰,支持嵌套(如 $(echo "时间:$(date)")),且不会与单引号混淆;反引号在嵌套时需要转义,可读性较差,且在某些Shell中可能存在兼容性问题。
Q2: 如何将命令结果赋值给数组变量?
A2: 可以通过 mapfile 或 readarray 命令将多行结果存入数组,
mapfile -t users < <(cut -d: -f1 /etc/passwd)
echo "第一个用户:${users[0]}"
或使用 IFS 分割:
output="user1,user2,user3" IFS=, read -ra user_array <<< "$output"
