ฉันจะใช้ Python เพื่อรับชื่อโฮสต์ของระบบได้อย่างไร


681

ฉันกำลังเขียนโปรแกรมแชทสำหรับเครือข่ายท้องถิ่น ฉันต้องการระบุคอมพิวเตอร์และรับชื่อคอมพิวเตอร์ที่ผู้ใช้ตั้งด้วย Python

คำตอบ:


1043

การใช้socketและgethostname()ฟังก์ชั่นของมัน สิ่งนี้จะได้รับhostnameคอมพิวเตอร์ที่ใช้งานตัวแปล Python:

import socket
print(socket.gethostname())

70
ก็ไม่ถูกต้อง มันทำงานได้สำหรับฉันออฟไลน์และในบ้าน แต่ตอนนี้ฉันเป็นสำนักงานและนี่จะส่งคืนชื่อโฮสต์อื่น
DataGreed

74
และโปรดทราบว่าสำหรับ FQDN คุณสามารถใช้socket.getfqdn()
Dave Forgac

31
@DataGreed นั่นเป็นเพราะชื่อโฮสต์ของคุณกำลังเปลี่ยนแปลง ไม่ใช่ปัญหาของงูหลาม
strickli

4
@DataGreed 1. ฉันค่อนข้างแน่ใจว่ามันไม่ใช่ "สุ่ม" แม้ว่ามันอาจจะเป็นแบบนั้นก็ตาม 2. คำถามที่ถามว่า "ชื่อโฮสต์ของระบบ" ไม่ใช่ "ชื่อระบบ" 3. สำหรับระบบจำนวนมาก (ไม่รวมถึง windows) เป็นโฮสต์และชื่อระบบเหมือนกัน
strickli

8
เพียงแค่อยากรู้ว่าสิ่งที่แตกต่างระหว่าง socket.gethostname () และ os.uname () [1] หรือ platform.uname () [1]
LetsOMG

388

ทั้งสองแบบพกพาสวย:

import platform
platform.node()

import socket
socket.gethostname()

โซลูชันใด ๆ ที่ใช้HOSTหรือHOSTNAMEตัวแปรสภาพแวดล้อมไม่สามารถเคลื่อนย้ายได้ แม้ว่ามันจะทำงานบนระบบของคุณเมื่อคุณเรียกใช้มันอาจไม่ทำงานเมื่อทำงานในสภาพแวดล้อมพิเศษเช่น cron


6
แบบพกพากึ่งดี ในบางแพลตฟอร์ม platform.node () จะให้ค่า fqdn และที่อื่น ๆ มีเพียงชื่อโฮสต์เท่านั้น
raindog308

3
python -m timeit "import socket; socket.gethostname()" 10000 loops, best of 3: 76.3 usec per loop
ใต้ Radar

8
python -m timeit "import platform; platform.node()" 1000000 loops, best of 3: 0.74 usec per loop
ใต้ Radar

7
@BelowtheRadar ไม่ต้องกังวลฉันมักจะเรียกเหล่านี้หนึ่งครั้งต่อสคริปต์
เบิ

6
platform.node () เร็วยิ่งกว่า os.getenv gethostname ไม่ได้เป็นคู่แข่ง แต่ถ้าเวลาไม่ใช่ปัจจัย: import os, platform; os.getenv('HOSTNAME', os.getenv('COMPUTERNAME', platform.node())).split('.')[0]ควรเป็นข้ามแพลตฟอร์มและสนับสนุนตัวแปรสภาพแวดล้อมหากมี - ซึ่งอนุญาตให้ผู้ใช้ควบคุมบางอย่างในสถานการณ์เร่งHOSTNAME=correct python xyz.py
ด่วน

121

คุณอาจจะโหลดโมดูลระบบปฏิบัติการต่อไปดังนั้นข้อเสนอแนะอื่นจะเป็น:

import os
myhost = os.uname()[1]

