Use Command-Subsitation, Not Process Substitution
Instead of reading from process substitution, use command substitution instead. For example:
mountpoint=$(stat -t "/my/mountpoint" 2>&1)
This will disable output by storing standard output in a variable, but leave the results available by playing out $ mountpoint. This approach also leaves available exit status through $ ?.
Simpler alternative
Alternatively, you can simply rewrite this more simply:
mountpoint="/my/mountpoint" if stat -t "$mountpoint" 2>&- then echo "NFS mount stale. Removing..." umount -f -l "$mountpoint" fi
It seems to me that this seems more attractive and less error prone, but your mileage can certainly vary.
(Ab) using read timeouts
In the comments, the OP asked a question about whether reading timeouts can be abused to process tagged data from stat. The answer is yes, if you close the standard error and check the empty string $ REPLY. For example:
mountpoint="/my/mountpoint" read -t1 < <(stat -t "$mountpoint" 2>&-) if [[ -n "$REPLY" ]]; then echo "NFS mount stale. Removing..." umount -f -l "$mountpoint" fi
This works for several reasons:
- When using inline reading in Bash:
If no NAMES are supplied, the reading of the string is stored in the REPLY variable.
- If the standard error is closed, $ REPLY will be empty if stat does not return something to standard output, which will not happen if it encounters an error. In other words, you check the contents of the string $ REPLY instead of the exit status of the read.
Todd A. Jacobs
source share