Linux實例如何決定其IP位址?
也就是說,不是 127.0.0.1。
這是儲存在檔案中還是 ifconfig 在每次呼叫時都會以某種方式計算它?
我設法解決它只是為了表明我付出了努力,但這不是我在認真的應用程式中放入的任何內容:
sudo ifconfig | head -n 2 | tail -n 1 | tr -s " " | tr " " ":" | cut -d":" -f 4
答案1
你的問題有一個根本性的缺陷。首先,主機可能(並且很可能)具有多個位址(例如,多個介面),甚至每個介面具有多個位址。對於 IPv6,這更是一個問題,其中每個全球連接的主機至少二地址。
其次,從 shell 執行此操作的“最佳”方法因係統而異。
Linux:
/sbin/ip addr show eth0 | awk -F"[ /]+" '/inet / {print $3}'
>= Solaris 11:
ipadm show-addr net0/v4 | awk -F"[ /]+" '/ok/ {print $5}'
Mac OS X/達爾文:
ipconfig getifaddr en0
即使採用最低公分母並使用ifconfig
也不會保持一致,因為輸出格式可能會變更。但是,要清理您的範例,請使用以下命令:
ifconfig eth0 | awk -F"[ :]+" '/inet / {print $4}'
如果您使用 perl、ruby、java 等更高級的語言而不是 shell,則每種語言都有自己的從核心獲取此資料的方法。我將把這個問題留給你來尋找。
答案2
這些資訊隨時可能改變,因此需要從核心中檢索,不能儲存在檔案中。
沒有真正好的方法來獲取此資訊。您的解析與任何解析一樣好,只是第二行的硬編碼是錯誤的:不能保證介面將以任何特定順序列出。一台機器具有多個介面是相當常見的:您可能有多個網路卡或虛擬介面。
通常,您感興趣的 IP 位址是與預設路由關聯的 IP 位址。對於大多數配置,您可以使用該命令取得正確的接口route
,然後使用 提取該接口的 IP 位址ifconfig
。
/sbin/ifconfig $(/sbin/route -n |
awk '$1 == "0.0.0.0" {print $8}') |
awk 'match($0, /inet addr:[.0-9]+/) {print substr($0, RSTART+10, RLENGTH-10)}'
請注意,無需調用sudo
.ifconfig
並且route
通常不是PATH
非 root 用戶的預設設置,但只要您只是讀取資訊而不更改設置,就可以在沒有特殊權限的情況下使用它們。
在 Linux 以外的 UNIX 變體上,您可能需要調整上面的指令。大多數都有名為ifconfig
和的命令route
,但輸出格式可能不同。
在 Linux 下,您可以使用以下命令來代替ifconfig
和:route
ip
ip路由2工具套件。雖然 iproute2 的作者考慮ifconfig
並route
棄用 iproute2,但事實上使用 並沒有什麼優勢ip
,因為 的輸出ip
並沒有明顯更容易解析,並且ifconfig
和route
始終可用,而一些精簡的 Linux 安裝省略了ip
。
答案3
這裡的所有答案在技術上都是正確的,但它們不是我認為的“正確”答案。不幸的是,你的問題非常模糊(如果你不太了解 Linux 中的網路工作原理,我可以理解),所以我將對這個問題的可能解釋給出一些答案。
機器的主IP
該機器有一個高於所有其他 IP 的 IP,該 IP 被視為機器的主要 IP。請注意,儘管這毫無意義,因為一個盒子可以有多個 IP,並且使用哪個 IP 會有所不同(我稍後會詳細介紹這一點)。
主 IP 只是與電腦主機名稱關聯的 IP。您可以透過執行以下命令找到該IP
getent hosts "$(hostname)" | awk '{ print $1 }'
現在,它的作用是根據 尋找機器主機名稱的 IP /etc/nsswitch.conf
。在大多數情況下,該/etc/nsswitch.conf
文件包含hosts: files dns
.這表示當嘗試執行任何類型的主機名稱或位址查找時,它將/etc/hosts
首先查找,然後查詢 DNS(如配置/etc/resolv.conf
)。
因此該命令getent hosts "$(hostname)"
可能會從 中取得符合的條目/etc/hosts
。只是awk
簡單地從該行中獲取 IP。
(getent
只是一個用於查詢中列出的“資料庫”的簡單實用程式/etc/nsswitch.conf
)
用於與外界通訊的IP
正如我之前提到的,機器的主 IP 毫無意義。機器可以使用多個 IP 中的任何一個進行通訊。就您而言,您可能只有一個介面和一個(非本地主機)IP。但是,一台伺服器可以有多個介面或 IP(有時單一介面上有多個 IP)。
使用哪個 IP 由核心的路由表決定。我不打算詳細介紹路由表的工作原理,因為它並不簡單(有多個路由表,使用哪一個取決於表選擇規則)。我只是告訴你如何找到哪個IP將被使用。
若要找出將使用哪個 IP 與特定目標進行通信,請使用以下命令:
ip route get 1.2.3.4
(作為1.2.3.4
目的地的IP)
在我的機器上,如果我使用 google.com 的 IP ( ) 之一執行此操作74.125.139.102
,我會得到以下結果:
74.125.139.102 via 192.168.0.1 dev wlan0 src 192.168.0.24
cache
這告訴我的是,192.168.0.24
每當我的機器與 . 進行通訊時,都會使用該 IP 74.125.139.102
。
如果你只想要IP,你可以grep
在最後加上一個額外的IP。
ip route get 1.2.3.4 | grep -oP '(?<=src )\S+'
grep
使用 代替 an 是awk
因為它不太容易出錯。該行可能會發生變化,其中 IP 不會位於同一位置,但它始終遵循“src”,因此我們只需獲取“src”之後立即的值
預設網關IP
最後,還有預設網關。如果您沒有特定的目的地來查詢將使用哪個 IP,則可以從預設閘道中選擇一個。如果您只有一個介面,那麼無論如何這都是最重要的。
這基本上和上面一模一樣,只是使用預設網關作為我們尋找的目的地
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')"
這將為您提供類似於上一節中的一行。該src
值是將用於流經預設閘道的流量的 IP。
與上一節一樣,要僅獲取 IP,請添加grep
.
ip route get "$(ip route show to 0/0 | grep -oP '(?<=via )\S+')" | grep -oP '(?<=src )\S+'
答案4
您的請求不明確,通常使用“localhost”一詞表示環回接口,而 127.0.0.1 是最常見和正確的答案。
你缺少的是:
- 事實上,每個接口都可以有不同的 IP,環回接口是一個網路接口,就像您的乙太網路卡或無線 USB 接收器一樣。
- 因此,一台 PC 沒有一個 IP,這完全取決於您正在考慮的介面以及您的作業系統下使用的介面數量。
您可能對「核心路由表」主題感興趣,這是開始了解核心如何處理網路活動的好方法。