将命令的一部分输出分配给bash中的变量?

时间:2017-03-31 13:29:42

标签: linux bash ssh

我正在使用此更新脚本,我正在使用ssh登录计算机,只需运行apt-get update&& apt-get upgrade -y。现在问题是我希望能够说出像#34; hostname"已成功更新。

这是我现在写的:

#!/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;

使用相同的ssh -t命令我在想是否可以获取主机名并在使用第一个ssh会话的同时将其分配给变量。这样我就不必两次写入ssh密码的密码了。

这样的事情:

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

然后我只是回显$ hostname。

2 个答案:

答案 0 :(得分:1)

{ 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

让我们把它分解成碎片:

  • <(...)进程替换语法,它替换了一个文件名,当读取该文件名时,将返回运行给定命令的子shell的输出。因此,< <(...)正在从此流程替换重定向。
  • read -r hostname,在本地运行,在名为hostname的变量中读取一行。
  • read -r -d '' rest读取下一个NUL字符,如果看到这样的NUL,则成功退出状态,如果没有,则读取不成功退出状态。
  • hostname || echo写入系统的主机名(如果成功)或空行(否则)。
  • ... && printf '\0'仅在{{1}中的命令时,在ssh的输出结尾处放置一个NUL(导致read -r -d '' rest以成功的退出状态退出)成功

(从原始答案简化为不再需要bash 4.4来检测远程apt-get命令何时失败)。

答案 1 :(得分:0)

也许像

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

然后

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