I am writing a script that opens a netcat process remotely on a server which listens for input and redirects it to a file:

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

The script proceeds to compress the ZFS snapshot through pigz and then sends the data as input to netcat:

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

When adding |pv to the end of pigz (within the parentheses) it shows that pigz is processing the data, but once the data passes to netcat I get a never ending stream of garbled data flooding stdout on the client side.

The server shows 0 size in increase for the file it needs to be writing to. Why isn't this working?


$(...) is command substitution. You don't want the output of zfs send to be taken as a file name for nc to read from. You want to send the output of zfs send as input to pigz while pigz sends its output to netcat, so:

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

Don't use UDP. UDP, contrary to TCP provides no guarantee of delivery.

If you wanted to use the < redirection operator, you could use ksh-style process substitution (also found in zsh and bash):

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

But that has no advantage over the standard |-based equivalent. There, the file name passed to the < redirection operator is a named pipe or /dev/fd/x special file that points to a pipe (pigz writing at the other end of the pipe).

That's the same but involves a few extra system calls. Another difference is that the shell doesn't wait for that zfs send|pigz command (though it waits for netcat which probably won't terminate before pigz as it's reading its output).

Or use yash's process redirection operator:

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

Again, no advantage over the standard syntax here. You'd typically use process redirection in yash when you want to have several fds of a command connected to pipes to other commands.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.