0

Could some one help to find out what is problem with my for loop script. I'm trying to install packages from a list of variables using a for loop. My issues is when go grab the first package to be installed it and goes grab package from the list at the same time. Also it will install the packages all at the same time. How do I check fix it. I need to do one at a time.

REQPKGS="redhat-lsb-core telnet"

for pkg in $REQPKGS; do
    if yum -q list installed "$REQPKGS" > /dev/null 2>&1; then
        echo -e "$pkg is already installed"
    else
        yum install $REQPKGS -y
        echo "Successfully installed $REQPKGS"
    fi
done

Result of my script:

+ REQPKGS='redhat-lsb-core telnet'
+ for pkg in '$REQPKGS'
+ yum -q list installed 'redhat-lsb-core telnet'
+ yum install redhat-lsb-core telnet -y
+ echo 'Successfully installed redhat-lsb-core telnet'
Successfully installed redhat-lsb-core telnet
+ for pkg in '$REQPKGS'
+ yum -q list installed 'redhat-lsb-core telnet'
+ yum install redhat-lsb-core telnet -y
Loaded plugins: product-id, refresh-packagekit, rhnplugin, security, subscription-manager
This system is receiving updates from RHN Classic or RHN Satellite.
Setting up Install Process
Package redhat-lsb-core-4.0-7.el6.x86_64 already installed and latest version
Package 1:telnet-0.17-48.el6.x86_64 already installed and latest version
Nothing to do
+ echo 'Successfully installed redhat-lsb-core telnet'
Successfully installed redhat-lsb-core telnet
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
pirulo
  • 103
  • 2
    Also, why not use yum install $REQPKGS -y on its own rather than this for loop? yum will skip over packages that are already installed on its own. – Centimane Sep 16 '16 at 15:43

1 Answers1

5

You use your array variable ($REQPKGS) inside your loop instead of the loop variable ($pkg), so it's doing exactly what you told it to do, install both packages at the same time twice.

Change the inside of your for loop to:

REQPKGS=(redhat-lsb-core telnet)

for pkg in "${REQPKGS[@]}"; do
    if yum -q list installed "$pkg" > /dev/null 2>&1; then
        echo -e "$pkg is already installed"
    else
        yum install "$pkg" -y && echo "Successfully installed $pkg"
    fi
done

When using a for loop, the variable you define after for holds the value for each iteration of the loop; in your case the variable that contains a single package at a time is $pkg.

Alternatively

REQPKGS=(redhat-lsb-core telnet)

yum install -y "${REQPKGS[@]}"

Will install any packages specified that aren't installed, and skip any packages that are already installed.

Centimane
  • 4,490
  • Centimane, It works great now. I got confused with the name of the variables. Thank a lot.!!! – pirulo Sep 16 '16 at 14:28
  • 1
    I would suggest a small improvement of yum install $pkg -y && echo "Success..." so that you're not misled by a yum failure and a "Successful" echo statement. – Jeff Schaller Sep 16 '16 at 15:07
  • @JeffSchaller That is better, I was focusing on the change in variable name rather than improving the logic itself, but I'll add that in – Centimane Sep 16 '16 at 15:40
  • @JeffSchaller honestly if we're going to improve the logic just doing yum install -y $REQPKGS would probably be the way to go, yum will skip over installed packages on its own. – Centimane Sep 16 '16 at 15:42
  • I don't disagree but the Q does ask for one at a time. – Jeff Schaller Sep 16 '16 at 15:44
  • @pirulo if this answer solved your problem feel free to accept it so that this question is marked as resolved. – Centimane Sep 16 '16 at 15:44
  • Thanks guys for the input. I'm learning new stuff today so I can improved my skills. By the way how do I mark this post resolve? – pirulo Sep 16 '16 at 16:13
  • @pirulo there should be a check mark beside the answer, you can click on that. For more info: http://unix.stackexchange.com/help/someone-answers – Centimane Sep 16 '16 at 16:17
  • @JeffSchaller: I know the OP really wants to do for pkg in $REQPKGS, which is a train wreck waiting to happen, but please don’t suggest code that needlessly uses a shell variable without quoting it. See my answer to “Security implications of forgetting to quote a variable in bash/POSIX shells” for notes on how to handle multi-word variables as arrays in bash (e.g., REQPKGS=(redhat-lsb-core telnet) / for pkg in "${REQPKGS[@]}"). – G-Man Says 'Reinstate Monica' Sep 16 '16 at 17:53
  • That's a great point, @G-Man, and thank you for the link! We're solving so many more problems than the OP even knew they had. – Jeff Schaller Sep 16 '16 at 18:23
  • @G-Man I'll do the cleanup, I was really just focused on replacing the instances of the array variable inside the loop, but I'll rewrite it as I would instead – Centimane Sep 16 '16 at 18:37
  • Thanks for improving your answer. It should be noted that arrays are a feature of bash (and some other shells, like maybe ksh) but are not required by POSIX.  I guess that most systems that have yum will also have bash(?), but there may be portability issues if somebody tries to use this technique in an old or severely stripped-down system. – G-Man Says 'Reinstate Monica' Sep 16 '16 at 20:52
  • To my knowledge yum only exists on Fedora, RHEL and CentOS. Not sure if the original version of these included bash, but the versions in the last 10 years do. – Centimane Sep 17 '16 at 03:39