return value from eval

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite












The bash manual states:



eval [arg ...]

The args are read and concatenated together into a single com-
mand. This command is then read and executed by the shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.


I try



eval `nonsense`
echo $?


The result is 0.



Whereas when I execute the back-quoted command separately:



`nonsense`
echo $?


The result is 127.



From what is written in the bash manual I would expect eval to return 127 when taking the back-quoted nonsense as argument.



How to obtain the exit status of the argument of eval?







share|improve this question


















  • 2




    `nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
    – Ignacio Vazquez-Abrams
    Jan 4 at 10:19







  • 4




    You should run eval nonsense, then you will get 127.
    – Weijun Zhou
    Jan 4 at 10:24










  • @WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
    – Viesturs
    Jan 4 at 10:38











  • OK, I upvoted it because it has provided some insight to the problem.
    – Weijun Zhou
    Jan 4 at 14:49














up vote
4
down vote

favorite












The bash manual states:



eval [arg ...]

The args are read and concatenated together into a single com-
mand. This command is then read and executed by the shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.


I try



eval `nonsense`
echo $?


The result is 0.



Whereas when I execute the back-quoted command separately:



`nonsense`
echo $?


The result is 127.



From what is written in the bash manual I would expect eval to return 127 when taking the back-quoted nonsense as argument.



How to obtain the exit status of the argument of eval?







share|improve this question


















  • 2




    `nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
    – Ignacio Vazquez-Abrams
    Jan 4 at 10:19







  • 4




    You should run eval nonsense, then you will get 127.
    – Weijun Zhou
    Jan 4 at 10:24










  • @WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
    – Viesturs
    Jan 4 at 10:38











  • OK, I upvoted it because it has provided some insight to the problem.
    – Weijun Zhou
    Jan 4 at 14:49












up vote
4
down vote

favorite









up vote
4
down vote

favorite











The bash manual states:



eval [arg ...]

The args are read and concatenated together into a single com-
mand. This command is then read and executed by the shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.


I try



eval `nonsense`
echo $?


The result is 0.



Whereas when I execute the back-quoted command separately:



`nonsense`
echo $?


The result is 127.



From what is written in the bash manual I would expect eval to return 127 when taking the back-quoted nonsense as argument.



How to obtain the exit status of the argument of eval?







share|improve this question














The bash manual states:



eval [arg ...]

The args are read and concatenated together into a single com-
mand. This command is then read and executed by the shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.


I try



eval `nonsense`
echo $?


The result is 0.



Whereas when I execute the back-quoted command separately:



`nonsense`
echo $?


The result is 127.



From what is written in the bash manual I would expect eval to return 127 when taking the back-quoted nonsense as argument.



How to obtain the exit status of the argument of eval?









share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 17:15









Community♦

1




1










asked Jan 4 at 10:15









Viesturs

224138




224138







  • 2




    `nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
    – Ignacio Vazquez-Abrams
    Jan 4 at 10:19







  • 4




    You should run eval nonsense, then you will get 127.
    – Weijun Zhou
    Jan 4 at 10:24










  • @WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
    – Viesturs
    Jan 4 at 10:38











  • OK, I upvoted it because it has provided some insight to the problem.
    – Weijun Zhou
    Jan 4 at 14:49












  • 2




    `nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
    – Ignacio Vazquez-Abrams
    Jan 4 at 10:19







  • 4




    You should run eval nonsense, then you will get 127.
    – Weijun Zhou
    Jan 4 at 10:24










  • @WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
    – Viesturs
    Jan 4 at 10:38











  • OK, I upvoted it because it has provided some insight to the problem.
    – Weijun Zhou
    Jan 4 at 14:49







2




2




`nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
– Ignacio Vazquez-Abrams
Jan 4 at 10:19





`nonsense` doesn't return anything if nonsense doesn't exist, so there are no arguments to eval.
– Ignacio Vazquez-Abrams
Jan 4 at 10:19





4




4




You should run eval nonsense, then you will get 127.
– Weijun Zhou
Jan 4 at 10:24




You should run eval nonsense, then you will get 127.
– Weijun Zhou
Jan 4 at 10:24












@WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
– Viesturs
Jan 4 at 10:38





@WeijunZhou, for the specific case at hand nonsense comes in back-quotes,
– Viesturs
Jan 4 at 10:38













OK, I upvoted it because it has provided some insight to the problem.
– Weijun Zhou
Jan 4 at 14:49




OK, I upvoted it because it has provided some insight to the problem.
– Weijun Zhou
Jan 4 at 14:49










2 Answers
2






active

oldest

votes

















up vote
5
down vote



accepted










When you do the following -



`nonsense`
echo $?


You basically are asking "Tell me the exit status when I try to get the output of the command nonsense"
the answer to that is "command not found" or 127



But when you do the following



eval `nonsense`
echo $?


You are asking "tell me the exit status of eval when I evaluate an empty string" (the output of command nonsense) which is equal to running eval without arguments.



eval has no problems in running without arguments and its exit status becomes 0






share|improve this answer


















  • 5




    Code formatting should not be used for English prose.
    – Charles Duffy
    Jan 4 at 17:40










  • @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
    – amisax
    Jan 8 at 8:38

















up vote
9
down vote













Actually, it's more the:



$ `nonsense`
bash: nonsense: command not found
$ echo "$?"
127


That is surprising here.



We're asking bash to run the command that results of the split+glob operator on the stdout of nonsense. Since nonsense produces no output, it runs no command, so you may think the exit status should be 0.



But actually, when a simple command line has no argument, only assignment or redirection, the exit status is that of the last command substitution in assignment and normal words (not in redirection targets) that was run (though failure in redirections will also affect the exit status).



That's specially useful with assignments.



In:



output=$(grep pattern file)
status=$?


You can get both the output and exit status of grep, which you couldn't do if $? was otherwise the exit status of that non-command.



In:



output=$(cmd1) cmd2


That is where there are both assignment words and argument words, the exit status of cmd1 is ignored. $? will contain the exit status of cmd2.



And, also $output will only be set for cmd2 only. Exception to that is when cmd2 is a special builtin.



eval is such a special builtin.



$ a=0; a=1 eval; echo "$a"
1


In bash and most modern POSIX shells.



a=`exit 5` eval; echo "$?"


or



eval `exit 5`; echo "$?"


Would output 0, as it's the result of running eval with no argument. But that was not the case in the Bourne shell or ksh88, where for special builtins you'd get the exit status of exit 5 there.



In those shells, you'll also find:



$ a=`exit 3` set x; echo "$?"
3


As set is another special builtin.



. is another special builtin. In the Bourne shell and ksh88:



$ . /some/file `exit 4`; echo "$?"
4


(as long as /some/file doesn't run any command)






share|improve this answer




















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f414740%2freturn-value-from-eval%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    5
    down vote



    accepted










    When you do the following -



    `nonsense`
    echo $?


    You basically are asking "Tell me the exit status when I try to get the output of the command nonsense"
    the answer to that is "command not found" or 127



    But when you do the following



    eval `nonsense`
    echo $?


    You are asking "tell me the exit status of eval when I evaluate an empty string" (the output of command nonsense) which is equal to running eval without arguments.



    eval has no problems in running without arguments and its exit status becomes 0






    share|improve this answer


















    • 5




      Code formatting should not be used for English prose.
      – Charles Duffy
      Jan 4 at 17:40










    • @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
      – amisax
      Jan 8 at 8:38














    up vote
    5
    down vote



    accepted










    When you do the following -



    `nonsense`
    echo $?


    You basically are asking "Tell me the exit status when I try to get the output of the command nonsense"
    the answer to that is "command not found" or 127



    But when you do the following



    eval `nonsense`
    echo $?


    You are asking "tell me the exit status of eval when I evaluate an empty string" (the output of command nonsense) which is equal to running eval without arguments.



    eval has no problems in running without arguments and its exit status becomes 0






    share|improve this answer


















    • 5




      Code formatting should not be used for English prose.
      – Charles Duffy
      Jan 4 at 17:40










    • @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
      – amisax
      Jan 8 at 8:38












    up vote
    5
    down vote



    accepted







    up vote
    5
    down vote



    accepted






    When you do the following -



    `nonsense`
    echo $?


    You basically are asking "Tell me the exit status when I try to get the output of the command nonsense"
    the answer to that is "command not found" or 127



    But when you do the following



    eval `nonsense`
    echo $?


    You are asking "tell me the exit status of eval when I evaluate an empty string" (the output of command nonsense) which is equal to running eval without arguments.



    eval has no problems in running without arguments and its exit status becomes 0






    share|improve this answer














    When you do the following -



    `nonsense`
    echo $?


    You basically are asking "Tell me the exit status when I try to get the output of the command nonsense"
    the answer to that is "command not found" or 127



    But when you do the following



    eval `nonsense`
    echo $?


    You are asking "tell me the exit status of eval when I evaluate an empty string" (the output of command nonsense) which is equal to running eval without arguments.



    eval has no problems in running without arguments and its exit status becomes 0







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 8 at 8:38

























    answered Jan 4 at 10:40









    amisax

    1,363314




    1,363314







    • 5




      Code formatting should not be used for English prose.
      – Charles Duffy
      Jan 4 at 17:40










    • @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
      – amisax
      Jan 8 at 8:38












    • 5




      Code formatting should not be used for English prose.
      – Charles Duffy
      Jan 4 at 17:40










    • @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
      – amisax
      Jan 8 at 8:38







    5




    5




    Code formatting should not be used for English prose.
    – Charles Duffy
    Jan 4 at 17:40




    Code formatting should not be used for English prose.
    – Charles Duffy
    Jan 4 at 17:40












    @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
    – amisax
    Jan 8 at 8:38




    @CharlesDuffy .. thanks for the edit tip, made the changes accordingly
    – amisax
    Jan 8 at 8:38












    up vote
    9
    down vote













    Actually, it's more the:



    $ `nonsense`
    bash: nonsense: command not found
    $ echo "$?"
    127


    That is surprising here.



    We're asking bash to run the command that results of the split+glob operator on the stdout of nonsense. Since nonsense produces no output, it runs no command, so you may think the exit status should be 0.



    But actually, when a simple command line has no argument, only assignment or redirection, the exit status is that of the last command substitution in assignment and normal words (not in redirection targets) that was run (though failure in redirections will also affect the exit status).



    That's specially useful with assignments.



    In:



    output=$(grep pattern file)
    status=$?


    You can get both the output and exit status of grep, which you couldn't do if $? was otherwise the exit status of that non-command.



    In:



    output=$(cmd1) cmd2


    That is where there are both assignment words and argument words, the exit status of cmd1 is ignored. $? will contain the exit status of cmd2.



    And, also $output will only be set for cmd2 only. Exception to that is when cmd2 is a special builtin.



    eval is such a special builtin.



    $ a=0; a=1 eval; echo "$a"
    1


    In bash and most modern POSIX shells.



    a=`exit 5` eval; echo "$?"


    or



    eval `exit 5`; echo "$?"


    Would output 0, as it's the result of running eval with no argument. But that was not the case in the Bourne shell or ksh88, where for special builtins you'd get the exit status of exit 5 there.



    In those shells, you'll also find:



    $ a=`exit 3` set x; echo "$?"
    3


    As set is another special builtin.



    . is another special builtin. In the Bourne shell and ksh88:



    $ . /some/file `exit 4`; echo "$?"
    4


    (as long as /some/file doesn't run any command)






    share|improve this answer
























      up vote
      9
      down vote













      Actually, it's more the:



      $ `nonsense`
      bash: nonsense: command not found
      $ echo "$?"
      127


      That is surprising here.



      We're asking bash to run the command that results of the split+glob operator on the stdout of nonsense. Since nonsense produces no output, it runs no command, so you may think the exit status should be 0.



      But actually, when a simple command line has no argument, only assignment or redirection, the exit status is that of the last command substitution in assignment and normal words (not in redirection targets) that was run (though failure in redirections will also affect the exit status).



      That's specially useful with assignments.



      In:



      output=$(grep pattern file)
      status=$?


      You can get both the output and exit status of grep, which you couldn't do if $? was otherwise the exit status of that non-command.



      In:



      output=$(cmd1) cmd2


      That is where there are both assignment words and argument words, the exit status of cmd1 is ignored. $? will contain the exit status of cmd2.



      And, also $output will only be set for cmd2 only. Exception to that is when cmd2 is a special builtin.



      eval is such a special builtin.



      $ a=0; a=1 eval; echo "$a"
      1


      In bash and most modern POSIX shells.



      a=`exit 5` eval; echo "$?"


      or



      eval `exit 5`; echo "$?"


      Would output 0, as it's the result of running eval with no argument. But that was not the case in the Bourne shell or ksh88, where for special builtins you'd get the exit status of exit 5 there.



      In those shells, you'll also find:



      $ a=`exit 3` set x; echo "$?"
      3


      As set is another special builtin.



      . is another special builtin. In the Bourne shell and ksh88:



      $ . /some/file `exit 4`; echo "$?"
      4


      (as long as /some/file doesn't run any command)






      share|improve this answer






















        up vote
        9
        down vote










        up vote
        9
        down vote









        Actually, it's more the:



        $ `nonsense`
        bash: nonsense: command not found
        $ echo "$?"
        127


        That is surprising here.



        We're asking bash to run the command that results of the split+glob operator on the stdout of nonsense. Since nonsense produces no output, it runs no command, so you may think the exit status should be 0.



        But actually, when a simple command line has no argument, only assignment or redirection, the exit status is that of the last command substitution in assignment and normal words (not in redirection targets) that was run (though failure in redirections will also affect the exit status).



        That's specially useful with assignments.



        In:



        output=$(grep pattern file)
        status=$?


        You can get both the output and exit status of grep, which you couldn't do if $? was otherwise the exit status of that non-command.



        In:



        output=$(cmd1) cmd2


        That is where there are both assignment words and argument words, the exit status of cmd1 is ignored. $? will contain the exit status of cmd2.



        And, also $output will only be set for cmd2 only. Exception to that is when cmd2 is a special builtin.



        eval is such a special builtin.



        $ a=0; a=1 eval; echo "$a"
        1


        In bash and most modern POSIX shells.



        a=`exit 5` eval; echo "$?"


        or



        eval `exit 5`; echo "$?"


        Would output 0, as it's the result of running eval with no argument. But that was not the case in the Bourne shell or ksh88, where for special builtins you'd get the exit status of exit 5 there.



        In those shells, you'll also find:



        $ a=`exit 3` set x; echo "$?"
        3


        As set is another special builtin.



        . is another special builtin. In the Bourne shell and ksh88:



        $ . /some/file `exit 4`; echo "$?"
        4


        (as long as /some/file doesn't run any command)






        share|improve this answer












        Actually, it's more the:



        $ `nonsense`
        bash: nonsense: command not found
        $ echo "$?"
        127


        That is surprising here.



        We're asking bash to run the command that results of the split+glob operator on the stdout of nonsense. Since nonsense produces no output, it runs no command, so you may think the exit status should be 0.



        But actually, when a simple command line has no argument, only assignment or redirection, the exit status is that of the last command substitution in assignment and normal words (not in redirection targets) that was run (though failure in redirections will also affect the exit status).



        That's specially useful with assignments.



        In:



        output=$(grep pattern file)
        status=$?


        You can get both the output and exit status of grep, which you couldn't do if $? was otherwise the exit status of that non-command.



        In:



        output=$(cmd1) cmd2


        That is where there are both assignment words and argument words, the exit status of cmd1 is ignored. $? will contain the exit status of cmd2.



        And, also $output will only be set for cmd2 only. Exception to that is when cmd2 is a special builtin.



        eval is such a special builtin.



        $ a=0; a=1 eval; echo "$a"
        1


        In bash and most modern POSIX shells.



        a=`exit 5` eval; echo "$?"


        or



        eval `exit 5`; echo "$?"


        Would output 0, as it's the result of running eval with no argument. But that was not the case in the Bourne shell or ksh88, where for special builtins you'd get the exit status of exit 5 there.



        In those shells, you'll also find:



        $ a=`exit 3` set x; echo "$?"
        3


        As set is another special builtin.



        . is another special builtin. In the Bourne shell and ksh88:



        $ . /some/file `exit 4`; echo "$?"
        4


        (as long as /some/file doesn't run any command)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 4 at 12:32









        Stéphane Chazelas

        281k53518849




        281k53518849






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f414740%2freturn-value-from-eval%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay