Why doesn't using multiple commands with a || or && conditional work? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election Results Why I closed the “Why is Kali so hard” questionHow can I test if a variable is empty or contains only spaces?Precedence of logical operators versus semicolonUsing sshpass, return code (exit status) differs for reasons unknown using valid commandsScript in C shell skipping over last else statement?Modify bash arguments if only one argument is setFunction that calls another function with list of arguments doesn't workC Shell Script syntax error “unexpected end of of file”“dash” arguments to shell scriptsHow to use as argument the characters + , - , x , / in a scriptCreate a menu driven script with do loop and case statement in bashA star is being printed for an empty directory after running a script to list the subfolderecho $HISTSIZE not printing when executed via shell script but works in command line

How to react to hostile behavior from a senior developer?

Why are the trig functions versine, haversine, exsecant, etc, rarely used in modern mathematics?

As a beginner, should I get a Squier Strat with a SSS config or a HSS?

Project Euler #1 in C++

Has negative voting ever been officially implemented in elections, or seriously proposed, or even studied?

Why is Nikon 1.4g better when Nikon 1.8g is sharper?

Maximum summed subsequences with non-adjacent items

How come Sam didn't become Lord of Horn Hill?

When a candle burns, why does the top of wick glow if bottom of flame is hottest?

Why wasn't DOSKEY integrated with COMMAND.COM?

Should I use a zero-interest credit card for a large one-time purchase?

Does the Weapon Master feat grant you a fighting style?

How to tell that you are a giant?

How would a mousetrap for use in space work?

Significance of Cersei's obsession with elephants?

Using et al. for a last / senior author rather than for a first author

Performance gap between bool std:vector and array

What is the Characteristic of a local ring?

Crossing US/Canada Border for less than 24 hours

Take 2! Is this homebrew Lady of Pain warlock patron balanced?

Modified Intersection Puzzle

What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?

NumericArray versus PackedArray in MMA12

What's the meaning of "fortified infraction restraint"?



Why doesn't using multiple commands with a || or && conditional work?



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionHow can I test if a variable is empty or contains only spaces?Precedence of logical operators versus semicolonUsing sshpass, return code (exit status) differs for reasons unknown using valid commandsScript in C shell skipping over last else statement?Modify bash arguments if only one argument is setFunction that calls another function with list of arguments doesn't workC Shell Script syntax error “unexpected end of of file”“dash” arguments to shell scriptsHow to use as argument the characters + , - , x , / in a scriptCreate a menu driven script with do loop and case statement in bashA star is being printed for an empty directory after running a script to list the subfolderecho $HISTSIZE not printing when executed via shell script but works in command line



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








12

















This works on a shell (bash, dash) prompt:



[ -z "" ] && echo A || echo B
A


However, I am trying to write a POSIX shell script, it starts like this:



#!/bin/sh

