Home > OS >  how can i use grep result from a variable in if/else statment
how can i use grep result from a variable in if/else statment

Time:02-05

i am trying to create a condition statement that checks if the grep found if a package is installed. if it is true , then the package should not be installed , and if it is false , then the package should be installed. i am always getting the same result package is not installed no matter which value i put please help (in my case the all packages are installed and grep finds a match. here is code:

chk1=$(yum list installed | grep rpmdevtools) 
chk2=$(yum list installed | grep rpmbuild)
chk3=$(yum list installed | grep rpmdev)
if [[ $chk1 -ne 0 && "$chk2" -ne 0 && "$chk3" -ne 0 ]];then
   echo "package exists"
   sleep 5
else
   echo "package doesn't exists installing .."
   sleep 5
   sudo yum install wget -y
   wget http://mirror.centos.org/centos/7/os/x86_64/Packages/rpmdevtools-8.3-5.el7.noarch.rpm
   sudo yum install rpmdevtools-8.3-5.el7.noarch.rpm -y
fi

CodePudding user response:

You're mixing 2 types of results here : result (i.e. displayed text) and return value.

TL;DR

You can verify if the variable $chkX is not empty with [[ ! -z ${chkX} ]], such as :

if [[ ! -z ${chk1} ]] && [[ ! -z ${chk2} ]] && [[ ! -z ${chk3} ]]; then
[...]

Or you can do something like this, based on exit codes.

yum list installed | grep -q vim
if [[ $? -eq 0 ]]; then
  # do your stuff here when package is installed
else
  #.. do your stuff here when package isn't installed ..
fi

or

if yum list installed | grep -q 'vim' ;then
  # do your stuff here when package is installed
else
  # .. do your stuff here when package isn't installed ..
fi


When executing in a subshell through $(yum ...) you are storing the result (i.e. displayed text) that's echoed by the command.
For instance:

$> yum list installed | grep vim
vim-common.x86_64                                 2:8.2.3755-1.fc35                    @updates       

If you want the return code or exit code, it's accessible through $?.
For example:

$> ls
[...]
$> echo $?
0
$> ls toto
ls: cannot access 'toto': No such file or directory
$> echo $?
2

Note every command changes the exit code.
So accessing twice $? will change its value.

$> ls toto
ls: cannot access 'toto': No such file or directory
$> echo $?
2
$> echo $?
0

In your case, you're testing if the text given by yum is mathematically equal to 0:

chk3=$(yum list installed | grep rpmdev)
if [[ $chk1 -ne 0 && "$chk2" -ne 0 && "$chk3" -ne 0 ]];then
                                             ^^^^^^

It's not possible because :

  • no package found -> empty variable
  • one or many package found -> single or multiline text with package information.
  • and you'll never get 0.

If you run it with test you have various cases of failure:

# note: rpmdevtools is not installed on by computer
$> chk1=$(yum list installed | grep rpmdevtools) 
$> test $chk1 -ne 0
bash: test: -ne: unary operator expected

# multiple vim-* packages are installed
$> chk1=$(yum list installed | grep vim) 
$> test $chk1 -ne 0
bash: test: too many arguments

CodePudding user response:

I'm not familiar with yum, there may be a better way to check, but this will make your if statement work:

if
    yum list installed | grep -q rpmdevtools &&
    yum list installed | grep -q rpmbuild &&
    yum list installed | grep -q rpmdev
then

I also recommend adding -w to grep, to match a whole word.

If yum list installed is a slow command, consider saving the output in a variable, and grepping that (instead of running it three times):

list=$(yum list installed)

if
    echo "$list" | grep -q rpmdevtools &&
    echo "$list" | grep -q rpmbuild &&
    echo "$list" | grep -q rpmdev
then
  •  Tags:  
  • Related