5

This question already has an answer here:

I'm trying to check if a machine is a ThinkPad or not using something like this:

sudo dmidecode | grep ThinkPad

I want the end result return true or false (or 1/0).

I'm thinking the solution might be something like this:

sudo dmidecode | grep -c ThinkPad | test xargs -gt 0

But I'm not sure how to properly use xargs here.

marked as duplicate by don_crissti, Jeff Schaller, Eric Renouf, muru, GAD3R Apr 17 '17 at 15:54

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • @don_crissti I don't see how I could use any of those answers without creating a shell script. I think this is different because answers are specifically one-liners for command line. – Philip Kirkbride Apr 17 '17 at 13:07
  • It's exactly the same - and your answer here proves that beyond any doubt - it's almost the same as derobert's answer there but instead of if...then...else you're using && and ||. – don_crissti Apr 17 '17 at 13:14
14

Just tack the exit status check after grep, it will always get the exit status from the last command of the pipeline by default:

sudo dmidecode | grep -q ThinkPad; echo $?

Use -q to suppress any output from grep as we are interested in exit status only.


You can use command grouping if you fancy, but this is somewhat redundant here:

sudo dmidecode | { grep -q ThinkPad; echo $? ;}
  • I'm expecting to see 1 with this command but it returns 0 – Philip Kirkbride Apr 17 '17 at 3:34
  • @PhilipKirkbride Whats the output of sudo dmidecode | grep ThinkPad? – heemayl Apr 17 '17 at 3:35
  • It returns two lines with the word ThinkPad – Philip Kirkbride Apr 17 '17 at 3:36
  • 1
    @PhilipKirkbride The pattern is there...why would you think that grep would return 1? 0 means success (pattern found for grep), 1 means failure. Exit status is different from the Truthy-Falsy concept, actually the reverse. – heemayl Apr 17 '17 at 3:38
  • ah that makes sense. This will work than. – Philip Kirkbride Apr 17 '17 at 3:39
9

If you're going to use this an shell script with an if check, just use -q as heemayl suggested:

if sudo dmidecode | grep -q Thinkpad
then
    echo "I'm a Thinkpad"
fi

Since the if block checks the command's exit status, we can rely on grep's exit status directly instead of printing $? and the comparing it to something else.

2

Inspired by Heemayl's answer:

sudo dmidecode | grep -q ThinkPad && echo true || echo false

This will return true if ThinkPad is found by grep and false if not.

  • 1
    Philip, There's a caveat here... The portion after || will be executed if any of grep or echo true returns exit status non-zero... Although practically, the probability of failure of echo is nearly zero... – heemayl Apr 17 '17 at 16:40
1

Using test and command substitution,

test -n "$(sudo dmidecode | grep Thinkpad)" 

also,

[ -n "$(sudo dmidecode | grep Thinkpad)" ]
  • Using test here is completey redundant, and a common antipattern. Pretty much every Unix command sets its exit code to indicate success or failure; learn to use that instead of checking whether something was printed (which will be false in many common success scenarios, and could be true even if a command failed). – tripleee Apr 17 '17 at 17:14
0
sudo dmidecode | grep -c ThinkPad | xargs test 0 -lt

You need to rearrange the xargs and test command as also it's operands to be able to get what you want. This will return a true status if there are nonzero (>0) ThinkPad comprising lines.

Alternatively, if you want retain the operand order of test command you can do

sudo dmidecode | grep -c ThinkPad | xargs -I \{\} test \{\} -gt 0

And then, in both the commands, check for the $? variable's value to determine the fate of grep's success / failure, as follows:

if sudo dmidecode | grep -c ThinkPad | xargs -I \{\} test \{\} -gt 0; then
   echo "success hooray!"
else 
   echo nothing
fi

Not the answer you're looking for? Browse other questions tagged or ask your own question.