一个普通的 tar 命令
tar cvf foo.tar ./foo >foo.out 2>foo.err
Run Code Online (Sandbox Code Playgroud)
具有三个输出 IO 流
然后我可以检查 foo.err 是否有错误消息,而无需通读文件名列表。
如果我想对存档数据做一些事情(通过 netcat 或特殊压缩程序进行管道传输),我可以使用 tar 的 -f -选项
tar cvf - ./foo 2>foo.err | squish > foo.tar.S
Run Code Online (Sandbox Code Playgroud)
但是现在我的文件名列表与我的错误消息混合在一起,因为 tar 的-v输出显然不能进入 STDOUT(这是存档数据流动的地方),所以 tar 巧妙地将其写入 STDERR。
使用 Korn shell,有没有一种方法可以构造一个命令,将归档流通过管道传输到另一个命令,但仍能将-v输出与任何错误消息分开捕获。
如果您的系统支持/dev/fd/n:
tar cvf /dev/fd/3 ./foo 3>&1 > foo.out 2>foo.err | squish > foo.tar.S
Run Code Online (Sandbox Code Playgroud)
您可以使用进程替换编写ksh(or bashor zsh) 的AT&T 实现:
tar cvf >(squish > foo.tar.S) ./foo > foo.out 2>foo.err
Run Code Online (Sandbox Code Playgroud)
除了这一次,shell 决定使用哪个文件描述符而不是3(通常在 9 以上)之外,这完全相同。另一个区别是,这一次,您获得的退出状态为tar而不是squish。在不支持 的系统上/dev/fd/n,某些 shell 可能会使用命名管道来实现该功能。
如果您的系统不支持/dev/fd/n或您的 shell 无法使用命名管道进行进程替换,那么您就必须手动处理命名管道。
您必须为此使用命名管道。
首先在文件夹中创建一个:
mkfifo foo.pipe
Run Code Online (Sandbox Code Playgroud)
然后使用该命令:
tar cvf foo.pipe ./foo >foo.out 2>foo.err & cat foo.pipe >foo.tar
Run Code Online (Sandbox Code Playgroud)
注意:在cat双组分,现在也可以gzip也好,都可以从管道中读取:
tar cvf foo.pipe ./foo >foo.out 2>foo.err & gzip -c foo.pipe >foo.tar
Run Code Online (Sandbox Code Playgroud)
解释:
输出写入名称管道 ( foo.pipe),另一个进程 ( cat, gzip, netcat) 从中读取。因此,您不会丢失 stdout/stderr 信息通道。
GNU tar 的--index-file选项运行良好:
tar cvf - ./foo 2>foo.err --index-file=foo.out | squish > foo.tar.S
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3937 次 |
| 最近记录: |