0

I'm trying to learn how to write Bash scripts. I have this script to update my servers through ssh. I'm trying to add a check and a conditional to determine if the OS uses Yum or Apt then it will run the appropriate update commands. The if else statement seems to be wrong but I'm not sure how to correct this.

Here is the script:

#!/bin/bash
USERNAME="root"
HOSTS="host1 host2 host3"
apt_run="apt update && apt -y upgrade"
yum_run="yum check-update && yum -y update"

for HOSTNAME in ${HOSTS} ; do
    ssh -l ${USERNAME} ${HOSTNAME} 
    find_os=$( command -v yum || command -v apt-get ) || echo "Neither 
    yum nor apt-get found"
    if [[ $find_os='yum' ]]
       then
       "${yum_run}"
    else
       "${apt_run}"
    fi

done
6
  • What are the scripts after "Neither yum nor $? Seems its too long and cut off by an editor. Commented Jan 18, 2020 at 20:46
  • Spaces are part of shell syntax. You want [[ $find_os == 'yum' ]] or probably more accurately (because command -v yum on my workstations returns /usr/bin/yum): [[ "${find_os##*/}" == yum ]] Commented Jan 18, 2020 at 20:57
  • 1
    Also of note: you are running those commands locally, not over ssh. Feed the commands to be ran remotely to stdin via a heredoc. Commented Jan 18, 2020 at 20:58
  • ssh -l ${USERNAME} ${HOSTNAME} <there is no command here>. The syntax is user@host... Commented Jan 18, 2020 at 21:06
  • 1
    Storing commands in variables (like apt_run and yum_run) has severe problems (see BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!). Using it with ssh might actually work, because the oddities of ssh command parsing might cancel out those of variable expansion... sort of. Maybe. But IMO it's better to avoid the additional source of confusion, and just use commands directly wherever possible. Commented Jan 18, 2020 at 21:29

1 Answer 1

2

Here is my script for my virtual machines.

#!/bin/bash

hosts=(
  leap151 kali ubuntu omv
)

for hostname in "${hosts[@]}"; do
ssh -t root@"$hostname" << 'EOF'
  if type -P zypper >/dev/null; then
    command zypper ref && command zypper up
   elif type -P apt-get >/dev/null; then
     command apt-get update && command apt-get upgrade
  else
    echo 'Neither zypper nor apt found!' >&2
    exit 127
  fi
EOF
done

Use an array for the host. Since you're using bash the builtin type is fine just for searching the executable within your PATH. See help type for more info. Use the -t option in ssh also use a heredoc just what I have/did. The exit 127 is what the shell would exit if there are no executable see man 1p exit.

Sign up to request clarification or add additional context in comments.

4 Comments

What are the functions for? They're defined in the local shell, so they won't be available to the remote shells running over ssh (and you don't seem to use them at all -- just the literal commands, which will work fine).
command apt-get update && apt-get - why do you use command at all, and why do you use it with the first, but not with the second command?
yeah, need the command with both apt-get, I will update the script.
Yeah, sorry the function got mixed up on my dev branch. Ill remove them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.