簡體   English   中英

Linux bash腳本提取IP地址

[英]Linux bash script to extract IP address

我想在我的 Debian 7.3 上制作大腳本(類似於翻譯的內容和更多新的用戶友好環境)。 我有個問題。 我只想使用命令給我的一些信息。 例如我的 ifconfig 看起來像:

eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0  
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1309425 (1.2 MiB)  T

我只想在行中顯示 IP 地址: echo "Your IP address is: (IP_ADDRESS )"。 有沒有任何命令可以讓我做這樣的事情,在 stream 中搜索我想要獲取的信息? 我知道grepsed但我對它們不是很好。

編輯:首先要感謝您幫助我解決這個問題,現在我知道更多了。 其次說項目正在進行中。 如果有人對它感興趣,請pm我。

如果目標是找到互聯網方向連接的IP地址,那么這應該是一個很好的解決方案。

2021 年編輯:添加了“sed”和“grep”版本以及新的“awk”版本(有些是 gnu)


要查找連接到 Internet 的ip route ,我們可以使用ip route命令。 使用較新版本的 Linux,您可以通過如下典型輸出獲得更多信息:

ip route get 8.8.8.8
8.8.8.8 via 10.36.15.1 dev ens160 src 10.36.15.150 uid 1002
    cache

所以要獲得IP,您需要在src之后找到 IP,使用awksedgrep

ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/src (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/src/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*src (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*src \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?src (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'src \K[^ ]+'
10.36.15.150

如果您喜歡使用awksedgrep接口名稱

ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}'
ip route get 8.8.8.8 | awk 'match($0,/dev (\S*)/,a)&&$0=a[1]'
ip route get 8.8.8.8 | awk '{for(i=1;i<=NF;i++)if($i~/dev/)$0=$(i+1)}NR==1'

ip route get 8.8.8.8 | sed -E 's/.*?dev (\S+) .*/\1/;t;d'
ip route get 8.8.8.8 | sed 's/.*dev \([^ ]*\).*/\1/;t;d'
ip route get 8.8.8.8 | sed  -nE '1{s/.*?dev (\S+) .*/\1/;p}'

ip route get 8.8.8.8 | grep -oP 'dev \K[^ ]+'
ens192

ip route不會打開任何連接,它只顯示到達8.8.8.8所需的路由。 8.8.8.8是谷歌的 DNS。

如果您想將其存儲到變量中,請執行以下操作:

my_ip=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')

my_interface=$(ip route get 8.8.8.8 | awk -F"dev " 'NR==1{split($2,a," ");print a[1]}')

為什么其他解決方案可能會失敗:

ifconfig eth0

  • 如果您擁有的接口有另一個名稱(eno1、wifi、venet0 等)
  • 如果您有多個接口
  • IP連接方向不是多個IF列表中的第一個

Hostname -I

  • 可能只得到 127.0.1.1
  • 不適用於所有系統。
  • 給所有 IP 不僅是連接到互聯網的 IP。 -I, --all-ip-addresses 主機的所有地址

要獲取您的 IP 地址:

echo `ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`

這將為您提供 eth0 的 IP 地址。

編輯:由於最近版本的 Ubuntu 中接口的名稱更改,這不再起作用。 相反,你可以使用這個:

hostname --all-ip-addresseshostname -I ,它們做同樣的事情(給你主機的所有 IP 地址)。

如果您想獲取以空格分隔的 IP 列表,您可以使用帶有--all-ip-addresses (short -I ) 標志的hostname命令

hostname -I

如此處所述: 將 IP 地址放入 bash 變量。 有更好的方法嗎?

ip -4 addr show eth0 | grep -oP "(?<=inet ).*(?=/)"

可能不適用於所有情況(特別是如果您有多個 NIC),這將有所幫助:

hostname -I | awk '{ print $1 }'

隨你挑:

$ cat file
eth0      Link encap:Ethernet  HWaddr 08:00:27:a3:e3:b0
          inet addr:192.168.1.103  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fea3:e3b0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1904 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2002 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1309425 (1.2 MiB)  T

$ awk 'sub(/inet addr:/,""){print $1}' file
192.168.1.103

$ awk -F'[ :]+' '/inet addr/{print $4}' file
192.168.1.103
  /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'
ip route get 8.8.8.8| grep src| sed 's/.*src \(.* \)/\1/g'|cut -f1 -d ' '

請注意,因為我只是花了一些時間對服務器上的拙劣升級進行故障排除。 原來,那(幾年前)我已經實施了一項測試,以查看是否存在動態添加的接口(例如 eth0:1),如果存在,我會將某些 proggis 綁定到 eth0 上的“主”IP。 基本上它是 'ifconfig|grep...|sed...' 解決方案的變體(加上檢查 'eth0:' 的存在)。
升級帶來了新的網絡工具,輸出也略有變化:

舊的 ifconfig:

eth0      Link encap:Ethernet  HWaddr 42:01:0A:F0:B0:1D
          inet addr:10.240.176.29  Bcast:10.240.176.29  Mask:255.255.255.255
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          ...<SNIP>

而新版本將顯示:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1460
      inet 10.240.212.165  netmask 255.255.255.255  broadcast 10.240.212.165
      ...<SNIP>

渲染對 'eth0:' 和 'inet addr:' 的搜索失敗(不要介意名為 'em0'、'br0' 或 'wlan0' 的接口......)。 當然,您可以檢查“inet”(或“inet6”),並使 addr: 部分可選,但仔細觀察,您會發現或多或少一切都發生了變化,“Mask”現在是“netmask”,.. .

'ip route ...' 建議非常漂亮 - 所以也許:

_MyIP="$( ip route get 8.8.8.8 | awk 'NR==1 {print $NF}' )"
if [ "A$_MyIP" == "A" ]
then
    _MyIPs="$( hostname -I )"
    for _MyIP in "$_MyIPs"
    do
        echo "Found IP: \"$_MyIP\""
    done
else
    echo "Found IP: $_MyIP"
fi

好吧,無論如何都是這樣的。 由於所有提議的解決方案似乎都有失敗的情況,請檢查可能的邊緣情況 - 沒有 eth,多個 eth 和 lo,'hostname -i' 何時會失敗,...然后決定最佳解決方案,檢查它是否有效,否則第二個最好。

干杯'n'啤酒!

在我看來,實現您所需要的最簡單、最優雅的方法是:

ip route get 8.8.8.8 | tr -s ' ' | cut -d' ' -f7

ip route get [host] - 為您提供用於訪問遠程主機的網關,例如:

8.8.8.8 via 192.168.0.1 dev enp0s3  src 192.168.0.109

tr -s ' ' - 刪除任何額外的空格,現在你有統一性,例如:

8.8.8.8 via 192.168.0.1 dev enp0s3 src 192.168.0.109

cut -d' ' -f7 - 將字符串截斷為 ' ' 空格分隔的字段,然后從中選擇字段 #7,例如:

192.168.0.109

對以前的ip route ...解決方案之一稍作修改,從而消除了對 grep 的需要:

ip route get 8.8.8.8 | sed -n 's|^.*src \(.*\)$|\1|gp'
awk '/inet addr:/{gsub(/^.{5}/,"",$2); print $2}' file
192.168.1.103

如果您只想使用 sed 來提取 IP 地址:

ifconfig eth0 2>/dev/null sed -n 's/.*[[:space:]]\([[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\.[[:digit:]][[:digit:]]*\).*/\1/p'

對以前的ip route...僅使用ipsed並正確隔離 IPv4 ZA12A3907BE8 的解決方案

ip -4 route get 1.1.1.1 | sed -n 's/^.*src \([0-9.]*\).*$/\1/p'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM