0

I have script that checks the availability of package on my server, it iterate through array and should return [INSTALLED] if it is. Below script is modified to the basic to give you understanding what'd it do.

#!/bin/bash

declare -a prog=("mysql-server" "apache2" "php" "ufw")
declare -a snap=("beer")

for f in "${!prog[@]}"; do
  for connect in "${snap[@]}"; do
    ssh jan@"$connect" /bin/bash <<- EOF
    if [ \$(dpkg --get-selections | grep -E "(^|\s)${prog[$f]}(\$|\s)" | wc -l) -gt 0 ]; then
      prog[$f]="${prog[$f]} [INSTALLED]" # The program is already installed
      echo "\${prog[@]}"
    else
      echo "False"
    fi
EOF
    done
  done

This should return the package name and [INSTALLED] suffix if it is installed, otherwise it will only return the package name.

I expect the output to be:

mysql-server [INSTALLED]
apache2 [INSTALLED]
php [INSTALLED]
ufw

Turns out the output was:

mysql-server [INSTALLED]
apache2 [INSTALLED]
php [INSTALLED]
False

ufw package is not installed on the server, I expect it to return ufw instead Not installed— if I remove the else clause altogether, ufw would not be appear on the output at all.

Liso
  • 188
  • 2
  • 14
  • not sure I understand the issue ... the `else` block is coded to print `False` and that appears to be what it does; if different output is desired then update the `else` block to output the desired output; what am I missing? – markp-fuso Jan 09 '20 at 13:19
  • 2
    `if [ \$(dpkg --get-selections | grep -E "(^|\s)${prog[$f]}(\$|\s)" | wc -l) -gt 0 ]` just do `if dpkg --get-selections | grep -qE "(^|\s)${prog[$f]}(\$|\s)"; then`. But just to check if a package is installed, I think you can just `if dpkg -l "${prog[$f]}"; then` – KamilCuk Jan 09 '20 at 13:30
  • Exactly that. `[` is an alias to the `test` command. If you wouldn't use `test`, don't use `[`. – Charles Duffy Jan 09 '20 at 13:32
  • 2
    Your script has other problems as well. You don't need to modify `prog` at all; just output `$f` on each iteration, possibly with `[INSTALLED]` following it if the condition is true. – chepner Jan 09 '20 at 13:35
  • @chepner That seems like nice idea, but how would I do that ? Sorry I'm not really strong on bash language. – Liso Jan 10 '20 at 10:27
  • Your if statement would just set `status="[INSTALLED]"` or `status=""`, based on the result of `dpkg`. After the `if`, you would unconditionally execute `printf '%s %s\n' "$f" "$status"`. – chepner Jan 10 '20 at 12:35
  • @chepner Thank you very much ! that's working, I've never thought to do this. And its so much faster than before – Liso Jan 10 '20 at 12:48
  • @chepner But I faced a new problem, the output seems to be doubled as I add new server in `$snap` array, it understandable because the ssh loops through the array, but how to merge it to one ? Should I ask new question ? – Liso Jan 10 '20 at 12:49
  • Perhaps you want `connect` in the output string as well, so you can differentiate between `mysql-server` being installed on one server or the other. – chepner Jan 10 '20 at 12:58
  • @chepner Actually, I have done that before, but the result just weren't [right](https://paste.ubuntu.com/p/HzB4xHFGRx/), I want it to merge to one line so theres no duplicate entries. – Liso Jan 10 '20 at 13:28
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/205753/discussion-between-johnny-and-chepner). – Liso Jan 10 '20 at 13:29

0 Answers0