I want to check if a USB is busy and store the result in a variable:

$ foo=$(umount /dev/sdb1)
$ umount: /path/mounted: target is busy.

But when I want to print $foo, I get an empty variable

$ echo $foo

My final goal is to umount the USB. If the target is busy, issue a warning to the user, using whiptail. So:

$ [[ -z $foo ]] || whiptail --msbox "Cancel the operation that is maintaining your USB busy" 0 0

Is it possible to store the error target is busy on a variable, or should I use another kind of technique?

  • umount /dev/sdb1 || whiptail should work.
    – jordanm
    Sep 6, 2019 at 0:19
  • @jordanm Thanks, it seems that works Sep 6, 2019 at 0:24

1 Answer 1


Programs commonly write error messages to the “standard error” I/O stream; “stderr” for short.  If you search for that term, you’ll gets millions of results; the short explanation is that stderr exists so error messages can and will go to the screen when the “standard output” (“stdout”) is redirected, as in a hypothetical command like

umount /dev/sdb1 > um.result.txt

And you can see this happening; the error message appears on your screen even though you are trying to capture it in a variable.

The equally short answer is to use 2>&1 to merge the stderr stream into the stdout stream, so

foo=$(umount /dev/sdb1 2>&1)

will capture the error message in the variable.

Another approach, as suggested by jordanm in a comment, is to look at the exit status.  Variations on this theme include:

umount /dev/sdb1  ||  complain to user
if ! umount /dev/sdb1
    complain to user
umount /dev/sdb1 2> /dev/null  ||  complain to user
 foo=$(umount /dev/sdb1 2>&1)  ||  complain to user using "$foo"

  • @tsul: Thanks for doing that research and sharing your results. Oct 12, 2021 at 15:48
  • (Facepalm!) And I should have noticed the flaw in sh -c "<command>; echo $?". Yeah; if your comments are wrong, delete them. Oct 20, 2021 at 0:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .