• About the exit status of the `if' command.

    From hongyi.zhao@gmail.com@21:1/5 to All on Fri Jan 21 04:13:39 2022
    See the following testing:

    $ ( if [ 1 -eq 2 ]; then echo ok; fi ); echo $?
    0

    $ [ 1 -eq 2 ]; echo $?
    1

    $ help if
    [...]
    Exit Status:
    Returns the status of the last command executed.


    So, I think in the first test, the exit status should be the "[ 1 -eq 2 ]", but as you can see, this is not the case. Where is my understanding wrong?

    Regards,
    HZ

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to hongy...@gmail.com on Fri Jan 21 13:25:21 2022
    On 21.01.2022 13:13, hongy...@gmail.com wrote:
    See the following testing:

    $ ( if [ 1 -eq 2 ]; then echo ok; fi ); echo $? 0

    $ [ 1 -eq 2 ]; echo $? 1

    $ help if [...] Exit Status: Returns the status of the last command
    executed.


    So, I think in the first test, the exit status should be the "[ 1 -eq
    2 ]", but as you can see, this is not the case. Where is my
    understanding wrong?

    You missed that no command has been executed. The 'if' compound
    command would have executed the else case, but there isn't one.
    Thus 0 is returned.

    Janis


    Regards, HZ


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hongyi.zhao@gmail.com@21:1/5 to Janis Papanagnou on Fri Jan 21 04:59:50 2022
    On Friday, January 21, 2022 at 8:25:26 PM UTC+8, Janis Papanagnou wrote:
    On 21.01.2022 13:13, hongy...@gmail.com wrote:
    See the following testing:

    $ ( if [ 1 -eq 2 ]; then echo ok; fi ); echo $? 0

    $ [ 1 -eq 2 ]; echo $? 1

    $ help if [...] Exit Status: Returns the status of the last command executed.


    So, I think in the first test, the exit status should be the "[ 1 -eq
    2 ]", but as you can see, this is not the case. Where is my
    understanding wrong?
    You missed that no command has been executed. The 'if' compound
    command would have executed the else case, but there isn't one.
    Thus 0 is returned.

    Based on your above comments, I further noted the following description in help:

    The exit status of the entire construct is the exit status of the last
    command executed, or zero if no condition tested true.

    So, I obtained the following explanation: Given that the only condition "[ 1 -eq 2 ]" is false, we can say "no condition tested true" and therefore return zero.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to hongy...@gmail.com on Fri Jan 21 14:13:09 2022
    On 21.01.2022 13:59, hongy...@gmail.com wrote:
    On Friday, January 21, 2022 at 8:25:26 PM UTC+8, Janis Papanagnou wrote:
    On 21.01.2022 13:13, hongy...@gmail.com wrote:
    See the following testing:

    $ ( if [ 1 -eq 2 ]; then echo ok; fi ); echo $? 0

    $ [ 1 -eq 2 ]; echo $? 1

    $ help if [...] Exit Status: Returns the status of the last command
    executed.


    So, I think in the first test, the exit status should be the "[ 1 -eq
    2 ]", but as you can see, this is not the case. Where is my
    understanding wrong?
    You missed that no command has been executed. The 'if' compound
    command would have executed the else case, but there isn't one.
    Thus 0 is returned.

    Based on your above comments, I further noted the following description in help:

    The exit status of the entire construct is the exit status of the last
    command executed, or zero if no condition tested true.

    So, I obtained the following explanation: Given that the only
    condition "[ 1 -eq 2 ]" is false, we can say "no condition tested true"
    and therefore return zero.

    I'm not sure why you formulate it that way. In case of

    $ if [ 1 -eq 2 ]; then echo ok; else false ; fi ); echo $?
    1

    there's also "no condition tested true" and you don't get exit code 0.
    The point is another one. It's probably the best to simply look up the
    POSIX specs where it's clearly described:

    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed."

    It's clear, simple, and leaves no doubts, I hope.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hongyi.zhao@gmail.com@21:1/5 to Janis Papanagnou on Fri Jan 21 06:15:03 2022
    On Friday, January 21, 2022 at 9:13:15 PM UTC+8, Janis Papanagnou wrote:
    On 21.01.2022 13:59, hongy...@gmail.com wrote:
    On Friday, January 21, 2022 at 8:25:26 PM UTC+8, Janis Papanagnou wrote:
    On 21.01.2022 13:13, hongy...@gmail.com wrote:
    See the following testing:

    $ ( if [ 1 -eq 2 ]; then echo ok; fi ); echo $? 0

    $ [ 1 -eq 2 ]; echo $? 1

    $ help if [...] Exit Status: Returns the status of the last command
    executed.


    So, I think in the first test, the exit status should be the "[ 1 -eq
    2 ]", but as you can see, this is not the case. Where is my
    understanding wrong?
    You missed that no command has been executed. The 'if' compound
    command would have executed the else case, but there isn't one.
    Thus 0 is returned.

    Based on your above comments, I further noted the following description in help:

    The exit status of the entire construct is the exit status of the last command executed, or zero if no condition tested true.

    So, I obtained the following explanation: Given that the only
    condition "[ 1 -eq 2 ]" is false, we can say "no condition tested true"
    and therefore return zero.
    I'm not sure why you formulate it that way. In case of

    $ if [ 1 -eq 2 ]; then echo ok; else false ; fi ); echo $?
    1

    This is equivalent to:

    $ ( if [ 1 -eq 2 ]; then echo ok; else exit 1 ; fi ); echo $?
    1

    there's also "no condition tested true" and you don't get exit code 0.
    The point is another one. It's probably the best to simply look up the
    POSIX specs where it's clearly described:

    BTW, what's the URL where you find the following explanation?

    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed."

    So, if I want to obtain a valid exit status, it must be explicitly set by the then or else compound-list.

    It's clear, simple, and leaves no doubts, I hope.

    Got it. Thank you again.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to hongy...@gmail.com on Fri Jan 21 14:46:06 2022
    In article <8834cc9c-bdca-4cf0-96cd-68818323b9bcn@googlegroups.com>, hongy...@gmail.com <hongyi.zhao@gmail.com> wrote:
    ...
    BTW, what's the URL where you find the following explanation?

    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed."

    Do "man bash", then search for: if
    (that's literally 5 spaces then i then f)

    And you'll get the 411.

    BTW, the above text does not appear literally in my "man bash" as written;
    I'm guessing that Janis got it from some other source. But the general
    content is the same.

    --
    1) The only professionals who refer to their customers as "users" are
    computer guys and drug dealers.
    2) The only professionals who refer to their customers as "clients" are
    lawyers and prostitutes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Kenny McCormack on Fri Jan 21 16:36:42 2022
    On 21.01.2022 15:46, Kenny McCormack wrote:
    In article <8834cc9c-bdca-4cf0-96cd-68818323b9bcn@googlegroups.com>, hongy...@gmail.com <hongyi.zhao@gmail.com> wrote:
    ...
    BTW, what's the URL where you find the following explanation?

    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed."

    Do "man bash", then search for: if
    (that's literally 5 spaces then i then f)

    And you'll get the 411.

    BTW, the above text does not appear literally in my "man bash" as written; I'm guessing that Janis got it from some other source.

    My text was from the POSIX specs. (I've said that in my post but you
    may have missed it.)

    For basic standard stuff the POSIX specs are often better. The man
    pages may differ (even for basic standard stuff) between shells.

    But the general content is the same.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to hongy...@gmail.com on Fri Jan 21 16:26:33 2022
    On 21.01.2022 15:15, hongy...@gmail.com wrote:
    On Friday, January 21, 2022 at 9:13:15 PM UTC+8, Janis Papanagnou wrote:

    there's also "no condition tested true" and you don't get exit code 0.
    The point is another one. It's probably the best to simply look up the
    POSIX specs where it's clearly described:

    BTW, what's the URL where you find the following explanation?

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04


    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed."

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to janis_papanagnou@hotmail.com on Fri Jan 21 16:22:48 2022
    In article <ssejua$jno$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    For basic standard stuff the POSIX specs are often better. The man
    pages may differ (even for basic standard stuff) between shells.

    I would argue that the man page for one's specific shell is a better
    reference than the abstract POSIX specs. The POSIX specs tell you what *should* happen, while the man page will tell what *WILL* happen. The
    later is, in the real world, of much greater importance.

    Particularly for someone as literal-minded and "I just want it to work"
    focused as this OP.

    P.S. Incidentally, the text you supplied (from the POSIX specs) does appear
    in "man bash" word-for-word (or very close to it). It is just formatted differently. I mention this only for the benefit of OP, because, as I've said this OP is very literal-minded.

    --
    Those on the right constantly remind us that America is not a
    democracy; now they claim that Obama is a threat to democracy.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Kenny McCormack on Fri Jan 21 18:09:44 2022
    On 21.01.2022 17:22, Kenny McCormack wrote:
    In article <ssejua$jno$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    For basic standard stuff the POSIX specs are often better. The man
    pages may differ (even for basic standard stuff) between shells.

    I would argue that the man page for one's specific shell is a better reference than the abstract POSIX specs. [...]

    I basically agree with the first part. Though if the question is so
    basic as the OP's one, concerning operational 'if'-semantics, then
    I think POSIX might be better as the relevant reference. If, as you
    say, these basics seem to be borrowed by the shells' man pages from
    POSIX, yet the better. (It would be worse if shell's man pages would
    in a subtle way deviate - like in the OP's quoted wording - and that
    this deviation then spreads uncertainty and doubt.)
    With the second part I wouldn't say that they, the POSIX specs, are
    abstract. But YMMV, of course.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to All on Fri Jan 21 18:20:19 2022
    On 21.01.2022 15:15, hongy...@gmail.com wrote:

    BTW, what's the URL [...]

    Here are a couple links that you may want to inspect to get your
    first qualified answers before you post.

    For shell you may want to inspect

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html

    where you also find a link to the shell language, accessible though

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18

    And the entries to the standard Unix tools you find here

    https://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html

    and for the often used and referenced standard awk see this page

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html

    Hope that helps.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hongyi.zhao@gmail.com@21:1/5 to Janis Papanagnou on Fri Jan 21 16:48:02 2022
    On Saturday, January 22, 2022 at 1:20:24 AM UTC+8, Janis Papanagnou wrote:
    On 21.01.2022 15:15, hongy...@gmail.com wrote:

    BTW, what's the URL [...]

    Here are a couple links that you may want to inspect to get your
    first qualified answers before you post.

    For shell you may want to inspect

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html

    where you also find a link to the shell language, accessible though

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18

    And the entries to the standard Unix tools you find here

    https://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html

    and for the often used and referenced standard awk see this page

    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html

    Thank you for providing these links. Though the documentation and specs published by opengroup is famous and widely referred, its official stuff is not free and doesn't supply a friendly search interface for its massive knowledge base.

    HZ

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hongyi.zhao@gmail.com@21:1/5 to Kenny McCormack on Fri Jan 21 16:49:24 2022
    On Friday, January 21, 2022 at 10:46:11 PM UTC+8, Kenny McCormack wrote:
    In article <8834cc9c-bdca-4cf0...@googlegroups.com>,
    hongy...@gmail.com <hongy...@gmail.com> wrote:
    ...
    BTW, what's the URL where you find the following explanation?

    "Exit Status
    The exit status of the if command shall be the exit status of the then
    or else compound-list that was executed, or zero, if none was executed." Do "man bash", then search for: if
    (that's literally 5 spaces then i then f)

    I can only see the following description:

    $ man bash | grep -A7 ' if list'
    if list; then list; [ elif list; then list; ] ... [ else list; ] fi
    The if list is executed. If its exit status is zero, the then
    list is executed. Otherwise, each elif list is executed in
    turn, and if its exit status is zero, the corresponding then
    list is executed and the command completes. Otherwise, the
    else list is executed, if present. The exit status is the exit
    status of the last command executed, or zero if no condition
    tested true.


    And you'll get the 411.

    What do you mean by saying 411 here?

    BTW, the above text does not appear literally in my "man bash" as written; I'm guessing that Janis got it from some other source. But the general content is the same.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Waitzmann@21:1/5 to All on Sat Jan 22 18:48:33 2022
    "hongy...@gmail.com" <hongyi.zhao@gmail.com>:
    On Friday, January 21, 2022 at 9:13:15 PM UTC+8, Janis Papanagnou
    wrote:
    On 21.01.2022 13:59, hongy...@gmail.com wrote:

    On Friday, January 21, 2022 at 8:25:26 PM UTC+8, Janis
    Papanagnou wrote:

    You missed that no command has been executed. The 'if' compound
    command would have executed the else case, but there isn't one.
    Thus 0 is returned.

    Based on your above comments, I further noted the following
    description in help:

    The exit status of the entire construct is the exit status of
    the last command executed, or zero if no condition tested true.

    So, I obtained the following explanation: Given that the only
    condition "[ 1 -eq 2 ]" is false, we can say "no condition
    tested true" and therefore return zero.
    I'm not sure why you formulate it that way. In case of


    $ if [ 1 -eq 2 ]; then echo ok; else false ; fi ); echo $?
    1

    This is equivalent to:

    By coincidence, yes.

    $ ( if [ 1 -eq 2 ]; then echo ok; else exit 1 ; fi ); echo $?
    1

    If, for example, you remove the parentheses, you'll get different
    semantics.


    there's also "no condition tested true" and you don't get exit
    code 0. The point is another one. It's probably the best to
    simply look up the POSIX specs where it's clearly described:

    "Exit Status
    The exit status of the if command shall be the exit status of the
    then or else compound-list that was executed, or zero, if none
    was executed."

    So, if I want to obtain a valid exit status, it must be explicitly
    set by the then or else compound-list.

    Not exactly.  It suffices to have the exit status implicitly be set
    by the then or else compound‐list:  Every shell command (other than
    the comment (#)) has got an exit status.  So there is no way not to
    set an exit status.  It's the programmer's responsibility to have
    the shell execute the right commands, though.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hongyi.zhao@gmail.com@21:1/5 to Helmut Waitzmann on Sat Jan 22 17:41:29 2022
    On Sunday, January 23, 2022 at 8:25:32 AM UTC+8, Helmut Waitzmann wrote:
    "hongy...@gmail.com" <hongy...@gmail.com>:
    $ if [ 1 -eq 2 ]; then echo ok; else false ; fi ); echo $?
    1

    This is equivalent to:

    By coincidence, yes.
    $ ( if [ 1 -eq 2 ]; then echo ok; else exit 1 ; fi ); echo $?
    1
    If, for example, you remove the parentheses, you'll get different
    semantics.

    Aha, yep.


    there's also "no condition tested true" and you don't get exit
    code 0. The point is another one. It's probably the best to
    simply look up the POSIX specs where it's clearly described:

    "Exit Status
    The exit status of the if command shall be the exit status of the
    then or else compound-list that was executed, or zero, if none
    was executed."

    So, if I want to obtain a valid exit status, it must be explicitly
    set by the then or else compound-list.
    Not exactly. It suffices to have the exit status implicitly be set
    by the then or else compound‐list: Every shell command (other than
    the comment (#)) has got an exit status. So there is no way not to
    set an exit status. It's the programmer's responsibility to have
    the shell execute the right commands, though.

    Thank you for the correction and elaboration on this conclusion.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From William Ahern@21:1/5 to Kenny McCormack on Thu Jan 27 17:19:23 2022
    Kenny McCormack <gazelle@shell.xmission.com> wrote:
    In article <ssejua$jno$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou@hotmail.com> wrote:
    ...
    For basic standard stuff the POSIX specs are often better. The man
    pages may differ (even for basic standard stuff) between shells.

    I would argue that the man page for one's specific shell is a better reference than the abstract POSIX specs. The POSIX specs tell you what *should* happen, while the man page will tell what *WILL* happen. The
    later is, in the real world, of much greater importance.

    Bash has exceptionally strong POSIX compliance, particularly when it comes
    to basic shell semantics. But the Bash manual page is rather difficult to navigate, partly because so much is dedicated to all the various extension features, and partly because there's no singular section that concisely
    details the most basic semantics of the shell. Bash's info documentation
    isn't much better--it literally has a section, "Shell Syntax", but it isn't particularly helpful as most of the substance is described by reference to other sections.

    The POSIX specification is much more clear, IMHO, particularly with regard
    to basic shell semantics. POSIX 1003.1-2017 volume 3, chapter 2, "Shell
    Command Language", is the most concise *and* comprehensive description I've
    yet seen of the Unix shell. This is especially true if you ignore the entire second half (by length) of chapter 2, which is section 14, "Special Built-In Utilities". Attentively spending 20-30 minutes reading sections 1-13, top to bottom, can provide more substance and context than the vast majority of
    people ever learn through experience and poking around vendor manual pages.
    And after doing it once, whenever you're unsure about a behavior, you'll
    know *exactly* where to navigate, as opposed to grep'ing through the manual page, never being sure about unknown caveats and relationships described in sections far removed.

    I like the frame-based version of the spec at https://pubs.opengroup.org/onlinepubs/9699919799. To navigate to the "Shell Command Language" chapter, just click through "Shell & Utilities" in the top-right, then "Shell Command Language" in the bottom-right. This presents
    a navigation pane for chapter 2 in the bottom-right. For first timers with
    30 minutes of free time, just click through "Shell Introduction" and begin reading the main content frame. You can also download the frame-based
    version locally, permitting you to literally grep the spec if necessary. I rarely have such a need given the stellar organization, at least of the
    shell in particular.

    I have an untold number of specifications locally and bookmarked, and the
    POSIX spec is by far one of the best organized resources. The only
    comparable specifications that come to mind are the ISO C reference and WHATWG's "living" HTML standard. Contrast C++, which isn't much useful
    except for grep'ing. (Both C++ and HTML specs are styled as a literal description of the functional steps a compiler takes, but WHATWG's execution
    is far superior.) Or languages like Rust and Go, which don't even have a
    proper specifications--when people rave about the documentation, they're describing various tutorials and high-level references materials, which
    while nice and aren't comparable--they lack the detail needed by programmers doing anything non-trivial. You know this is so when the "documentation"
    tends to more often change to fit surprising behavior, rather than the other way around; and when people already familiar with the "documentation" still spend an inordinate amount of time Google'ing for answers rather than first going straight to the [supposedly] primary source. For Rust and Go, I more often find myself reaching to papers and proposals describing behaviors of interest. AFAIU, this is typical of Python as well--you have to discover and read the PEP, which being an isolated document whose details can easily, accidentally be superceded, is less than ideal.

    Particularly for someone as literal-minded and "I just want it to work" focused as this OP.

    Maybe this is just me, but when "I just want it to work", one of the most important considerations is developing a strong degree of confidence that I don't need to worry about non-obvious caveats and exceptions; that is, that it'll *actually* work. And the only way to get that--when you can get
    that--is via a concise, well structured specification that makes discovering potential caveats easy. This also requires a relatively stable object of the specification, but fortunately the Unix shell has been relatively quite
    stable in both its agreed-upon semantics and common implementations for
    decades now.

    Pendants can rattle off exceptions (see https://austingroupbugs.net/view_all_bug_page.php), but they're irrelevant
    and no worse than anything else comparable. Even the JSON spec and its implementations, as simple as they should be, are plagued by such issues.

    P.S. Incidentally, the text you supplied (from the POSIX specs) does appear in "man bash" word-for-word (or very close to it). It is just formatted differently. I mention this only for the benefit of OP, because, as I've said
    this OP is very literal-minded.

    That doesn't say much if you already know what you're looking for. The point
    is discovering this stuff when you *don't* know what you're looking for.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axel Reichert@21:1/5 to William Ahern on Sat Jan 29 09:51:24 2022
    William Ahern <william@25thandClement.com> writes:

    But the Bash manual page is rather difficult to navigate, partly
    because so much is dedicated to all the various extension features,
    and partly because there's no singular section that concisely details
    the most basic semantics of the shell.

    [...]

    The POSIX specification is much more clear, IMHO, particularly with
    regard to basic shell semantics. POSIX 1003.1-2017 volume 3, chapter
    2, "Shell Command Language", is the most concise *and* comprehensive description I've yet seen of the Unix shell.

    [...]

    Attentively spending 20-30 minutes reading sections 1-13, top to
    bottom, can provide more substance and context than the vast majority
    of people ever learn through experience and poking around vendor
    manual pages. And after doing it once, whenever you're unsure about a behavior, you'll know *exactly* where to navigate, as opposed to
    grep'ing through the manual page, never being sure about unknown
    caveats and relationships described in sections far removed.

    [...]

    people already familiar with the "documentation" still spend an
    inordinate amount of time Google'ing for answers rather than first
    going straight to the [supposedly] primary source.

    What a great piece of advocacy for "Read the source, Luke"! (With
    "source" meaning not the code, but the reference documentation)

    When Joerg Schily was still alive and kicking here, I learned for the
    first time (in a warmed/heated discussion) that such stuff was available. Before that, I grep'ed around in man pages, like you so aptly describe.

    Thanks for this post!

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)