shmig
shmig copied to clipboard
fix: pipe instead of using process expansion
fix #70
Just changed instances of
while read -r fname; do ...; done < <("$cmd" "$arg")
to
"$cmd" "$arg" | while read -r fname; do ...; done
I'm not enough of a bash expert to know for sure how the behavior of this differs from process expansion, but it seems to work and avoid the issue I was having with process expansion.
Some research on this.
- Process substitution "passes the name of the pipe (actually something like "/dev/fd/63") to the command as an argument, and expects the command to open that "file" and read/write it". -- comment on https://stackoverflow.com/a/51293856
# echo <(date)
/dev/fd/11
# cat <(date)
Fri Oct 18 16:40:20 PDT 2024
#
- Error propagation is different. Example below. Can work around with
set -o pipefailor the PIPESTATUS envvar if you are limited to bash. But Ash (Alpine Linux shell) does not support PIPESTATUS (source: https://lists.busybox.net/pipermail/busybox/2007-July/062422.html).
$ ls -l /notthere | tee listing.txt
ls: cannot access '/notthere': No such file or directory
$ echo $?
0
vs.
$ ls -l /notthere > >(tee listing.txt)
ls: cannot access '/notthere': No such file or directory
$ echo $?
2
- Subprocess may not be done when command completes. For example, in this command:
tar \
--create \
--file /tmp/etc-backup.tar \
--verbose \
--directory /etc . &> \
>(tee /tmp/etc-backup.log)
apparently the tee subprocess can still be running when main process returns.
-- source: https://stackoverflow.com/a/73598634
The second issue is the only one I need to think about. Is there a case where this matters?