基于Python Shell获取hostname和fqdn释疑

系统 1705 0

一直以来被Linux的hostname和fqdn(Fully Qualified Domain Name)困惑了好久,今天专门抽时间把它们的使用细节弄清了。

一、设置hostname/fqdn

在Linux系统内设置hostname很简单,如:

$ hostname florian

如果要设置fqdn的话,需要对/etc/hosts进行配置。

            
$ cat /etc/hosts
127.0.0.1 localhost
192.168.1.1 florian.test.com florian 
          

/etc/hosts配置文件的格式是:

ip fqdn [alias]...

即第一列为主机ip地址,第二列为主机fqdn地址,第三列以后为别名,可以省略,否则至少要包含hostname。

上述配置文件的配置项的第一行为localhost的配置,第二行为主机名florian配置fqdn=florian.test.com,ip=192.168.1.1。
至于fqdn的域名后缀,最好和文件/etc/sysconfig/network的HOSTNAME配置保持一致:

            
$ cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=test.com
          

二、查看hostname/fqdn

配置完成后,可以使用shell命令查看hostname和fqdn:

            
$ hostname && hostname -f 
florian
florian.test.com 
          

使用ping去测试hostname的ip映射是否成功。

            
$ ping florian
PING florian.test.com (192.168.1.1) 56(84) bytes of data.
$ ping florian.test.com
PING florian.test.com (192.168.1.1) 56(84) bytes of data. 
          

也可以使用python命令获取hostname和fqdn。

            
$ python 
Python 2.6.6 (r266:84292, Dec 7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> socket.gethostname()
'florian'
>>> socket.getfqdn() 
'florian.test.com' 
          

三、使用ip设置hostname带来的fqdn问题

以上描述了正常设置hostname和fqdn的方法,但是有时会使用ip地址直接作为hostname,此时会有些不同。

            
$ hostname 192.168.1.1
$ hostname && hostname -f
192.168.1.1
192.168.1.1 
          

我们发现使用ip作为hostname后,使用shell命令查询hostname和fqdn都是ip地址!!!这是因为DNS协议会解析hostname的内容,当发现其为ip地址时,则不会再去查询/etc/hosts文件。

再使用python查看一下,会发现python获取的fqdn竟然还是florian.test.com!!!

            
$ python
Python 2.6.6 (r266:84292, Dec 7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket 
>>> socket.gethostname()
'192.168.1.1'
>>> socket.getfqdn()
'florian.test.com' 
          

即便是刷新dns缓存也无济于事:

$ service nscd reload

将/etc/hosts文件的第二行注释:

            
cat /etc/hosts
127.0.0.1 localhost
# 192.168.1.1 florian.test.com florian 
          

刷新dns缓存:

$ service nscd reload

我们发现fqdn恢复正常了。

            
$ python
Python 2.6.6 (r266:84292, Dec 7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket 
>>> socket.gethostname()
'192.168.1.1'
>>> socket.getfqdn()
'192.168.1.1' 
          

之所以会有这样的行为,是因为python解析fqdn的逻辑和DNS并不完全一致,它会根据hostname查询对应的ip地址,然后在/etc/hosts内获取ip地址对应的配置行(第一行有效),然后解析fqdn列和alias列,并返回第一个包含字符'.'的对应列的值。

因此,使用ip设置hostname时,需要注意两点:

•首先,将hostname设置为ip地址
•其次,将/etc/hosts内包含该ip的配置项移除

为了保险起见,我们可以在/etc/hosts内尽可能靠前的位置添加如下配置:

            
cat /etc/hosts
127.0.0.1 localhost
192.168.1.1 192.168.1.1 
          

这样,即便是之后有包含该ip的配置项也不会生效,python会优先解析第二行的配置项,并获取和ip地址完全一样的fqdn地址。当然,使用shell命令hostname获取fqdn也不会出错,因为hostname已经被设为ip地址形式了。

下面给大家介绍python shell 根据ip 获取 hostname || 根据hostname 获取 ip

利用 socket 模块 里的 gethostbyname 函数

            
              >>> import 
              
                socket
              
               >>> 
              
                socket
              
              .
              
                gethostbyname
              
              (
              
                "www.baidu.com"
              
              ) 
              
                '61.135.169.125'
              
               >>> 
              
                socket
              
              .
              
                gethostbyname
              
              (
              
                "rs.xidian.edu.cn"
              
              ) 
              
                '202.117.119.1'
              
            
            
  • 1
  • 2
  • 3
  • 4
  • 5

方法2 利用 shell 中 hostname 命令

            
              def getHostName(ip): 
              
                
                  command
                
                 = 
                
                  'java -jar %s %s "hostname > %s.hostname"'
                
                 %(
                
                  remoteCmdLoca
                
                ,
                
                  ip
                
                ,
                
                  ip
                
                )
              
              
                result
              
               = subprocess.call(
              
                
                  command
                
                , 
                
                  shell
                
                =
                
                  True
                
                )
              
              
                
                  command
                
                 = 
                
                  '%s -q -r -pw Sybase123 %s root@%s:/root'
                
                 % (
                
                  pscpLoca
                
                , 
                
                  pscpLoca
                
                , 
                
                  ip
                
                )
              
              
                result
              
               = subprocess.call(
              
                
                  command
                
                , 
                
                  shell
                
                =
                
                  True
                
                )
              
              
                
                  command
                
                 = 
                
                  '%s -q -r -pw Sybase123 root@%s:/root/%s.hostname %s'
                
                 %(
                
                  pscpLoca
                
                ,
                
                  ip
                
                ,
                
                  ip
                
                ,
                
                  sumAutoLoca
                
                )
              
              
                result
              
               = subprocess.call(
              
                
                  command
                
                , 
                
                  shell
                
                =
                
                  True
                
                )
              
               fileName = sumAutoLoca + ip + 
              
                '.hostname'
              
               readFile = 
              
                open
              
              (fileName,
              
                'r'
              
              ) hostnameInfo = str(readFile.readline().strip(
              
                '\n'
              
              )) readFile.
              
                close
              
              () subprocess.call(
              
                'rm '
              
              + fileName, 
              
                shell
              
              =True) print 
              
                "=========%s hostname is %s========"
              
               %(ip,hostnameInfo) 
              
                return
              
               hostnameInfo
            
            
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

设计思路 ##

有时候socket不太稳定, 具体原因带查明

目的: 根据 ip 获取 hostname (适当改进也可逆转)

先设计了一个远程执行 ssh 命令jar, 或者可以用plink, 链接enter link description here

利用subprocess.call命令在远程ip机器上执行hostname > %s.hostname命令, 将hostname 信息输出到文件

用pscp将本地的pscp文件复制到远程ip机器上 /root 目录下(后来发现这步不需要)

然后利用本地的 pscp 将远程机器上带有hostname的文本文件/root/%s.hostname 复制到本地

利用 python 的文本读取功能读取信息, 从中取出hostname字符串

再利用 rm 命令把远程机器和本地的文本文件都删除


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论