Use Command-Subsitution, Not Process Substitution
Instead of reading in from process subsitution, consider using command substitution instead. For example:
mountpoint=$(stat -t "/my/mountpoint" 2>&1)
This will silence the output by storing standard output in a variable, but leave the results retrievable by dereferencing $mountpoint. This approach also leaves the exit status accessible through $?.
A Clearer Alternative
Alternatively, you might just rewrite this more simply as:
mountpoint="/my/mountpoint"
if stat -t "$mountpoint" 2>&-
then
echo "NFS mount stale. Removing..."
umount -f -l "$mountpoint"
fi
To me, this seems more intention-revealing and less error-prone, but your mileage may certainly vary.
(Ab)using Read Timeouts
In the comments, the OP asked whether read timeouts could be abused to handle hung input from stat. The answer is yes, if you close standard error and check for an empty $REPLY string. 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 the read builtin in Bash:
If no NAMEs are supplied, the line read is stored in the REPLY variable.
- With standard error closed, $REPLY will be empty unless stat returns something on standard output, which it won't if it encounters an error. In other words, you're checking the contents of the $REPLY string instead of the exit status from read.
read
? The reason it's there is to time out a command that would otherwise hang. This also happens with rpcinfo:read -t1 < <(rpcinfo -t 10.0.128.1 nfs) if [ $? -eq 0 ] ; then _RET=true else _RET=false fi
If 10.0.128.1 is not reachable, rpcinfo by itself would hang for a few minutes. Redirection toread
allows it to time out in 1 second instead. It is specifically in this context–withread
–that I'm having difficulty suppressing the output. – Seavey