Is a failed filename generation the only case where zsh stops processing a script?

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











up vote
0
down vote

favorite












I was trying to write a short script which would write all the executable programs found in $PATH:



for dir in $(tr ':' ' ' <<<"$PATH"); do
for pgm in $dir/*; do
if command -v "$pgm" >/dev/null 2>&1; then
echo "$pgm"
fi
done
done | sort >file


In bash, it works as expected, but zsh stops processing the script as soon as a filename generation fails in the inner loop:



for pgm in $dir/*; do
^^^^^^
...
done


As a result, since my $PATH contains a directory which doesn't contain any file (/usr/local/sbin), in zsh, the script fails to write the executables found in the directories afterwards.



Here's another code showing the same issue:



for f in /not_a_dir/*; do
echo 'in the loop'
done
echo 'after the loop'


In bash, this command outputs:



in the loop
after the loop


And exits with the code 0.



While in zsh, the same command outputs:



no matches found: /not_a_dir/*


And exits with the code 1.



The difference of behavior between the shells seems to come from the nomatch option, which is described in man zshoptions:




NOMATCH (+3) <C> <Z>



If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged
in the argument list. This also applies to file expansion of an initial ~ or =.




And also explained in man zshexpn (section FILENAME GENERATION):




The word is replaced with a list of sorted filenames that match the pattern. If no matching pattern is found, the shell gives an error message, unless the NULL_GLOB option is set, in which case the word is deleted; or unless the NOMATCH option is unset, in which case the word is left unchanged.




Because if I unset it, zsh behaves like bash:



unsetopt nomatch
for f in /not_a_dir/*; do
echo 'in the loop'
done
echo 'after the loop'


Now I understand the difference of behaviors between bash and zsh, but I want to understand in which conditions zsh stops processing a script.
So, I tried to reproduce the same issue by replacing the failed filename generation with a failed command (by executing not_a_cmd):



for f in ~/*; do
not_a_cmd
done
echo 'after the loop'


But the output of this script is almost identical in both shells (apart from the error messages due to not_a_cmd). In particular, both shells print:



after the loop


And both shells exit with the code 0.



So, it seems that a failed filename generation (like for f in /not_a_dir/*) makes zsh stop processing a script, but not a failed command (like not_a_cmd).



Is it an exception, or are there other cases?



I'm using zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).









share

























    up vote
    0
    down vote

    favorite












    I was trying to write a short script which would write all the executable programs found in $PATH:



    for dir in $(tr ':' ' ' <<<"$PATH"); do
    for pgm in $dir/*; do
    if command -v "$pgm" >/dev/null 2>&1; then
    echo "$pgm"
    fi
    done
    done | sort >file


    In bash, it works as expected, but zsh stops processing the script as soon as a filename generation fails in the inner loop:



    for pgm in $dir/*; do
    ^^^^^^
    ...
    done


    As a result, since my $PATH contains a directory which doesn't contain any file (/usr/local/sbin), in zsh, the script fails to write the executables found in the directories afterwards.



    Here's another code showing the same issue:



    for f in /not_a_dir/*; do
    echo 'in the loop'
    done
    echo 'after the loop'


    In bash, this command outputs:



    in the loop
    after the loop


    And exits with the code 0.



    While in zsh, the same command outputs:



    no matches found: /not_a_dir/*


    And exits with the code 1.



    The difference of behavior between the shells seems to come from the nomatch option, which is described in man zshoptions:




    NOMATCH (+3) <C> <Z>



    If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged
    in the argument list. This also applies to file expansion of an initial ~ or =.




    And also explained in man zshexpn (section FILENAME GENERATION):




    The word is replaced with a list of sorted filenames that match the pattern. If no matching pattern is found, the shell gives an error message, unless the NULL_GLOB option is set, in which case the word is deleted; or unless the NOMATCH option is unset, in which case the word is left unchanged.




    Because if I unset it, zsh behaves like bash:



    unsetopt nomatch
    for f in /not_a_dir/*; do
    echo 'in the loop'
    done
    echo 'after the loop'


    Now I understand the difference of behaviors between bash and zsh, but I want to understand in which conditions zsh stops processing a script.
    So, I tried to reproduce the same issue by replacing the failed filename generation with a failed command (by executing not_a_cmd):



    for f in ~/*; do
    not_a_cmd
    done
    echo 'after the loop'


    But the output of this script is almost identical in both shells (apart from the error messages due to not_a_cmd). In particular, both shells print:



    after the loop


    And both shells exit with the code 0.



    So, it seems that a failed filename generation (like for f in /not_a_dir/*) makes zsh stop processing a script, but not a failed command (like not_a_cmd).



    Is it an exception, or are there other cases?



    I'm using zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).









    share























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I was trying to write a short script which would write all the executable programs found in $PATH:



      for dir in $(tr ':' ' ' <<<"$PATH"); do
      for pgm in $dir/*; do
      if command -v "$pgm" >/dev/null 2>&1; then
      echo "$pgm"
      fi
      done
      done | sort >file


      In bash, it works as expected, but zsh stops processing the script as soon as a filename generation fails in the inner loop:



      for pgm in $dir/*; do
      ^^^^^^
      ...
      done


      As a result, since my $PATH contains a directory which doesn't contain any file (/usr/local/sbin), in zsh, the script fails to write the executables found in the directories afterwards.



      Here's another code showing the same issue:



      for f in /not_a_dir/*; do
      echo 'in the loop'
      done
      echo 'after the loop'


      In bash, this command outputs:



      in the loop
      after the loop


      And exits with the code 0.



      While in zsh, the same command outputs:



      no matches found: /not_a_dir/*


      And exits with the code 1.



      The difference of behavior between the shells seems to come from the nomatch option, which is described in man zshoptions:




      NOMATCH (+3) <C> <Z>



      If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged
      in the argument list. This also applies to file expansion of an initial ~ or =.




      And also explained in man zshexpn (section FILENAME GENERATION):




      The word is replaced with a list of sorted filenames that match the pattern. If no matching pattern is found, the shell gives an error message, unless the NULL_GLOB option is set, in which case the word is deleted; or unless the NOMATCH option is unset, in which case the word is left unchanged.




      Because if I unset it, zsh behaves like bash:



      unsetopt nomatch
      for f in /not_a_dir/*; do
      echo 'in the loop'
      done
      echo 'after the loop'


      Now I understand the difference of behaviors between bash and zsh, but I want to understand in which conditions zsh stops processing a script.
      So, I tried to reproduce the same issue by replacing the failed filename generation with a failed command (by executing not_a_cmd):



      for f in ~/*; do
      not_a_cmd
      done
      echo 'after the loop'


      But the output of this script is almost identical in both shells (apart from the error messages due to not_a_cmd). In particular, both shells print:



      after the loop


      And both shells exit with the code 0.



      So, it seems that a failed filename generation (like for f in /not_a_dir/*) makes zsh stop processing a script, but not a failed command (like not_a_cmd).



      Is it an exception, or are there other cases?



      I'm using zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).









      share













      I was trying to write a short script which would write all the executable programs found in $PATH:



      for dir in $(tr ':' ' ' <<<"$PATH"); do
      for pgm in $dir/*; do
      if command -v "$pgm" >/dev/null 2>&1; then
      echo "$pgm"
      fi
      done
      done | sort >file


      In bash, it works as expected, but zsh stops processing the script as soon as a filename generation fails in the inner loop:



      for pgm in $dir/*; do
      ^^^^^^
      ...
      done


      As a result, since my $PATH contains a directory which doesn't contain any file (/usr/local/sbin), in zsh, the script fails to write the executables found in the directories afterwards.



      Here's another code showing the same issue:



      for f in /not_a_dir/*; do
      echo 'in the loop'
      done
      echo 'after the loop'


      In bash, this command outputs:



      in the loop
      after the loop


      And exits with the code 0.



      While in zsh, the same command outputs:



      no matches found: /not_a_dir/*


      And exits with the code 1.



      The difference of behavior between the shells seems to come from the nomatch option, which is described in man zshoptions:




      NOMATCH (+3) <C> <Z>



      If a pattern for filename generation has no matches, print an error, instead of leaving it unchanged
      in the argument list. This also applies to file expansion of an initial ~ or =.




      And also explained in man zshexpn (section FILENAME GENERATION):




      The word is replaced with a list of sorted filenames that match the pattern. If no matching pattern is found, the shell gives an error message, unless the NULL_GLOB option is set, in which case the word is deleted; or unless the NOMATCH option is unset, in which case the word is left unchanged.




      Because if I unset it, zsh behaves like bash:



      unsetopt nomatch
      for f in /not_a_dir/*; do
      echo 'in the loop'
      done
      echo 'after the loop'


      Now I understand the difference of behaviors between bash and zsh, but I want to understand in which conditions zsh stops processing a script.
      So, I tried to reproduce the same issue by replacing the failed filename generation with a failed command (by executing not_a_cmd):



      for f in ~/*; do
      not_a_cmd
      done
      echo 'after the loop'


      But the output of this script is almost identical in both shells (apart from the error messages due to not_a_cmd). In particular, both shells print:



      after the loop


      And both shells exit with the code 0.



      So, it seems that a failed filename generation (like for f in /not_a_dir/*) makes zsh stop processing a script, but not a failed command (like not_a_cmd).



      Is it an exception, or are there other cases?



      I'm using zsh 5.6.2-dev-0 (x86_64-pc-linux-gnu).







      zsh





      share












      share










      share



      share










      asked 7 mins ago









      user938271

      19918




      19918

























          active

          oldest

          votes











          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: "",
          imageUploader:
          brandingHtml: "",
          contentPolicyHtml: "",
          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%2f478813%2fis-a-failed-filename-generation-the-only-case-where-zsh-stops-processing-a-scrip%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478813%2fis-a-failed-filename-generation-the-only-case-where-zsh-stops-processing-a-scrip%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?

          Displaying single band from multi-band raster using QGIS

          How many registers does an x86_64 CPU actually have?