ZFS 发送到 Pigz、netcat

ZFS 发送到 Pigz、netcat

我正在编写一个脚本,该netcat脚本在服务器上远程打开一个进程,该进程侦听输入并将其重定向到文件:

ssh $remote_upload_user@remote_upload_address "nc -l -p $remote_port > $remote_dir/$backup.gz&"

该脚本继续压缩 ZFS 快照pigz,然后将数据作为输入发送到netcat

netcat $remote_upload_address -u $remote_port < $(zfs send -R $zpool@label | pigz)

当添加到(括号内)|pv的末尾时,它表明正在处理数据,但是一旦数据传递到,我就会在客户端的标准输出中得到一个永无休止的乱码数据流。pigzpigznetcat

服务器显示需要写入的文件大小增加了 0。为什么这不起作用?

答案1

$(...)是命令替换。您不希望将 的输出作为要读取的zfs send文件名。nc您希望将 的输出zfs send作为输入发送到,pigz同时pigz将其输出发送到netcat,因此:

zfs send -R "$zpool@label" | pigz | netcat "$remote_upload_address" "$remote_port"

不要使用 UDP。与 TCP 不同,UDP 不提供传送保证。

如果你想使用<重定向运算符,你可以使用ksh-style过程替换(也可以在zsh和中找到bash):

netcat "$remote_upload_address" "$remote_port" < <(
  zfs send -R "$zpool@label" | pigz)

但这与基于标准的等价物相比没有优势|。在那里,传递给重定向运算符的文件名<是一个命名管道或/dev/fd/x指向管道的特殊文件(pigz在管道的另一端写入)。

这是相同的,但涉及一些额外的系统调用。另一个区别是 shell 不会等待该zfs send|pigz命令(尽管它会等待,但在读取其输出netcat之前可能不会终止)。pigz

或者使用yash的进程重定向运算符:

netcat "$remote_upload_address" "$remote_port" <(
  zfs send -R "$zpool@label" | pigz)

同样,这里比标准语法没有优势。yash当您希望某个命令的多个 fd 连接到其他命令的管道时,通常会使用进程重定向。

相关内容