我在使用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.0
和GNU 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