当前位置: 首页 > news >正文

shell中 <<<(Here String)的使用

在shell中经常使用命令
IFS="," read -r -a var_array <<< "$var_str"
作用是将一个字符串变量$var_str的值通过","分割,变成数组var_array 来使用。

其中, <<<(称为 Here String)的主要目的是将变量 $hosts 的内容作为输入传递给 read 命令。以下是其使用方法的详细解释:


1. <<< 的作用

<<< 是 Shell 的 Here String 语法,它将右侧的字符串(或变量内容)作为输入流传递给左侧的命令。其行为类似于临时文件或管道,但更简洁高效。

示例:
# 直接将字符串传递给命令
grep "foo" <<< "hello foo world"

# 将变量内容传递给命令
text="hello foo world"
grep "foo" <<< "$text"

以下采样用例 IFS="," read -r -a host_array <<< "$hosts" 来说明

2. 为什么在此处使用 <<<

例如 IFS="," read -r -a host_array <<< "$hosts" 中:

  • 目标:将变量 $hosts 的值(例如 "host1,host2,host3")按逗号分隔符(IFS=",")解析为数组 host_array
  • 关键需求read 命令需要从输入流中读取内容,而 $hosts 是一个字符串变量,无法直接作为输入流。
使用 <<< 的替代方案对比:
方法示例问题
管道echo "$hosts" | IFS="," read ...管道会创建子 Shell,read 在子 Shell 中运行,数组无法传递到父 Shell。
临时文件echo "$hosts" > tmp; read ... < tmp需要文件操作,效率低且有临时文件残留风险。
Here Stringread ... <<< "$hosts"直接传递变量内容,无子 Shell 问题,高效安全。

3. 关键优势

(1) 避免子 Shell 问题

如果使用管道(|),read 会在子 Shell 中执行,导致 host_array 仅在子 Shell 中有效,父 Shell 中无法访问:

# 错误示例:管道导致数组在子 Shell 中创建
echo "host1,host2,host3" | IFS="," read -r -a host_array
echo "${host_array[@]}"  # 输出为空!

<<< 直接在当前 Shell 中执行 read,确保数组对后续代码可见。

(2) 处理特殊字符

<<< "$hosts" 中的双引号保留 $hosts 的原始格式(如空格、换行符),确保 read 正确解析内容。如果省略双引号,Shell 会对变量值进行分词和通配符扩展,导致意外行为:

# 错误示例:未加双引号,导致分词问题
hosts="host1,host2,host3 with space"
IFS="," read -r -a host_array <<< $hosts  # 未加引号
echo "${host_array[2]}"  # 输出 "host3"(空格被错误处理)
(3) 高效性

<<< 直接在内存中传递数据,无需创建临时文件或通过管道传递,性能更高。


4. 完整流程解析

hosts="host1,host2,host3" 为例:

  1. 展开变量<<< "$hosts"$hosts 的值展开为字符串 "host1,host2,host3"
  2. 输入传递:Here String 将字符串传递给 read 命令作为输入流。
  3. 字段分割IFS="," 指定逗号为字段分隔符,read -a host_array 将输入按逗号分割为数组:
    host_array=("host1" "host2" "host3")
    

5. 其他替代方案的局限性

尝试直接使用变量:
IFS="," read -r -a host_array "$hosts"  # 语法错误!
  • read 不接受变量作为参数,必须从输入流中读取数据。
尝试使用 Here Document:
IFS="," read -r -a host_array <<EOF
$hosts
EOF
  • 虽然可行,但不如 <<< 简洁。

6. 总结

使用 <<< "$hosts" 的原因:

  1. 避免子 Shell:确保 read 在当前 Shell 中运行,变量可被后续代码使用。
  2. 直接传递输入:将字符串变量高效传递给 read 命令。
  3. 保留特殊字符:双引号包裹 $hosts 防止 Shell 的意外分词或扩展。

验证示例

# 正确用法
hosts="host1,host2,host3 with space"
IFS="," read -r -a host_array <<< "$hosts"
echo "数组长度: ${#host_array[@]}"        # 输出 3
echo "第三个元素: ${host_array[2]}"      # 输出 "host3 with space"

# 对比错误用法(未加双引号)
IFS="," read -r -a host_array <<< $hosts
echo "数组长度: ${#host_array[@]}"        # 输出 4(错误!)
echo "第三个元素: ${host_array[2]}"      # 输出 "with"(错误!)

7,跟<()进程替换+重定向比较一下

while read file; do count=$((count+1)); done < <(find . -type f)

done < <(find . -type f)中 <(find . -type f)是进程替换done后的<是重定向

这里的< <(find . -type f) 不能 替换为 while … done <<< find . -type f

<<< (Here String 要求输入内容预先完全生成,将右侧的固定字符串或变量内容一次性加载到内存中,适用于处理已知且数据量较小的输入。

进程替换支持流式处理(边生成边读取)。 find 命令的输出视为一个流式输入(逐行生成,类似管道),适用于处理动态生成或大量数据的场景。

以下场景可考虑使用 Here String

1,输入内容固定且微小:例如手动定义的字符串或小规模列表。

while read item; do ... done <<< "apple,banana,orange

2,调试代码:临时替换动态输入为静态字符串测试逻辑。

相关文章:

  • etcd部署硬件资源推荐
  • 搭建数字化生态平台公司:痛点与蚓链解决方案
  • Zookeeper(79)如何进行Zookeeper的监控?
  • 回溯算法中的for循环和递归使用
  • 自动化测试框架设计
  • Unity 优化封装常用API和编辑器扩展工具包
  • Redis的过期策略及其优缺点
  • FPGA之硬件设计笔记-持续更新中
  • python-leetcode-颜色分类
  • 安全模块设计:token服务、校验注解(开启token校验、开启签名校验、允许处理API日志)、获取当前用户信息的辅助类
  • 模拟进程通过系统调用向缓冲区写入并刷新的过程
  • k8s之pod的调度之污点与容忍污点,什么是污点? 如何容忍污点
  • 校园二手交易微信小程序的设计与实现(论文源码调试讲解)
  • 在鸿蒙HarmonyOS手机上安装hap应用
  • 深度学习基础--ResNet50V2网络的讲解,ResNet50V2的复现(pytorch)以及用复现的ResNet50做鸟类图像分类
  • 【北京迅为】iTOP-RK3568OpenHarmony系统南向驱动开发-第1章 GPIO基础知识
  • 线程概述以及Java中线程的三种创建方式(继承Thread类、实现Runnable接口、实现Callable接口)
  • 鸿蒙 ArkUI 实现 2048 小游戏
  • 网络安全 越权分为几种
  • Centos7源码编译安装Sqlite最新版本
  • 中国商标网官方查询网站/外链工具xg
  • 做网站视频赚钱吗/最吸引人的引流话术
  • 怎么给网站做301/代写文章
  • 网站做301的坏处/太原百度网站快速排名
  • 网站建设项目延期验收申请/百度软件商店
  • 政府网站建设合同.doc/企业培训公司