【问题标题】:How to properly store the output of host command in bash如何在 bash 中正确存储主机命令的输出
【发布时间】:2014-11-10 19:39:08
【问题描述】:

我正在尝试存储主机给出的 ip 地址,但主机实际上给出了一个字符串,说 host-name 的地址 ip-address 是地址数的倍它发现。所以我的问题是我可以以某种方式只访问地址,而不拆分字符串并查找 IP 地址吗?到目前为止我尝试过的看起来像这样

ip=$(host "$candidate")

IFS="s " read -ra ADDR <<< "$ip"
for i in "${ADDR[@]}"; do
    echo "$i"
done

其中 $candidate 保存主机名,但我无法真正使用它。有什么想法吗?

【问题讨论】:

  • 如果您从源/目标候选服务器设置了 ssh 访问密钥以实现无密码访问,您可以执行以下操作:ip=$(ssh user@$candidate "hostname -i")

标签: bash shell ip-address hostname


【解决方案1】:

您可以使用参数扩展/子串提取来隔离IP地址,如下:

#!/bin/bash

while read -r line; do 
    array+=( ${line##* } )      # substring extraction for IP only
done < <(host -t A google.com)

for i in ${array[@]}; do
    echo "$i"
done

输出:

$ bash getip.sh
173.194.115.36
173.194.115.35
173.194.115.40
173.194.115.37
173.194.115.34
173.194.115.39
173.194.115.41
173.194.115.46
173.194.115.33
173.194.115.38
173.194.115.32

你可以用字符串替换来完成同样的事情:

    array+=( ${line//*\ /} )      # string substitution for IP only

【讨论】:

  • 引用你的扩展——for i in "${array[@]}",否则你写的就是for i in ${array[*]}
  • 类似地:array+=( "${line##* }" ),如果您希望每行一个数组条目。
  • 或者:while IFS=' ' read -r ip _; do array+=( "$ip" ); done 通过将内容放入_ 隐式删除第一个` ` 之后的所有内容,无需PE。
  • 是的,同意,但是主机的输出格式为google.com has address 173.194.115.41,如另一个答案所示,这将导致read -r _ _ _ IP
【解决方案2】:

您可以使用不同的 DNS 查找工具,例如 dig:

$ foo=($(dig google.com +short))
$ printf '%s\n' "${foo[@]}"
74.125.228.196
74.125.228.206
74.125.228.200
74.125.228.198
74.125.228.193
74.125.228.192
74.125.228.199
74.125.228.197
74.125.228.201
74.125.228.195
74.125.228.194

如果必须使用host,则必须进行字符串拆分:

foo=()
while read -r _ _ _ addr; do
    foo+=("$addr")
done < <(host -t A google.com)
printf '%s\n' "${foo[@]}"

【讨论】:

  • 对于 bash 4 或更新版本,readarray 可用:readarray -t foo &lt; &lt;(dig google.com +short);这跳过了您的第一个答案围绕全局扩展和奇数 IFS 值的一些错误。也就是说,+1 建议 dig +short
猜你喜欢
  • 1970-01-01
  • 2021-10-18
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多