我正在编写一个脚本,该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
的末尾时,它表明正在处理数据,但是一旦数据传递到,我就会在客户端的标准输出中得到一个永无休止的乱码数据流。pigz
pigz
netcat
服务器显示需要写入的文件大小增加了 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 连接到其他命令的管道时,通常会使用进程重定向。