有条件列表、无条件列表
1 | 这个很好理解 |
命令替换
指的是将字符串替换为命令
1 | $(xxxx) |
进程替换
进程替换是 Shell 提供的一种高级重定向机制,允许将一个命令的输入或输出“伪装”成一个临时文件的路径
1.Shell 会动态创建一个临时命名管道(FIFO)或直接通过 /dev/fd
生成一个匿名文件描述符。
例如,<(ls)
会生成类似 /dev/fd/63
的路径。
2.启动子进程:
在后台启动 command
(如 ls
),并将其输出绑定到这个临时文件描述符。
3.传递路径给主命令:
将临时文件描述符的路径(如 /dev/fd/63
)作为参数传递给主命令(如 diff
、paste
)。
4.数据流处理:
主命令像读取普通文件一样从这个路径读取数据,实际读取的是子进程的动态输出。
1 | diff <(ls dir1) <(ls dir2) |
文件描述符的本质
文件描述符(File Descriptor,简称 fd)是操作系统用来标识和管理已打开文件或 I/O 资源的整数句柄。每个进程独立维护自己的文件描述符表。
- 标识资源:fd 不直接操作文件,而是指向内核中打开的文件、管道、套接字等资源。
- 动态分配:进程每打开一个资源,内核会分配一个最小的可用 fd(通常从
3
开始)。
1 | # 查看进程替换的临时文件路径 |
当使用进程替换(如 <(command)
)时:
- Shell 会为
command
的输出分配一个新的 fd(例如63
)。 - 生成一个路径
/dev/fd/63
,指向这个 fd。 - 主命令通过这个路径读取数据,实际是通过 fd 直接读取
command
的输出流。
底层技术:命名管道(FIFO)
在早期系统中,进程替换通过创建命名管道(FIFO)实现:
1 | # 手动模拟进程替换 |
进程替换案例
1 | 用进程替换替代临时文件: |
使用bash执行命令
这个很好理解,相当于新创建一个shell,然后让命令在子shell中运行
1 | bash -c 'echo "New Log" > /var/log/test.log' |
通过管道执行命令
举一个多正则匹配的例子
1 | 列出名称大于3个字母的文件 |
通过ssh执行命令
1 | ssh servera ls > outfile # 在本机创建文件 |
xargs与xargs安全性
xargs初级知识就略过了
不展开
1 | 在find和xargs结合使用时 |
显式子shell
cat package.tar.gz | (mkdir -p /tmp/other && ch /tmp/other && tar xzvf -)
读取tar包数据,放到后面新创建的目录中解压
tar czf - dir1 | (cd /tmp/dir2 && tar xvf -)
以压缩的方式将文件从dir1转到dir2
进程替换
exec
,将正在运行的shell替换成指定的命令,并在执行完成后退出
- 节约资源
不需要再启动一个进程
有些脚本如果要执行上百上千次,那么在最后一条命令时使用exec,能够节约相当的资源
- 为当前shell分配新的标准输入、标准输出和错误
1 |
|