使用pv进行替换会导致空文件

时间:2017-01-04 00:47:08

标签: bash process-substitution

我在使用Bash进程替换使pv命令与tar一起使用时遇到问题。

我可以像这样使用pv,它可以工作:

$ tar cvf - dir | pv > file.tar
dir/
dir/b
dir/a
  10KiB 0:00:00 [16.9MiB/s] [<=>                                 ]
$ ls -s file.tar 
12 file.tar

使用cat进程替换也有效:

$ tar cvf >(cat > file.tar) dir
dir/
dir/b
dir/a
$ ls -s file.tar 
12 file.tar

但是这个命令导致空file.tar

$ tar cvf >(pv > file.tar) dir
dir/
dir/b
dir/a
$ ls -s file.tar 
0 file.tar

我也尝试了tar cvf >(pv - > file.tar) dir同样的结果。

我的目标是让pv打印出进度,并将tar的输出(即文件列表和任何错误)传递给其他命令以进行其他处理。上面的第一个示例命令仅产生2个输出流:stdout包含二进制tar数据,stderr包含文件列表和任何错误消息。使用进程替换将产生3个输出流:二进制tar数据转到新进程,stdout包含文件列表,stderr包含任何错误消息。

我可以将pv命令与Bash进程替换一起使用吗?若然,怎么做?

我正在使用pv 1.6.0GNU bash, version 4.3.46(1)-release

有趣的是,如果我使用strace来尝试和调试pv,它就有效:

$ tar cvf >(strace pv > file.tar) dir
dir/
dir/b
dir/a
execve("/usr/bin/pv", ["pv"], [/* 75 vars */]) = 0
brk(NULL)                               = 0x1eb8000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f46c9bac000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=123417, ...}) = 0
mmap(NULL, 123417, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f46c9b8d000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f46c95c0000
mprotect(0x7f46c977f000, 2097152, PROT_NONE) = 0
mmap(0x7f46c997f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f46c997f000
mmap(0x7f46c9985000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f46c9985000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f46c9b8c000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f46c9b8b000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f46c9b8a000
arch_prctl(ARCH_SET_FS, 0x7f46c9b8b700) = 0
mprotect(0x7f46c997f000, 16384, PROT_READ) = 0
mprotect(0x60d000, 4096, PROT_READ)     = 0
mprotect(0x7f46c9bae000, 4096, PROT_READ) = 0
munmap(0x7f46c9b8d000, 123417)          = 0
brk(NULL)                               = 0x1eb8000
brk(0x1ed9000)                          = 0x1ed9000
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
fstat(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=73, ws_col=178, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, SNDCTL_TMR_START or TCSETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTTOU, {0x408690, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {0x408660, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGCONT, {0x408710, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGWINCH, {0x408620, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {0x408640, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGHUP, {0x408640, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTERM, {0x408640, [], SA_RESTORER, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGSYS, {SIG_IGN, [SYS], SA_RESTORER|SA_RESTART, 0x7f46c95f54b0}, {SIG_DFL, [], 0}, 8) = 0
geteuid()                               = 4841
stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=110592, ...}) = 0
msgget(0x500112e9, IPC_CREAT|0600)      = 2818048
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
fstat(1, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
ioctl(0, TCGETS, 0x7ffc1cd79860)        = -1 ENOTTY (Inappropriate ioctl for device)
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
getpid()                                = 29280
msgrcv(2818048, 0x7ffc1cd797e0, 568, 29280, IPC_NOWAIT) = -1 ENOMSG (No message of desired type)
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f46c9b69000
select(1, [0], [], NULL, {0, 90000})    = 1 (in [0], left {0, 89998})
splice(0, NULL, 1, NULL, 131072, SPLICE_F_MORE) = 10240
select(1, [0], [], NULL, {0, 90000})    = 1 (in [0], left {0, 89999})
splice(0, NULL, 1, NULL, 131072, SPLICE_F_MORE) = 0
read(0, "", 131072)                     = 0
write(2, "  10KiB 0:00:00 [  37MiB/s] [  <"..., 178  10KiB 0:00:00 [  37MiB/s] [  <=>                                                                                                                                               ]) = 178
)                       = 1
write(2, "\n", 1
)                       = 1
close(0)                                = 0
msgctl(2818048, IPC_RMID, 0x7ffc1cd79b30) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, SNDCTL_TMR_START or TCSETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
rt_sigaction(SIGPIPE, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGTTOU, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGTSTP, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGCONT, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGWINCH, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGHUP, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
rt_sigaction(SIGTERM, {SIG_DFL, [], SA_RESTORER, 0x7f46c95f54b0}, NULL, 8) = 0
munmap(0x7f46c9b69000, 135168)          = 0
exit_group(0)                           = ?
+++ exited with 0 +++

$ ls -s file.tar 
12 file.tar

0 个答案:

没有答案