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

Multi tool use
Multi tool use

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













































































          n6fjE5cMvXxu8J0yaiMLTvYOkbvWmaqa4oIMWyH bE,QRQYSVmHlajVUJ2Fdd5
          YiUQCmATD 6W R,AyDtTJbrWymDaqWn1,D ZcKFBuby,RDFh

          Popular posts from this blog

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

          How many registers does an x86_64 CPU actually have?

          Displaying single band from multi-band raster using QGIS