Title: Correct way to find vpn gateway using script
Tags: vpn;iproute;ifconfig
Question: I need to find ip that my vpn interface (vpn0) uses to connect so I can setup routes correctly using a script.
What is correct way to do this?
First solution I tried
❯ ip r | sed -rn &quot;s/.*dev vpn0 proto kernel scope link src ([0-9.]+) .*/\1/p&quot;
151.154.11.224
But this didn't work on both machines because ip r returns
151.154.11.224/20 dev vpn0 proto kernel scope link src 151.154.11.224 metric 50
for one one of them and
151.154.11.224/20 dev vpn0 scope link
for the another.
Two other solutions that I tried:
❯ ip a s dev vpn0 | sed -rn 's/.*inet (([0-9]+\.){3}[0-9]+).*/\1/p'
151.154.11.224
❯ ifconfig vpn0 | sed -rn &quot;s/.*destination ([0-9.]+)/\1/p&quot;
151.154.11.224
How should I do this?
edit (this is what I have currently)
get-endpoint() {
if hash jq 2&gt;/dev/null; then
ip -4 -j a | jq -r &quot;.[] | select(.ifname == \&quot;${1}\&quot;).addr_info[0].local&quot;
else
ip -4 a s dev &quot;${1}&quot; | sed -rn 's/.*inet (([0-9]+\.){3}[0-9]+).*/\1/p'


Here is another answer: If you have the GNU grep that supports PCRE you could use something like this
ip r | grep -oP ' vpn0 .* src \K[0-9.]+'
The \K separates a &quot;must match but don't show&quot; criterion with a &quot;show this match&quot; pattern.
Worked example
printf &quot;%s\n%s\n&quot; '151.154.11.224/20 dev vpn0 proto kernel scope link src 151.154.11.224 metric 50' '151.154.11.224/20 dev vpn0 scope link' |
grep -oP ' vpn0 .* src \K[0-9.]+'
151.154.11.224
Alternatively, since I'm not at all sure why you're looking at ip route to find interface addresses, use ip address and parse that
ip a |
awk -v netif='vpn0' '
$2 == netif &quot;:&quot; { this=1 }
this &amp;&amp; $1 == &quot;inet&quot; { gsub(&quot;/[[:digit:]]+&quot;, &quot;&quot;, $2); print $2; exit }
Or, as one line
ip a | awk -v netif='vpn0' '$2==netif&quot;:&quot; {this=1} this &amp;&amp; $1==&quot;inet&quot; {gsub(&quot;/[[:digit:]]+&quot;,&quot;&quot;,$2); print $2; exit}'
Yet another option is to parse the JSON that ip can provide (probably the better option for a script, assuming you have jq)
ip -j address |
jq -r '.[] | select(.ifname | contains(&quot;vpn0&quot;)) | .addr_info[0].local'
Comment for this answer: Problem isn't with parsing (`grep`,`sed`,`awk`,etc). As I said above `ip r` didn't work because second machine didn't print any `src`, only `151.154.11.224/20 dev vpn0 scope link`
Comment for this answer: I was setting routes and `ip r` did return src ip in some scenarios, so I kinda got mentally stuck on that. I combined your json option with `ip -4 a s dev vpn0` parsed with sed for now.
Comment for this answer: The second one isn't an IP address - is that your issue? It wasn't clear in your question. If you actually want IP addresses why not look at `ip address`? I'll update the answer

{'source': 'StackExchangeDataset', 'subset': 'unix.stackexchange.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2020:00:10/21/20', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<vpn><iproute><ifconfig>', 'Title': 'Correct way to find vpn gateway using script', 'ViewCount': 72, 'id': 615683, 'user_AboutMe': None, 'user_AccountId': 3210055.0, 'user_DisplayName': 'warbaque', 'user_Reputation': 131.0, 'user_Views': 1.0, 'user_id': 218153.0}}