nillenilsson
nillenilsson

Reputation: 513

Assign part of a command's output to a variable in bash?

I have this update script i am working on and i am using ssh to log onto the machine and simply run apt-get update && apt-get upgrade -y. Now the thing is i want to be able to say something like "hostname" updated successfully.

Here's what i have written right now:

#!/bin/bash

ip=(192.168.1.23 192.168.1.40 192.168.1.41 192.168.1.42 192.168.1.43)
#ssh-key=~/.ssh/id_ed25519


for i in "${ip[@]}"; do {
  ssh -t victor@$i "sudo apt-get update && sudo apt-get upgrade -y"
    if [ $? -eq 0 ]; then
      echo "Update went successfully";
    else
      echo "$(tput smul)$(tput setaf 1)Update failed$(tput rmul)";
      exit 1;
    fi
} done;

with the same ssh -t command i was thinking if i could get the hostname and assign it to a variable at the same time i'm using the first ssh session. That is so i dont have to write in my password for the ssh key twice.

So something like this:

hostname=$"(ssh -t victor@$i hostname && sudo apt-get update && sudo apt-get upgrade -y"

And then i just echo $hostname.

Upvotes: 1

Views: 191

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295934

{ read -r hostname; read -r -d '' rest; retval=$?; } < <(
  ssh "victor@$i" "
    hostname || echo
    sudo apt-get update && sudo apt-get upgrade -y && printf '\0'
  "
)
printf '%s\n' "$rest"
if [[ $retval = 0 ]]; then  ## this is intentionally a string comparison, not numeric
  echo "Remote SSH command was successful"
else
  echo "Remote SSH command failed"
fi

Let's break this down into pieces:

  • <(...) is process substitution syntax, which substitutes a filename which will, when read from, return the output of a subshell running the given commands. Thus, < <(...) is redirecting from this process substitution.
  • read -r hostname, run locally, reads a single line into the variable named hostname.
  • read -r -d '' rest reads up to the next NUL character, with a successful exit status if such a NUL is seen, and an unsuccessful exit status if not.
  • hostname || echo writes the system's hostname (if successful) or an empty line (otherwise).
  • ... && printf '\0' puts a NUL on the end of the output from ssh (causing read -r -d '' rest to exit with a successful exit status) only if the commands in ... succeeded.

(Simplified from the original answer to no longer need bash 4.4 to detect when the remote apt-get commands failed).

Upvotes: 1

daniel.971
daniel.971

Reputation: 64

Maybe something like

hostname="$(nmblookup -A <ip>)"

and then

if [ $? -eq 0 ]; then
  echo "$hostname: Update went successfully."
else
  echo "$hostname: Update failed!"
fi

Upvotes: 0

Related Questions