[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

readonly raw_input_string=$1

[ -z "$raw_input_string" ] && echo "The given argument is empty."; exit 1


And I don't know why, but I don't get the message:




The given argument is empty.




if I call the script like this:



./test_empty_argument ""


Why is that?










share|improve this question



















  • 5





    See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

    – ilkkachu
    Apr 3 at 17:12







  • 1





    Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

    – user2497
    Apr 3 at 17:37






  • 3





    @user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

    – chepner
    Apr 3 at 18:11












  • @chepner So it is not a valid solution? Something else must be used?

    – user2497
    Apr 3 at 18:31






  • 6





    [ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

    – chepner
    Apr 3 at 18:50


















12

















This works on a shell (bash, dash) prompt:



[ -z "" ] && echo A || echo B
A


However, I am trying to write a POSIX shell script, it starts like this:



#!/bin/sh

[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

readonly raw_input_string=$1

[ -z "$raw_input_string" ] && echo "The given argument is empty."; exit 1


And I don't know why, but I don't get the message:




The given argument is empty.




if I call the script like this:



./test_empty_argument ""


Why is that?










share|improve this question



















  • 5





    See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

    – ilkkachu
    Apr 3 at 17:12







  • 1





    Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

    – user2497
    Apr 3 at 17:37






  • 3





    @user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

    – chepner
    Apr 3 at 18:11












  • @chepner So it is not a valid solution? Something else must be used?

    – user2497
    Apr 3 at 18:31






  • 6





    [ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

    – chepner
    Apr 3 at 18:50














12












12








12










This works on a shell (bash, dash) prompt:



[ -z "" ] && echo A || echo B
A


However, I am trying to write a POSIX shell script, it starts like this:



#!/bin/sh

[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

readonly raw_input_string=$1

[ -z "$raw_input_string" ] && echo "The given argument is empty."; exit 1


And I don't know why, but I don't get the message:




The given argument is empty.




if I call the script like this:



./test_empty_argument ""


Why is that?










share|improve this question


















This works on a shell (bash, dash) prompt:



[ -z "" ] && echo A || echo B
A


However, I am trying to write a POSIX shell script, it starts like this:



#!/bin/sh

[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

readonly raw_input_string=$1

[ -z "$raw_input_string" ] && echo "The given argument is empty."; exit 1


And I don't know why, but I don't get the message:




The given argument is empty.




if I call the script like this:



./test_empty_argument ""


Why is that?







shell-script arguments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 3 at 20:40









ilkkachu

63.5k10104181




63.5k10104181










asked Apr 3 at 6:41









VlastimilVlastimil

8,6531667150




8,6531667150







  • 5





    See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

    – ilkkachu
    Apr 3 at 17:12







  • 1





    Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

    – user2497
    Apr 3 at 17:37






  • 3





    @user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

    – chepner
    Apr 3 at 18:11












  • @chepner So it is not a valid solution? Something else must be used?

    – user2497
    Apr 3 at 18:31






  • 6





    [ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

    – chepner
    Apr 3 at 18:50













  • 5





    See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

    – ilkkachu
    Apr 3 at 17:12







  • 1





    Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

    – user2497
    Apr 3 at 17:37






  • 3





    @user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

    – chepner
    Apr 3 at 18:11












  • @chepner So it is not a valid solution? Something else must be used?

    – user2497
    Apr 3 at 18:31






  • 6





    [ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

    – chepner
    Apr 3 at 18:50








5




5





See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

– ilkkachu
Apr 3 at 17:12






See How can I test if a variable is empty or contains only spaces? for ways on testing if a variable is empty, unset, or only contains blanks. The issue in this question has nothing to do with that.

– ilkkachu
Apr 3 at 17:12





1




1





Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

– user2497
Apr 3 at 17:37





Just use if [ X”” = X”$var” ] ; then echo isempty ; fi

– user2497
Apr 3 at 17:37




3




3





@user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

– chepner
Apr 3 at 18:11






@user2497 There is no reason to use that in any shell released in the last 20 years. That's a workaround for old, buggy shells.

– chepner
Apr 3 at 18:11














@chepner So it is not a valid solution? Something else must be used?

– user2497
Apr 3 at 18:31





@chepner So it is not a valid solution? Something else must be used?

– user2497
Apr 3 at 18:31




6




6





[ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

– chepner
Apr 3 at 18:50






[ "" = "$var" ] would work fine; a quoted empty string will not be removed from the argument list of [. But that's not necessary either, because [ -z "$var" ] also works just fine.

– chepner
Apr 3 at 18:50











4 Answers
4






active

oldest

votes


















36














Note that your line



[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


this is the same as



[ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."
exit 1


(an unquoted ; can, in most circumstances, be replaced by a newline character)



This means that the exit 1 statement is always executed regardless of how many arguments were passed to the script. This in turn means that the message The given argument is empty. would never have a chance of getting printed.



To execute more than a single statement after a test using the "short-circuit syntax", group the statements in ...; . The alternative is to use a proper if statement (which, IMHO, looks cleaner in a script):



if [ "$#" -ne 1 ]; then
echo 'Invalid number of arguments, expected one.' >&2
exit 1
fi


You have the same issue with your second test.




Regarding



[ -z "" ] && echo A || echo B


This would work for the given example, but the generic



some-test && command1 || command2


would not be the same as



if some-test; then
command1
else
command2
fi


Instead, it is more like



if ! some-test && command1; ; then
command2
fi


or



if some-test && command1; then
:
else
command2
fi


That is, if either the test or the first command fails, the second command executes, which means it has the potential to execute all three involved statements.






share|improve this answer
































    18














    This:



    [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


    is not:



    [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1; 


    But instead is:



     echo "Invalid number of arguments, expected one."; 
    exit 1


    Your script is exiting regardless of how many arguments you passed to it.






    share|improve this answer






























      8














      One way to make it more readable is to define a die function (à la perl) like:



      die() 
      printf >&2 '%sn' "$@"
      exit 1


      # then:

      [ "$#" -eq 1 ] || die "Expected one argument, got $#"

      [ -n "$1" ] || die "Empty argument not supported"


      You can add more bells and whistles like colours, prefix, line number... if need be.






      share|improve this answer

























      • In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

        – jrw32982
        Apr 3 at 18:15






      • 3





        The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

        – Charles Duffy
        Apr 3 at 20:54






      • 1





        @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

        – Stéphane Chazelas
        Apr 4 at 7:17












      • @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

        – jrw32982
        Apr 4 at 13:24












      • @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

        – jrw32982
        Apr 4 at 13:29



















      -1














      I've often seen this as a test for an empty string:



      if [ "x$foo" = "x" ]; then ...





      share|improve this answer

























      • Should have been "=" - fixed.

        – wef
        Apr 3 at 6:56






      • 3





        That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

        – Charles Duffy
        Apr 3 at 20:52












      • Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

        – wef
        Apr 3 at 22:21











      • NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

        – Charles Duffy
        Apr 3 at 23:13







      • 1





        I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

        – Charles Duffy
        Apr 3 at 23:32











      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',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      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%2f510216%2fwhy-doesnt-using-multiple-commands-with-a-or-conditional-work%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      36














      Note that your line



      [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


      this is the same as



      [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."
      exit 1


      (an unquoted ; can, in most circumstances, be replaced by a newline character)



      This means that the exit 1 statement is always executed regardless of how many arguments were passed to the script. This in turn means that the message The given argument is empty. would never have a chance of getting printed.



      To execute more than a single statement after a test using the "short-circuit syntax", group the statements in ...; . The alternative is to use a proper if statement (which, IMHO, looks cleaner in a script):



      if [ "$#" -ne 1 ]; then
      echo 'Invalid number of arguments, expected one.' >&2
      exit 1
      fi


      You have the same issue with your second test.




      Regarding



      [ -z "" ] && echo A || echo B


      This would work for the given example, but the generic



      some-test && command1 || command2


      would not be the same as



      if some-test; then
      command1
      else
      command2
      fi


      Instead, it is more like



      if ! some-test && command1; ; then
      command2
      fi


      or



      if some-test && command1; then
      :
      else
      command2
      fi


      That is, if either the test or the first command fails, the second command executes, which means it has the potential to execute all three involved statements.






      share|improve this answer





























        36














        Note that your line



        [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


        this is the same as



        [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."
        exit 1


        (an unquoted ; can, in most circumstances, be replaced by a newline character)



        This means that the exit 1 statement is always executed regardless of how many arguments were passed to the script. This in turn means that the message The given argument is empty. would never have a chance of getting printed.



        To execute more than a single statement after a test using the "short-circuit syntax", group the statements in ...; . The alternative is to use a proper if statement (which, IMHO, looks cleaner in a script):



        if [ "$#" -ne 1 ]; then
        echo 'Invalid number of arguments, expected one.' >&2
        exit 1
        fi


        You have the same issue with your second test.




        Regarding



        [ -z "" ] && echo A || echo B


        This would work for the given example, but the generic



        some-test && command1 || command2


        would not be the same as



        if some-test; then
        command1
        else
        command2
        fi


        Instead, it is more like



        if ! some-test && command1; ; then
        command2
        fi


        or



        if some-test && command1; then
        :
        else
        command2
        fi


        That is, if either the test or the first command fails, the second command executes, which means it has the potential to execute all three involved statements.






        share|improve this answer



























          36












          36








          36







          Note that your line



          [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


          this is the same as



          [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."
          exit 1


          (an unquoted ; can, in most circumstances, be replaced by a newline character)



          This means that the exit 1 statement is always executed regardless of how many arguments were passed to the script. This in turn means that the message The given argument is empty. would never have a chance of getting printed.



          To execute more than a single statement after a test using the "short-circuit syntax", group the statements in ...; . The alternative is to use a proper if statement (which, IMHO, looks cleaner in a script):



          if [ "$#" -ne 1 ]; then
          echo 'Invalid number of arguments, expected one.' >&2
          exit 1
          fi


          You have the same issue with your second test.




          Regarding



          [ -z "" ] && echo A || echo B


          This would work for the given example, but the generic



          some-test && command1 || command2


          would not be the same as



          if some-test; then
          command1
          else
          command2
          fi


          Instead, it is more like



          if ! some-test && command1; ; then
          command2
          fi


          or



          if some-test && command1; then
          :
          else
          command2
          fi


          That is, if either the test or the first command fails, the second command executes, which means it has the potential to execute all three involved statements.






          share|improve this answer















          Note that your line



          [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


          this is the same as



          [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."
          exit 1


          (an unquoted ; can, in most circumstances, be replaced by a newline character)



          This means that the exit 1 statement is always executed regardless of how many arguments were passed to the script. This in turn means that the message The given argument is empty. would never have a chance of getting printed.



          To execute more than a single statement after a test using the "short-circuit syntax", group the statements in ...; . The alternative is to use a proper if statement (which, IMHO, looks cleaner in a script):



          if [ "$#" -ne 1 ]; then
          echo 'Invalid number of arguments, expected one.' >&2
          exit 1
          fi


          You have the same issue with your second test.




          Regarding



          [ -z "" ] && echo A || echo B


          This would work for the given example, but the generic



          some-test && command1 || command2


          would not be the same as



          if some-test; then
          command1
          else
          command2
          fi


          Instead, it is more like



          if ! some-test && command1; ; then
          command2
          fi


          or



          if some-test && command1; then
          :
          else
          command2
          fi


          That is, if either the test or the first command fails, the second command executes, which means it has the potential to execute all three involved statements.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 19 mins ago

























          answered Apr 3 at 6:48









          KusalanandaKusalananda

          142k18266442




          142k18266442























              18














              This:



              [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


              is not:



              [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1; 


              But instead is:



               echo "Invalid number of arguments, expected one."; 
              exit 1


              Your script is exiting regardless of how many arguments you passed to it.






              share|improve this answer



























                18














                This:



                [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


                is not:



                [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1; 


                But instead is:



                 echo "Invalid number of arguments, expected one."; 
                exit 1


                Your script is exiting regardless of how many arguments you passed to it.






                share|improve this answer

























                  18












                  18








                  18







                  This:



                  [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


                  is not:



                  [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1; 


                  But instead is:



                   echo "Invalid number of arguments, expected one."; 
                  exit 1


                  Your script is exiting regardless of how many arguments you passed to it.






                  share|improve this answer













                  This:



                  [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1


                  is not:



                  [ "$#" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1; 


                  But instead is:



                   echo "Invalid number of arguments, expected one."; 
                  exit 1


                  Your script is exiting regardless of how many arguments you passed to it.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Apr 3 at 6:46









                  murumuru

                  38k590166




                  38k590166





















                      8














                      One way to make it more readable is to define a die function (à la perl) like:



                      die() 
                      printf >&2 '%sn' "$@"
                      exit 1


                      # then:

                      [ "$#" -eq 1 ] || die "Expected one argument, got $#"

                      [ -n "$1" ] || die "Empty argument not supported"


                      You can add more bells and whistles like colours, prefix, line number... if need be.






                      share|improve this answer

























                      • In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                        – jrw32982
                        Apr 3 at 18:15






                      • 3





                        The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                        – Charles Duffy
                        Apr 3 at 20:54






                      • 1





                        @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                        – Stéphane Chazelas
                        Apr 4 at 7:17












                      • @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                        – jrw32982
                        Apr 4 at 13:24












                      • @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                        – jrw32982
                        Apr 4 at 13:29
















                      8














                      One way to make it more readable is to define a die function (à la perl) like:



                      die() 
                      printf >&2 '%sn' "$@"
                      exit 1


                      # then:

                      [ "$#" -eq 1 ] || die "Expected one argument, got $#"

                      [ -n "$1" ] || die "Empty argument not supported"


                      You can add more bells and whistles like colours, prefix, line number... if need be.






                      share|improve this answer

























                      • In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                        – jrw32982
                        Apr 3 at 18:15






                      • 3





                        The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                        – Charles Duffy
                        Apr 3 at 20:54






                      • 1





                        @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                        – Stéphane Chazelas
                        Apr 4 at 7:17












                      • @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                        – jrw32982
                        Apr 4 at 13:24












                      • @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                        – jrw32982
                        Apr 4 at 13:29














                      8












                      8








                      8







                      One way to make it more readable is to define a die function (à la perl) like:



                      die() 
                      printf >&2 '%sn' "$@"
                      exit 1


                      # then:

                      [ "$#" -eq 1 ] || die "Expected one argument, got $#"

                      [ -n "$1" ] || die "Empty argument not supported"


                      You can add more bells and whistles like colours, prefix, line number... if need be.






                      share|improve this answer















                      One way to make it more readable is to define a die function (à la perl) like:



                      die() 
                      printf >&2 '%sn' "$@"
                      exit 1


                      # then:

                      [ "$#" -eq 1 ] || die "Expected one argument, got $#"

                      [ -n "$1" ] || die "Empty argument not supported"


                      You can add more bells and whistles like colours, prefix, line number... if need be.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Apr 4 at 13:35

























                      answered Apr 3 at 16:53









                      Stéphane ChazelasStéphane Chazelas

                      315k57597955




                      315k57597955












                      • In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                        – jrw32982
                        Apr 3 at 18:15






                      • 3





                        The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                        – Charles Duffy
                        Apr 3 at 20:54






                      • 1





                        @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                        – Stéphane Chazelas
                        Apr 4 at 7:17












                      • @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                        – jrw32982
                        Apr 4 at 13:24












                      • @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                        – jrw32982
                        Apr 4 at 13:29


















                      • In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                        – jrw32982
                        Apr 3 at 18:15






                      • 3





                        The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                        – Charles Duffy
                        Apr 3 at 20:54






                      • 1





                        @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                        – Stéphane Chazelas
                        Apr 4 at 7:17












                      • @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                        – jrw32982
                        Apr 4 at 13:24












                      • @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                        – jrw32982
                        Apr 4 at 13:29

















                      In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                      – jrw32982
                      Apr 3 at 18:15





                      In practice, do you ever call your die function with multiple arguments? (If so, can you give an example?) I use an almost identical die function, but use "$*" instead, which may be more what you're intending?

                      – jrw32982
                      Apr 3 at 18:15




                      3




                      3





                      The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                      – Charles Duffy
                      Apr 3 at 20:54





                      The value of "$@" is that it allows multi-line messages without needing to add literal newlines.

                      – Charles Duffy
                      Apr 3 at 20:54




                      1




                      1





                      @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                      – Stéphane Chazelas
                      Apr 4 at 7:17






                      @jrw32982, using "$*" to join args with spaces also means you need to set $IFS to SPC for it to work in all contexts including those where $IFS has been modified. Alternatively with ksh/zsh, you can use print -r -- "$@" or echo -E - "$@" in zsh.

                      – Stéphane Chazelas
                      Apr 4 at 7:17














                      @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                      – jrw32982
                      Apr 4 at 13:24






                      @CharlesDuffy Yes, but I've never seen that done in the context of a die-type function. What I'm asking is: in practice, have you ever seen anyone write die "unable to blah:" "some error", for the purpose of getting a 2-line error message?

                      – jrw32982
                      Apr 4 at 13:24














                      @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                      – jrw32982
                      Apr 4 at 13:29






                      @StéphaneChazelas Good point. So (in my formulation) it should be die() IFS=" "; printf >&2 "%sn" "$*"; exit 1; . Have you ever personally used this kind of die function to have printf generate a multi-line error message by passing multiple arguments? Or do you only ever pass a single argument to die so that it only adds a single newline to its output?

                      – jrw32982
                      Apr 4 at 13:29












                      -1














                      I've often seen this as a test for an empty string:



                      if [ "x$foo" = "x" ]; then ...





                      share|improve this answer

























                      • Should have been "=" - fixed.

                        – wef
                        Apr 3 at 6:56






                      • 3





                        That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                        – Charles Duffy
                        Apr 3 at 20:52












                      • Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                        – wef
                        Apr 3 at 22:21











                      • NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                        – Charles Duffy
                        Apr 3 at 23:13







                      • 1





                        I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                        – Charles Duffy
                        Apr 3 at 23:32















                      -1














                      I've often seen this as a test for an empty string:



                      if [ "x$foo" = "x" ]; then ...





                      share|improve this answer

























                      • Should have been "=" - fixed.

                        – wef
                        Apr 3 at 6:56






                      • 3





                        That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                        – Charles Duffy
                        Apr 3 at 20:52












                      • Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                        – wef
                        Apr 3 at 22:21











                      • NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                        – Charles Duffy
                        Apr 3 at 23:13







                      • 1





                        I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                        – Charles Duffy
                        Apr 3 at 23:32













                      -1












                      -1








                      -1







                      I've often seen this as a test for an empty string:



                      if [ "x$foo" = "x" ]; then ...





                      share|improve this answer















                      I've often seen this as a test for an empty string:



                      if [ "x$foo" = "x" ]; then ...






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Apr 3 at 6:55

























                      answered Apr 3 at 6:54









                      wefwef

                      31215




                      31215












                      • Should have been "=" - fixed.

                        – wef
                        Apr 3 at 6:56






                      • 3





                        That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                        – Charles Duffy
                        Apr 3 at 20:52












                      • Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                        – wef
                        Apr 3 at 22:21











                      • NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                        – Charles Duffy
                        Apr 3 at 23:13







                      • 1





                        I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                        – Charles Duffy
                        Apr 3 at 23:32

















                      • Should have been "=" - fixed.

                        – wef
                        Apr 3 at 6:56






                      • 3





                        That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                        – Charles Duffy
                        Apr 3 at 20:52












                      • Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                        – wef
                        Apr 3 at 22:21











                      • NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                        – Charles Duffy
                        Apr 3 at 23:13







                      • 1





                        I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                        – Charles Duffy
                        Apr 3 at 23:32
















                      Should have been "=" - fixed.

                      – wef
                      Apr 3 at 6:56





                      Should have been "=" - fixed.

                      – wef
                      Apr 3 at 6:56




                      3




                      3





                      That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                      – Charles Duffy
                      Apr 3 at 20:52






                      That practice is literally from the 1970s. There is no reason whatsoever to use it with any shell that is compliant with the 1992 POSIX sh standard (so long as correct quoting is used and now-obsolescent functionality such as -a, -o, ( and ) as derectives to tell test to combine multiple operations in a single invocation are avoided; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html).

                      – Charles Duffy
                      Apr 3 at 20:52














                      Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                      – wef
                      Apr 3 at 22:21





                      Non-linux unices shipped with the original 'sh' well into the '90's - maybe still do. In my job at that time, I had to write portable install scripts and I used this construct. I just looked at the install scripts that NVidia ships for linux and they still use this construct.

                      – wef
                      Apr 3 at 22:21













                      NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                      – Charles Duffy
                      Apr 3 at 23:13






                      NVidia may use it, but that's not to say they have any technical justification to do so; cargo-cult development in commercial UNIX is sadly prevalent. Even Heirloom Bourne doesn't have the bug in question -- so the SunOS codebase (that being the last commercial UNIX to ship a non-POSIX /bin/sh, and Heirloom Bourne's immediate predecessor) didn't have it either.

                      – Charles Duffy
                      Apr 3 at 23:13





                      1




                      1





                      I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                      – Charles Duffy
                      Apr 3 at 23:32





                      I don't wear a hat, so I can't promise to post a YouTube video eating it should someone turn up a shell published on a commercial UNIX with this bug post-1990... but if I did, it would be tempting. :)

                      – Charles Duffy
                      Apr 3 at 23:32

















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f510216%2fwhy-doesnt-using-multiple-commands-with-a-or-conditional-work%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Adding axes to figuresAdding axes labels to LaTeX figuresLaTeX equivalent of ConTeXt buffersRotate a node but not its content: the case of the ellipse decorationHow to define the default vertical distance between nodes?TikZ scaling graphic and adjust node position and keep font sizeNumerical conditional within tikz keys?adding axes to shapesAlign axes across subfiguresAdding figures with a certain orderLine up nested tikz enviroments or how to get rid of themAdding axes labels to LaTeX figures

                      Luettelo Yhdysvaltain laivaston lentotukialuksista Lähteet | Navigointivalikko

                      Gary (muusikko) Sisällysluettelo Historia | Rockin' High | Lähteet | Aiheesta muualla | NavigointivalikkoInfobox OKTuomas "Gary" Keskinen Ancaran kitaristiksiProjekti Rockin' High