8
+1 สำหรับการแก้ปัญหาโดยใช้osโมดูล ไม่ใช่แบบพกพาและไม่แม่นยำจริงๆ แต่ก็มีประโยชน์อยู่ดี
MestreLion

20
ไม่รองรับ os.uname บน Windows: docs.python.org/dev/library/os#os.uname
Noam Manos

9
คุณสามารถทำ os.uname (). nodename เพื่อให้ชัดเจนขึ้นใน 3.3+
Hut8 8

4
คำตอบด้านล่างให้ภาพที่คล้ายกันplatform.uname()[1]ซึ่งทำงานบน Windows
เพ้อฝัน

6
@fantabolous คุณอาจไม่ควรใช้คำตำแหน่งเช่น "ด้านล่าง" เนื่องจากคำตอบอาจเปลี่ยนไประหว่างการลงจอด)
Jonathan Komar

65

เกี่ยวกับ:

import platform

h = platform.uname()[1]

ที่จริงแล้วคุณอาจต้องการดูผลลัพธ์ทั้งหมด platform.uname()


1
ทำงานบน Ubuntu และ Windows สำหรับฉัน ขอบคุณ! 👍
GollyJer

61

os.getenv('HOSTNAME')และos.environ['HOSTNAME']ไม่ได้ผลเสมอไป ในงาน cron และ WSDL HTTP HOSTNAME จะไม่ถูกตั้งค่า ใช้สิ่งนี้แทน:

import socket
socket.gethostbyaddr(socket.gethostname())[0]

มันก็จะ (แม้ใน Windows) ส่งกลับชื่อโฮสต์ที่มีคุณสมบัติครบถ้วนแม้ว่าคุณจะกำหนดนามแฝงสั้น ๆ ใน/ etc / hosts

หากคุณกำหนดนามแฝงใน/ etc / hostsแล้วsocket.gethostname()จะกลับนามแฝง platform.uname()[1]ทำสิ่งเดียวกัน

ฉันวิ่งเข้าไปในกรณีที่ข้างต้นไม่ทำงาน นี่คือสิ่งที่ฉันใช้ตอนนี้:

import socket
if socket.gethostname().find('.')>=0:
    name=socket.gethostname()
else:
    name=socket.gethostbyaddr(socket.gethostname())[0]

ก่อนอื่นจะเรียกใช้ gethostname เพื่อดูว่าจะส่งคืนบางสิ่งที่ดูเหมือนชื่อโฮสต์หรือไม่ถ้าไม่ใช่จะใช้โซลูชันดั้งเดิมของฉัน


15
คุณอาจต้องการsocket.getfqdn()แม้ว่ามันจะไม่ใช่สิ่งที่ OP ถาม
jfs




5

ในบางระบบชื่อโฮสต์จะถูกตั้งค่าในสภาพแวดล้อม หากเป็นกรณีที่สำหรับคุณโมดูล OSสามารถดึงมันออกมาจากสภาพแวดล้อมที่ผ่านos.getenv ตัวอย่างเช่นถ้า HOSTNAME เป็นตัวแปรสภาพแวดล้อมที่มีสิ่งที่คุณต้องการสิ่งต่อไปนี้จะได้รับ:

import os
system_name = os.getenv('HOSTNAME')

อัปเดต: ตามที่ระบุไว้ในความคิดเห็นสิ่งนี้อาจไม่ได้ผลเนื่องจากสภาพแวดล้อมของทุกคนไม่ได้รับการตั้งค่าด้วยวิธีนี้ ฉันเชื่อว่าในตอนแรกที่ฉันตอบคำถามนี้ฉันใช้โซลูชันนี้เพราะเป็นสิ่งแรกที่ฉันพบในการค้นหาเว็บและใช้งานได้ในเวลานั้น เนื่องจากขาดการพกพาฉันอาจจะไม่ใช้สิ่งนี้ในตอนนี้ อย่างไรก็ตามฉันจะทิ้งคำตอบนี้ไว้เพื่ออ้างอิง FWIW จะกำจัดความต้องการการนำเข้าอื่น ๆ หากสภาพแวดล้อมของคุณมีชื่อระบบและคุณกำลังนำเข้าโมดูลระบบปฏิบัติการแล้ว ทดสอบถ้าไม่สามารถใช้งานได้ในทุกสภาพแวดล้อมที่คุณคาดว่าโปรแกรมของคุณจะทำงานให้ใช้วิธีการแก้ปัญหาอื่นที่มีให้


