在Bash中如何将变量设置为命令的输出
技术背景
在Bash脚本编程中,经常需要将命令的输出结果存储到变量中,以便后续使用。这在处理系统信息、文件操作、数据处理等场景中非常常见。通过将命令输出赋值给变量,可以方便地对结果进行进一步的处理、分析或展示。
实现步骤
1. 使用反引号(`)
反引号是一种传统的命令替换方式,它可以将反引号内的命令执行结果替换到相应的位置。
1 2
| myPi=`echo '4*a(1)' | bc -l` echo $myPi
|
2. 使用 $(command)
语法
这是现代Bash推荐的命令替换方式,它更易读,并且支持嵌套。
1 2
| OUTPUT="$(ls -1)" echo "${OUTPUT}"
|
3. 读取多行输出
当命令输出包含多行时,使用引号来保留多行变量值。
1 2 3
| MULTILINE="$(ls \ -1)" echo "${MULTILINE}"
|
4. 读取多个变量
可以将命令输出解析到多个变量中。
1 2
| { read -r _;read -r filesystem size using avail prct mountpoint ; } < <(df -k /) echo $using
|
5. 处理错误信息
可以将命令的错误信息和正常输出分别存储到不同的变量中。
1 2 3 4 5 6 7
| exec {cmderrfd}< > <(:) unset varerstr variable="$(ls -ld /tnt /tmp /mnt /mot 2>&$cmderrfd)" varerror=$? while read -r -u $cmderrfd -t .002 errline; do varerstr+=${errline/#/${varerstr:+$'\n'}} done exec {cmderrfd}<&-
|
6. 处理特殊字符
对于包含特殊字符的文件名或输出,可以使用 -print0
选项和 IFS
来正确处理。
1 2 3 4 5 6
| while IFS='' read -r -d '' filename; do size=$(stat -c %s "$filename") printf ' %13d %q\n' $size "$filename" done < <( find . \( -type f -o -type d \) -print0 )
|
7. 使用 mapfile
处理输出
mapfile
可以将命令输出存储到数组中。
1 2 3 4 5
| mapfile -t -d '' entries < <( find . \( -type f -o -type d \) -print0) for entry in "${entries[@]}";do size=$(stat -c %s "$entry") printf ' %13d %q\n' $size "$entry" done
|
核心代码
简单示例
1 2 3 4 5 6 7
| myPi=$(bc -l <<< '4*a(1)') echo $myPi
{ read -r _;read -r filesystem size using avail prct mountpoint ; } < <(df -k /) echo $using
|
复杂示例
1 2 3 4 5 6 7 8 9
| exec {cmderrfd}< > <(:) unset varerstr variable="$(ls -ld /tnt /tmp /mnt /mot 2>&$cmderrfd)" varerror=$? while read -r -u $cmderrfd -t .002 errline; do varerstr+=${errline/#/${varerstr:+$'\n'}} done exec {cmderrfd}<&- declare -p ${!var*}
|
最佳实践
- 优先使用
$(command)
语法:它更易读,且支持嵌套,在现代Bash中推荐使用。 - 使用引号保留多行输出:当命令输出包含多行时,使用引号可以确保多行内容被正确保留。
- 处理错误信息:将命令的错误信息和正常输出分别存储到不同的变量中,以便进行错误处理。
- 使用
mapfile
处理输出:对于包含特殊字符或多行的输出,使用 mapfile
可以方便地将其存储到数组中进行处理。
常见问题
1. 变量赋值时出现空格
在变量赋值时,等号两边不能有空格,否则会导致赋值失败。
1 2 3 4 5 6 7
| WTFF=`echo "stuff"` echo "Example: $WTFF"
WTFF= `echo "stuff"` echo "Example: $WTFF"
|
2. 命令替换语法不兼容
$(command)
语法仅在Bash或KornShell及其派生的shell中有效,如果脚本需要在各种Unix系统上运行,建议使用反引号(`)。
3. 处理特殊字符问题
当处理包含特殊字符的文件名或输出时,需要特别注意使用 -print0
选项和 IFS
来正确处理。否则,可能会导致文件名或输出被错误解析。