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.

  • @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. Apr 17, 2017 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 ||. Apr 17, 2017 at 13:14

5 Answers 5


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 $? ;}
  • 1
    I'm expecting to see 1 with this command but it returns 0 Apr 17, 2017 at 3:34
  • @PhilipKirkbride Whats the output of sudo dmidecode | grep ThinkPad?
    – heemayl
    Apr 17, 2017 at 3:35
  • It returns two lines with the word ThinkPad Apr 17, 2017 at 3:36
  • 2
    @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, 2017 at 3:38
  • ah that makes sense. This will work than. Apr 17, 2017 at 3:39

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
    echo "I'm a Thinkpad"

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.


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, 2017 at 16:40

Using test and command substitution,

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


[ -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, 2017 at 17:14
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!"
   echo nothing

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