5
ที่ส่งกลับ "ไม่มี" สำหรับฉัน ตามลิงค์ที่คุณโพสต์นั่นหมายความว่าไม่มีตัวแปร 'HOSTNAME' ... : - /
John

@John: คุณใช้ Windows เหรอ? มันใช้งานได้สำหรับฉันบนกล่อง Linux แต่ฉันก็ไม่มี None บน Windows ด้วย
GreenMatt

@MuhiaNJoroge: ฉันคิดว่ามันขึ้นอยู่กับการใช้งาน / การติดตั้งของคุณ เมื่อฉันเขียนคำตอบนั้นฉันอยู่ในกล่อง Red Hat และทำงานได้ ตอนนี้ฉันอยู่บน Ubuntu และมันใช้งานไม่ได้ ฉันแก้ไขคำตอบแล้ว
GreenMatt

ไม่ทำงานใน lenovo NAS ส่งคืนไม่มี ตอนนี้ฉันใช้การพิมพ์ซ็อกเก็ตนำเข้า (socket.gethostname ())
Rui Martins

@RuiMartins: อย่างที่ฉันพูดไปดูเหมือนว่ามันจะไม่ทำงานทุกที่ ดีใจที่คุณพบบางสิ่งที่ใช้งานได้
GreenMatt

5

ฉันต้องการชื่อของพีซีเพื่อใช้ในไฟล์ PyLog conf ของฉันและซ็อกเก็ตไลบรารี่ไม่สามารถใช้งานได้ แต่ไลบรารี่ของ os คือ

สำหรับWindowsฉันใช้:

os.getenv('COMPUTERNAME', 'defaultValue')

โดยที่ defaultValue เป็นสตริงเพื่อป้องกันไม่มีการส่งคืน


12
COMPUTERNAME เป็นตัวแปรสภาพแวดล้อมของ Microsoft เท่านั้นและไม่สามารถพกพาได้
Dwight Spencer

1
ใช่ แต่มันใช้งานได้กับระบบ MS และถ้ามันเหมาะกับมันก็ใช้งานได้ หลายครั้งที่ผู้คนที่นี่ได้รับการผูกมัดเกี่ยวกับความเร็วหรือความเป็นอิสระของแพลตฟอร์มเมื่อการปฏิบัติจริงและคำถามทำให้พวกเขาไม่เกี่ยวข้อง
Bill Kidd

7
@BillKidd OP กล่าวถึง Windows, OS X และ Linux ในคำถามดังนั้นความต้องการการพกพาของระบบจึงเป็นข้อสันนิษฐานที่สมเหตุสมผลมาก
zstewart

1
@BillKidd โดยทั่วไปแล้วมันเป็นความจริงที่คุณควรหลีกเลี่ยงการปรับให้เหมาะสมหรือการพกพาก่อนวัยอันควรโดยไม่ต้องใช้โซลูชั่นที่พร้อมใช้งานและวิธีแก้ปัญหาที่บำรุงรักษาได้มากกว่าเพราะพกพาได้มากกว่า
นักฟิสิกส์บ้า

2

คุณต้องรันรหัสบรรทัดนี้

sock_name = socket.gethostname()

จากนั้นคุณสามารถใช้ชื่อเพื่อค้นหา addr:

print(socket.gethostbyname(sock_name))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.