All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: Dmitri Seletski <drjoms@gmail.com>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH iproute2-next] "ip help" wrong output, exit code.
Date: Thu, 25 Jun 2026 14:34:35 -0700	[thread overview]
Message-ID: <20260625143435.6147e1d9@phoenix.local> (raw)
In-Reply-To: <65f53987-c992-41b9-9603-9e9a448e469d@gmail.com>

On Thu, 25 Jun 2026 16:54:29 +0100
Dmitri Seletski <drjoms@gmail.com> wrote:

> I am confused.
> 
> Whats the next step here?
> 
> Regards
> 
> Dmitri
> 
> On 6/22/26 18:47, Dmitri Seletski wrote:
> > Hello David,
> >
> >
> > Based on change introduced:
> >
> > Two samples of "ip help" with demonstration of exit code and standard 
> > output are below.
> >
> > This is in line with what expect.
> >
> >
> > dimkosPC~/compiled/iproute2-next #if ./ip/ip help a >>/dev/null  ; 
> > then echo help triggered  ; else echo error code triggered  ;fi  #this 
> > redirects standard output  to /dev/null, so text missing is not error,
> > but standard text
> > help triggered
> >
> > dimkosPC~/compiled/iproute2-next #if ./ip/ip help   ; then echo help 
> > triggered  ; else echo error code triggered  ;fi
> > Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
> >       ip [ -force ] -batch filename
> > where  OBJECT := { address | addrlabel | fou | help | ila | ioam | 
> > l2tp | link |
> >                   macsec | maddress | monitor | mptcp | mroute | mrule |
> >                   neighbor | neighbour | netconf | netns | nexthop | 
> > ntable |
> >                   ntbl | route | rule | sr | stats | tap | tcpmetrics |
> >                   token | tunnel | tuntap | vrf | xfrm }
> >       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
> >                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
> >                    -f[amily] { inet | inet6 | mpls | bridge | link } |
> >                    -4 | -6 | -M | -B | -0 |
> >                    -l[oops] { maximum-addr-flush-attempts } | -echo | 
> > -br[ief] |
> >                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] 
> > [filename] |
> >                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | 
> > -a[ll] |
> >                    -c[olor]}
> > help triggered
> >
> > Two samples of command that is broken on purpose.
> >
> > dimkosPC~/compiled/iproute2-next #if ./ip/ip idontexist   ; then echo 
> > help triggered  ; else echo error code triggered  ;fi
> > Object "idontexist" is unknown, try "ip help".
> > error code triggered
> >
> > dimkosPC~/compiled/iproute2-next #if ./ip/ip idontexist  >>/dev/null 
> >  ; then echo help triggered  ; else echo error code triggered  ;fi 
> >  #this redirects standard output  to /dev/null, so text missing is not 
> > error, but standard text
> > Object "idontexist" is unknown, try "ip help".
> > error code triggered
> >
> > This works as expected as per my understanding.
> >
> >
> > Not everything is fixed, but chunk of things fixed is better than non 
> > of it.
> >
> > for example:
> >
> > if ip  add help    ; then echo help triggered  ; else echo error code 
> > triggered  ;fi  #this redirects standard output  to /dev/null, so text 
> > missing is not error, but standard text
> > Usage: ip address {add|change|replace} IFADDR dev IFNAME [ LIFETIME ]
> >                                                      [ CONFFLAG-LIST ]
> >       ip address del IFADDR dev IFNAME [mngtmpaddr]
> >       ip address {save|flush} [ dev IFNAME ] [ scope SCOPE-ID ] [ to 
> > PREFIX ]
> >                            [ FLAG-LIST ] [ label LABEL ] [ { up | down 
> > } ]
> >       ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master 
> > DEVICE ]
> >                         [ nomaster ]
> >                         [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]
> >                         [ label LABEL ] [ { up | down } ] [ vrf NAME ]
> >                         [ proto ADDRPROTO ] ]
> >       ip address {showdump|restore}
> > IFADDR := PREFIX | ADDR peer PREFIX
> >          [ broadcast ADDR ] [ anycast ADDR ]
> >          [ label IFNAME ] [ scope SCOPE-ID ] [ metric METRIC ]
> >          [ proto ADDRPROTO ]
> > SCOPE-ID := [ host | link | global | NUMBER ]
> > FLAG-LIST := [ FLAG-LIST ] FLAG
> > FLAG  := [ permanent | dynamic | secondary | primary |
> >           [-]tentative | [-]deprecated | [-]dadfailed | temporary |
> >           CONFFLAG-LIST ]
> > CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG
> > CONFFLAG  := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]
> > LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]
> > LFT := forever | SECONDS
> > ADDRPROTO := [ NAME | NUMBER ]
> > TYPE := { amt | bareudp | bond | bond_slave | bridge | bridge_slave |
> >          dsa | dummy | erspan | geneve | gre | gretap | gtp | hsr |
> >          ifb | ip6erspan | ip6gre | ip6gretap | ip6tnl |
> >          ipip | ipoib | ipvlan | ipvtap |
> >          macsec | macvlan | macvtap | netdevsim |
> >          netkit | nlmon | pfcp | rmnet | sit | team | team_slave |
> >          vcan | veth | vlan | vrf | vti | vxcan | vxlan | wwan |
> >          xfrm | virt_wifi }
> > error code triggered
> >
> > This is still problematic.
> >
> >
> > But so far code leaves "ip help" command/argument in better shape than 
> > it found it in.
> >
> >
> > I may try improve things more, but lets submit what we already have 
> > "better", please.
> >
> > Kind Regards
> >
> > Dmitri Seletski
> >
> >
> > On 6/22/26 17:44, David Laight wrote:  
> >> On Mon, 22 Jun 2026 07:57:00 -0700
> >> Stephen Hemminger <stephen@networkplumber.org> wrote:
> >>  
> >>> On Sun, 21 Jun 2026 22:48:59 +0100
> >>> Dmitri Seletski <drjoms@gmail.com> wrote:
> >>>  
> >>>>  From 0805e07105cd15c5b94271a4706e50e3c65dbde5 Mon Sep 17 00:00:00 
> >>>> 2001
> >>>> From: Dmitri Seletski <drjoms@gmail.com>
> >>>> Date: Sun, 21 Jun 2026 22:12:43 +0100
> >>>> Subject: [PATCH iproute2-next]  "ip help" wrong output, exit code.
> >>>>
> >>>> Changed output of "ip help" from standard error to standard output. 
> >>>> And
> >>>> Exit is now 0 instead of -1. "ip help|grep bridge" - now gives bridge
> >>>> syntax instead of flooding user with everything from "ip help".
> >>>> ---
> >>>> ip/ip.c | 4 ++--
> >>>> 1 file changed, 2 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/ip/ip.c b/ip/ip.c
> >>>> index e4b71bde..4627b61c 100644
> >>>> --- a/ip/ip.c
> >>>> +++ b/ip/ip.c
> >>>> @@ -56,7 +56,7 @@ static void usage(void) __attribute__((noreturn));
> >>>>
> >>>> static void usage(void)
> >>>> {
> >>>> -fprintf(stderr,
> >>>> +fprintf(stdout,
> >>>> "Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
> >>>> "       ip [ -force ] -batch filename\n"
> >>>> "where  OBJECT := { address | addrlabel | fou | help | ila | ioam | 
> >>>> l2tp
> >>>> | link |\n"
> >>>> @@ -72,7 +72,7 @@ static void usage(void)
> >>>> "                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch]
> >>>> [filename] |\n"
> >>>> "                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] |
> >>>> -a[ll] |\n"
> >>>> "                    -c[olor]}\n");
> >>>> -exit(-1);
> >>>> +exit(0);
> >>>> }  
> >>> Your mailer damages white space.
> >>>  
> >> The output also needs to depend on whether these is a 'usage' error or
> >> if 'help' is requested.
> >> Code code is correct for the former - except it should do exit(1).
> >>
> >>     David
> >>
> >>  
> 

We need to have a broad solution that doesn't look ugly.
There are a couple problems with current code:
  1. Help should exit with 0 (ok); invalid argument should exit with non-zero
     by Gnu convention that is 2 but other commands like git use 129
  2. help should go to stdout; usage on error should go to stderr

The solution should work across iproute2 commands: ip, tc, dpll, tipc, bridge, ...
and the sub commands.

So far the mailing list patches were kind of messy and limited.

  reply	other threads:[~2026-06-25 21:34 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-20  9:36 "ip help" output is an error Dmitri Seletski
2026-06-21 15:21 ` Stephen Hemminger
2026-06-21 21:51   ` Dmitri Seletski
2026-06-22  7:49   ` David Laight
2026-06-22 10:39     ` Dmitri Seletski
     [not found]   ` <069b13e1-f689-410b-bd40-b5e5831b67e7@gmail.com>
2026-06-22 14:57     ` [PATCH iproute2-next] "ip help" wrong output, exit code Stephen Hemminger
2026-06-22 16:44       ` David Laight
2026-06-22 17:47         ` Dmitri Seletski
2026-06-25 15:54           ` Dmitri Seletski
2026-06-25 21:34             ` Stephen Hemminger [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-06-21 21:56 Dmitri Seletski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260625143435.6147e1d9@phoenix.local \
    --to=stephen@networkplumber.org \
    --cc=drjoms@gmail.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.