diff --git a/AUTHORS b/AUTHORS
index 032f0ae..fcae081 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -13,3 +13,4 @@ Kenneth Endfinger
lexhuismans
Ettore Simone
luoling8192
+xraystyle
diff --git a/README.md b/README.md
index 5f0dc9f..7697eca 100644
--- a/README.md
+++ b/README.md
@@ -56,9 +56,12 @@ Goal of this utility is to provide compatible CLI with [iproute2], supporting sa
* `ip neigh help`
* `bridge help`
* `bridge link help`
- * `ss help`
+ * `ss help`
+* Options
+ * Brief output mode: `ip -br link` or `ip -br addr`
* Link module (Interfaces)
* List local interfaces `ip link`
+ * List interfaces in brief format `ip -br link`
* Show one interface `ip link show en0`
* Shutdown interface `ip link set dev en0 down`
* Start interface `ip link set dev en0 up`
@@ -78,6 +81,7 @@ Goal of this utility is to provide compatible CLI with [iproute2], supporting sa
* IPv6 (NDP) neighbours are being flushed for all interfaces
* Address module
* List all addresses `ip addr`
+ * List all addresses in brief format `ip -br addr`
* List IPv4 addresses `ip -4 addr`
* List IPv6 addresses `ip -6 addr`
* Add address to interface `ip addr add 10.0.0.5/24 dev en0`
@@ -119,6 +123,13 @@ Goal of this utility is to provide compatible CLI with [iproute2], supporting sa
* Same options work for `bridge` and `ss` commands
## Changelog
+
+ HEAD
+
+- Added `--brief` option for show commands (https://github.com/brona/iproute2mac/issues/42, PR https://github.com/brona/iproute2mac/pull/69)
+
+
+
HEAD
diff --git a/src/ip.py b/src/ip.py
index fabdf37..cd91339 100755
--- a/src/ip.py
+++ b/src/ip.py
@@ -90,7 +90,7 @@ def parse_ifconfig(res, af, address):
return links
-def link_addr_show(argv, af, json_print, pretty_json, color, address):
+def link_addr_show(argv, af, json_print, pretty_json, color, address, brief):
if len(argv) > 0 and argv[0] == "dev":
argv.pop(0)
if len(argv) > 0:
@@ -114,35 +114,62 @@ def link_addr_show(argv, af, json_print, pretty_json, color, address):
return json_dump(links, pretty_json)
for l in links:
- print("%d: %s: <%s> mtu %d status %s" % (
- l["ifindex"],
- colorize_ifname(color, l["ifname"]),
- ",".join(l["flags"]),
- l["mtu"],
- colorize_op_state(color, l["operstate"])
- ))
- print(
- " link/" + l["link_type"] +
- ((" " + colorize_mac(color, l["address"])) if "address" in l else "") +
- ((" brd " + colorize_mac(color, l["broadcast"])) if "broadcast" in l else "")
- )
- for a in l.get("addr_info", []):
+ if brief:
+ # Brief format: interface_name STATUS ip_addresses...
+ # Interface name (left-padded to align)
+ ifname_colored = colorize_ifname(color, l["ifname"])
+ ifname_padding = max(0, 16 - len(l["ifname"]))
+ line = ifname_colored + " " * ifname_padding + " "
+
+ # Status
+ status_colored = colorize_op_state(color, l["operstate"])
+ status_padding = max(0, 8 - len(l["operstate"]))
+ line += status_colored + " " * status_padding
+
+ # Add addresses
+ addrs = []
+ for a in l.get("addr_info", []):
+ addr_str = "%s/%d" % (colorize_inet(color, a["family"], a["local"]), a["prefixlen"])
+ addrs.append(addr_str)
+
+ # For link output, show MAC address
+ if not address and "address" in l:
+ addrs.insert(0, colorize_mac(color, l["address"]))
+
+ # Add minimum 7 spaces before first address, then single space between addresses
+ if addrs:
+ line += " " + " ".join(addrs)
+ print(line)
+ else:
+ print("%d: %s: <%s> mtu %d status %s" % (
+ l["ifindex"],
+ colorize_ifname(color, l["ifname"]),
+ ",".join(l["flags"]),
+ l["mtu"],
+ colorize_op_state(color, l["operstate"])
+ ))
print(
- " %s %s" % (a["family"], colorize_inet(color, a["family"], a["local"])) +
- ((" peer %s" % colorize_inet(color, a["family"], a["address"])) if "address" in a else "") +
- "/%d" % (a["prefixlen"]) +
- ((" brd " + colorize_inet(color, a["family"], a["broadcast"])) if "broadcast" in a else "")
+ " link/" + l["link_type"] +
+ ((" " + colorize_mac(color, l["address"])) if "address" in l else "") +
+ ((" brd " + colorize_mac(color, l["broadcast"])) if "broadcast" in l else "")
)
+ for a in l.get("addr_info", []):
+ print(
+ " %s %s" % (a["family"], colorize_inet(color, a["family"], a["local"])) +
+ ((" peer %s" % colorize_inet(color, a["family"], a["address"])) if "address" in a else "") +
+ "/%d" % (a["prefixlen"]) +
+ ((" brd " + colorize_inet(color, a["family"], a["broadcast"])) if "broadcast" in a else "")
+ )
return True
# Help
-def do_help(argv=None, af=None, json_print=None, pretty_json=None, color=None):
+def do_help(argv=None, af=None, json_print=None, pretty_json=None, color=None, brief=None):
perror("Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }")
perror("where OBJECT := { link | addr | route | neigh }")
perror(" OPTIONS := { -V[ersion] | -j[son] | -p[retty] | -c[olor] |")
- perror(" -4 | -6 }")
+ perror(" -br[ief] | -4 | -6 }")
perror(HELP_ADDENDUM)
exit(255)
@@ -184,7 +211,7 @@ def do_help_neigh():
# Route Module
@help_msg(do_help_route)
-def do_route(argv, af, json_print, pretty_json, color):
+def do_route(argv, af, json_print, pretty_json, color, brief):
if not argv or (
any_startswith(["show", "lst", "list"], argv[0]) and len(argv) == 1
):
@@ -409,13 +436,13 @@ def do_route_get(argv, af, json_print, pretty_json, color):
# Addr Module
@help_msg(do_help_addr)
-def do_addr(argv, af, json_print, pretty_json, color):
+def do_addr(argv, af, json_print, pretty_json, color, brief):
if not argv:
argv.append("show")
if any_startswith(["show", "lst", "list"], argv[0]):
argv.pop(0)
- return do_addr_show(argv, af, json_print, pretty_json, color)
+ return do_addr_show(argv, af, json_print, pretty_json, color, brief)
elif "add".startswith(argv[0]) and len(argv) >= 3:
argv.pop(0)
return do_addr_add(argv, af)
@@ -427,8 +454,8 @@ def do_addr(argv, af, json_print, pretty_json, color):
return True
-def do_addr_show(argv, af, json_print, pretty_json, color):
- return link_addr_show(argv, af, json_print, pretty_json, color, True)
+def do_addr_show(argv, af, json_print, pretty_json, color, brief):
+ return link_addr_show(argv, af, json_print, pretty_json, color, True, brief)
def do_addr_add(argv, af):
@@ -481,13 +508,13 @@ def do_addr_del(argv, af):
# Link module
@help_msg(do_help_link)
-def do_link(argv, af, json_print, pretty_json, color):
+def do_link(argv, af, json_print, pretty_json, color, brief):
if not argv:
argv.append("show")
if any_startswith(["show", "lst", "list"], argv[0]):
argv.pop(0)
- return do_link_show(argv, af, json_print, pretty_json, color)
+ return do_link_show(argv, af, json_print, pretty_json, color, brief)
elif "set".startswith(argv[0]):
argv.pop(0)
return do_link_set(argv, af)
@@ -496,8 +523,8 @@ def do_link(argv, af, json_print, pretty_json, color):
return True
-def do_link_show(argv, af, json_print, pretty_json, color):
- return link_addr_show(argv, af, json_print, pretty_json, color, False)
+def do_link_show(argv, af, json_print, pretty_json, color, brief):
+ return link_addr_show(argv, af, json_print, pretty_json, color, False, brief)
def do_link_set(argv, af):
@@ -550,7 +577,7 @@ def do_link_set(argv, af):
# Neigh module
@help_msg(do_help_neigh)
-def do_neigh(argv, af, json_print, pretty_json, color):
+def do_neigh(argv, af, json_print, pretty_json, color, brief):
if not argv:
argv.append("show")
@@ -694,6 +721,7 @@ def main(argv):
af = -1 # default / both
json_print = False
pretty_json = False
+ brief = False
color_mode = "never"
while argv and argv[0].startswith("-"):
@@ -706,6 +734,9 @@ def main(argv):
elif argv[0] == "-4":
af = 4
argv.pop(0)
+ elif "-brief".startswith(argv[0]):
+ brief = True
+ argv.pop(0)
elif "-color".startswith(argv[0].split("=")[0]):
# 'always' is default if -color is set without any value
color_mode = argv[0].split("=")[1] if "=" in argv[0] else "always"
@@ -738,7 +769,7 @@ def main(argv):
argv.pop(0)
# Functions return true or terminate with exit(255)
# See help_msg and do_help*
- return cmd_func(argv, af, json_print, pretty_json, color_scheme)
+ return cmd_func(argv, af, json_print, pretty_json, color_scheme, brief)
perror('Object "{}" is unknown, try "ip help".'.format(argv[0]))
exit(1)
diff --git a/test/commands.sh b/test/commands.sh
index 5e6e897..296a5bc 100755
--- a/test/commands.sh
+++ b/test/commands.sh
@@ -144,6 +144,32 @@ $ip_cmd a s
! $ip_cmd addr asdf
+## brief format tests
+
+# Test basic -br addr show
+$ip_cmd -br addr show | grep -E "^lo[0-9]* +[A-Z]+ +"
+
+# Test -br a shorthand
+$ip_cmd -br a | grep -E "^lo[0-9]* +[A-Z]+ +"
+
+# Test -br with specific device
+$ip_cmd -br addr show dev lo0 | grep -E "^lo0 +[A-Z]+ +"
+
+# Test -br with -4 (IPv4 only)
+$ip_cmd -4 -br addr show | grep -E "^lo[0-9]* +[A-Z]+ +" | grep "127.0.0.1"
+
+# Test -br with -6 (IPv6 only)
+$ip_cmd -6 -br addr show | grep -E "^lo[0-9]* +[A-Z]+ +" | grep "::1"
+
+# Test -br with -j (JSON output should override brief)
+$ip_cmd -br -j addr show | perl -MJSON -e 'decode_json()'
+
+# Test order: -br before command
+$ip_cmd -br addr show | grep -E "^lo[0-9]* +[A-Z]+ +"
+
+# Test order: -br after command (should also work)
+$ip_cmd addr -br show | grep -E "^lo[0-9]* +[A-Z]+ +"
+
# link
@@ -169,6 +195,20 @@ $ip_cmd l s | grep mtu
! $ip_cmd link asdf
+## link brief format tests
+
+# Test basic -br link show
+$ip_cmd -br link show | grep -E "^lo[0-9]* +[A-Z]+ +"
+
+# Test -br l shorthand
+$ip_cmd -br l | grep -E "^lo[0-9]* +[A-Z]+ +"
+
+# Test -br with specific device
+$ip_cmd -br link show lo0 | grep -E "^lo0 +[A-Z]+ +"
+
+# Test -br with -j (JSON output should override brief)
+$ip_cmd -br -j link show | perl -MJSON -e 'decode_json()'
+
# neigh
$ip_cmd nei help 2>&1 >/dev/null | grep "Usage: ip neighbour"