Solved Perplexing behavior of shell when trying to loop over input

I created a script using zsh.

One version of the script looks like the following.

It correctly loops over all three lines of input and prints what would happen, sleeping 5 seconds after each print

Bash:
#!/usr/bin/env zsh

while IFS= read -r snap ; do
  fs="$( echo "$snap" | cut -d@ -f1 )"
  echo "ssh de1 \"doas zfs send zroot/$snap\" | pv | doas zfs recv \"zroot/backup/de1/$fs\""
  sleep 5
done <<EOF
jail/jail1/usr/local@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc/dehydrated@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
EOF

In another version of the script, where everything is exactly the same except that in this one we actually run the pipeline instead of echo.

Bash:
#!/usr/bin/env zsh

while IFS= read -r snap ; do
  fs="$( echo "$snap" | cut -d@ -f1 )"
  ssh de1 "doas zfs send zroot/$snap" | pv | doas zfs recv "zroot/backup/de1/$fs"
  sleep 5
done <<EOF
jail/jail1/usr/local@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc/dehydrated@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
EOF

But in this latter version, it performs the pipeline for the first line of input successfully, and then it sleeps 5 seconds as expected. But then after this it exits with status 0.

Can someone help me understand what is going on here?

I am running FreeBSD 13.1-RELEASE
 
Furthermore here is another variant that I did for testing just now

Bash:
#!/usr/bin/env zsh

while IFS= read -r snap ; do
  fs="$( echo "$snap" | cut -d@ -f1 )"
  echo "$snap" | pv | cat
  sleep 5
done <<EOF
jail/jail1/usr/local@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
jail/jail1/usr/local/etc/dehydrated@manual-snapshot:2023-05-11-16-56-39_0200:subnetted-ipv6
EOF

And this version behaves like we expect as well. All three lines of input get processed by the pipeline with a 5 sec sleep after each run of the pipeline.

So I don't understand where the problem I am seeing is even coming from, nor why..
 
ssh will drain stdin
see
 
Back
Top