惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
P
Proofpoint News Feed
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
Microsoft Security Blog
Microsoft Security Blog
F
Fortinet All Blogs
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
美团技术团队
D
Docker
博客园 - Franky
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

博客园 - 吴丹阳-V

换源神器 chsrc:一键为你的开发环境切换到最快镜像 python 什么是偏函数 python 多进程日志打印方法 CDN 带宽控制的几种方法 obsidian-things3-today插件 凡人修仙传动漫截图 Things 工作流 创建一个chrome独立APP窗口 202405081331 mac 鼠须管 - rime 如何使用命令行执行同步操作 系统调用的具体过程以及注意点【包含AIGC】 使用 shell 脚本启动固定数量的进程 为什么 echo -n 后面会带着一个百分号 网络-最多有多少个a类、b类和c类网络号 unicode 与 utf-8 与 utf-16【包含AIGC】 《你的第一本哲学书》 我喜欢的音乐歌手标签 nginx 进程模型-整体架构 linux - trap 命令 丰田五问法 webp 格式图片压缩效果
linux-command-substitution(命令替换)
吴丹阳-V · 2024-10-19 · via 博客园 - 吴丹阳-V

linux-command-substitution(命令替换)

1 什么是命令替换

在有一下情况的时候,会发生命令替换:

$(command)

或者是反引号
`command`

这个命令会在子shell中执行,使用标准输出替换掉上面的命令文本。并且在管道关闭或者子进程终止前,shell会一直等待。

2 命令替换时为什么把换行变成了空格

shell读取的输出会以空格作为分隔符进行解析。
不过你可以通过从新设定 IFS 字段来重新指定分隔符。

比如说现在有一个文本文件:

wudanyang@dy-turbo-vm:~/workspace$ cat links.txt
123
456
789

把文件内容实用命令替换成一个变量之后,文本输出是以空格分隔的,换行符被替换掉了

wudanyang@dy-turbo-vm:~/workspace$ a=$(cat links.txt)
wudanyang@dy-turbo-vm:~/workspace$ echo $a
123 456 789

但是如果在输出的时候使用双引号括起来,那么换行符就会被保留下来:

wudanyang@dy-turbo-vm:~/workspace$ a=$(cat links.txt)
wudanyang@dy-turbo-vm:~/workspace$ echo "$a"
123
456
789

3 读取文件的时候空格被当成了分隔符

当有这样一个文件:

$ cat links.txt
hello world
today is weekend
so happy

直接输出是这样的:

wudanyang@dy-turbo-vm:~/workspace$ a=$(cat links.txt)
wudanyang@dy-turbo-vm:~/workspace$ echo $a
hello world today is weekend so happy

如果直接读取的话,因为默认空格是分隔符,所以会认为这是很多行

$ for i in $(cat links.txt); do echo $i; done
hello
world
today
is
weekend
so
happy

3.1 使用双引号解决

使用双引号可以解决这个问题,不实用shell的字符处理,而是使用双引号的字符处理逻辑:

for i in "$(cat links.txt)"; do echo "$i"; done
hello world
today is weekend
so happy

3.2 使用 IFS 修改默认分隔符

当然也可以使用 IFS,把默认的分隔符修改掉,但是记得要还原回来, 不然可能执行别的程序会有问题

oriIFS=$IFS;IFS=$'\n'; for i in $(cat links.txt); do echo $i; done;IFS=$oriIFS;
hello world
today is weekend
so happy

3.3 使用管道+read指令

The read utility shall read a single logical line from standard input into one or more shell variables.

cat links.txt | while read i; do echo $i; done
hello world
today is weekend
so happy

4 小结

可以看到命令替换的字符串还是有一些弯弯绕绕的,所以,一般情况下,就不要使用命令替换,而是直接使用管道,或者就不使用shell了

5 参考

命令替换 2.6.3 Command Substitution : Shell Command Language
shell - 为什么使用命令替换时换行符会丢失? - Unix 和 Linux 堆栈交换 --- shell - Why do newline characters get lost when using command substitution? - Unix & Linux Stack Exchange

阅读(1p) - Linux 手册页 --- read(1p) - Linux manual page