Simultaneously check for empty output and successful exit status
Solution 1
First of all, while they are functionally equivalent,
$(…)
is widely considered to be clearer than `…`
—
see this, this, and this. Secondly,
you don’t need to use $?
to check whether a command succeeded or failed.
My attention was recently drawn to Section 2.9.1, Simple Commands
of The Open Group Base Specifications for Shell & Utilities (Issue 7):
A "simple command" is a sequence of optional variable assignments and redirections, in any sequence, optionally followed by words and redirections, terminated by a control operator.
When a given simple command is required to be executed …
⋮ (blah, blah, blah …)If there is a command name, execution shall continue as described in Command Search and Execution. If there is no command name, but the command contained a command substitution, the command shall complete with the exit status of the last command substitution performed. …
For example,
-
the exit status of the command
ls -ld "module_$(uname).c"
is the exit status from the
ls
, but -
the exit status of the command
myfile="module_$(uname).c"
is the exit status from the
uname
.
So ferada’s answer can be streamlined a bit:
if output=$(/etc/grub.d/30_os-prober) && [ -z "$output" ] # i.e., if 30_os-prober successfully produced no output then install_linux_only else install_dual_boot fi
Note that it is good practice to use all-upper-case names only for environment variables (or variables to be visible throughout the script). Variables of limited scope are usually named in lower case (or, if you prefer, camelCase).
Solution 2
You can assign the value to a variable and then check the exit status as well:
PROBE_VALUE=`/etc/grub.d/30_os-prober`
if [ "$?" -eq 0 ] && [ -z "$PROBE_VALUE" ]; then
install_linux_only
else
install_dual_boot
fi
Related videos on Youtube
200_success
Former moderator of https://codereview.stackexchange.com
Updated on September 18, 2022Comments
-
200_success over 1 year
I'd like to write the following test in an installer script1:
if [ -n "`/etc/grub.d/30_os-prober`" ]; then install_dual_boot else install_linux_only fi
However, it's also possible that
30_os-prober
produces no output because it somehow failed to complete. If30_os-prober
fails with a non-zero exit status, it would be safer to assume the a dual-boot situation.How can I check that
30_os-prober
produced no output successfully?Basically, I would like to obtain an effect similar to…
if [ -n "`/etc/grub.d/30_os-prober`" ]; then # Do stuff for a dual-boot machine install_dual_boot elif ! /etc/grub.d/30_os-prober >/dev/null; then # OS probe failed; assume dual boot out of abundance of caution install_dual_boot else install_linux_only fi
… but without running the same command twice.
1 Background information:
30_os-prober
comes with GRUB2, and the script I am writing is part of my custom configuration for FAI.-
Admin almost 9 yearsYou don't have to run the command inside the
[]
's of anif
statement... -
Admin almost 9 years@AndrewHenle Could you clarify what you mean?
-
Admin almost 9 yearsYou need the exit status and the output. You can't get both if you constrain yourself to running the command inside
[]
's. As ferada's answer shows.... -
Admin almost 9 yearsYour question is inconsistent: the first code block says
if [ -z … ] then install_dual_boot
but the second one saysif [ -n … ] then install_dual_boot
.
-
-
Scott - Слава Україні almost 9 yearsYour approach and logic are good, but you seem to have your
then
andelse
branches backwards: based on his words and his second code block, the OP seems to wantinstall_dual_boot
if the output is-n
or the probe fails. -
ferada almost 9 years@Scott Nah, you're right, your solution looks nicer anyway.