Could PATH contain newlines?












2














It is known that a path could contain newlines in any of its components.



Should we conclude then that the environment variable $PATH could contain newlines ?



If so, how to split the $PATH into its elements, similar to (Bourne like):



IFS=':' ; set -f
for var in $PATH
do
echo "<$var>"
done


But if it could be done without changing IFS, even better.










share|improve this question





























    2














    It is known that a path could contain newlines in any of its components.



    Should we conclude then that the environment variable $PATH could contain newlines ?



    If so, how to split the $PATH into its elements, similar to (Bourne like):



    IFS=':' ; set -f
    for var in $PATH
    do
    echo "<$var>"
    done


    But if it could be done without changing IFS, even better.










    share|improve this question



























      2












      2








      2







      It is known that a path could contain newlines in any of its components.



      Should we conclude then that the environment variable $PATH could contain newlines ?



      If so, how to split the $PATH into its elements, similar to (Bourne like):



      IFS=':' ; set -f
      for var in $PATH
      do
      echo "<$var>"
      done


      But if it could be done without changing IFS, even better.










      share|improve this question















      It is known that a path could contain newlines in any of its components.



      Should we conclude then that the environment variable $PATH could contain newlines ?



      If so, how to split the $PATH into its elements, similar to (Bourne like):



      IFS=':' ; set -f
      for var in $PATH
      do
      echo "<$var>"
      done


      But if it could be done without changing IFS, even better.







      shell path newlines






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 32 mins ago









      ilkkachu

      55.9k784155




      55.9k784155










      asked 4 hours ago









      Isaac

      11.2k11648




      11.2k11648






















          2 Answers
          2






          active

          oldest

          votes


















          2














          Yes, PATH can contain newlines (even on ancient Unix system).



          As to splitting any string in shell, the only way you can do it portably is with IFS. You can use IFS=:; set -f -- $PATH or pass it to a function instead of looping with for, though.



          With bash you can "read" a string into an array (mapfile -td: <<< "$PATH" path). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.






          share|improve this answer























          • Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
            – ilkkachu
            38 mins ago










          • No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
            – Stéphane Chazelas
            30 mins ago










          • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
            – Stéphane Chazelas
            29 mins ago





















          1














          In POSIX shells, $IFS is a field delimiter, not separator, so a $PATH value like /bin:/usr/bin: would be split into /bin and /usr/bin instead of /bin, /usr/bin and the empty string (meaning the current directory). You need:



          IFS=:; set -o noglob
          for var in $PATH""; do
          printf '<%s>n' "$var"
          done


          To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh:



          for var in "${(s/:/@)PATH}"; do
          printf '<%s>n' "$var"
          done


          Though in that case, zsh already has the $path array tied to $PATH like in csh/tcsh, so:



          for var in "$path[@]"; do
          printf '<%s>n' "$var"
          done





          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',
            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%2f491706%2fcould-path-contain-newlines%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Yes, PATH can contain newlines (even on ancient Unix system).



            As to splitting any string in shell, the only way you can do it portably is with IFS. You can use IFS=:; set -f -- $PATH or pass it to a function instead of looping with for, though.



            With bash you can "read" a string into an array (mapfile -td: <<< "$PATH" path). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.






            share|improve this answer























            • Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
              – ilkkachu
              38 mins ago










            • No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
              – Stéphane Chazelas
              30 mins ago










            • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
              – Stéphane Chazelas
              29 mins ago


















            2














            Yes, PATH can contain newlines (even on ancient Unix system).



            As to splitting any string in shell, the only way you can do it portably is with IFS. You can use IFS=:; set -f -- $PATH or pass it to a function instead of looping with for, though.



            With bash you can "read" a string into an array (mapfile -td: <<< "$PATH" path). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.






            share|improve this answer























            • Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
              – ilkkachu
              38 mins ago










            • No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
              – Stéphane Chazelas
              30 mins ago










            • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
              – Stéphane Chazelas
              29 mins ago
















            2












            2








            2






            Yes, PATH can contain newlines (even on ancient Unix system).



            As to splitting any string in shell, the only way you can do it portably is with IFS. You can use IFS=:; set -f -- $PATH or pass it to a function instead of looping with for, though.



            With bash you can "read" a string into an array (mapfile -td: <<< "$PATH" path). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.






            share|improve this answer














            Yes, PATH can contain newlines (even on ancient Unix system).



            As to splitting any string in shell, the only way you can do it portably is with IFS. You can use IFS=:; set -f -- $PATH or pass it to a function instead of looping with for, though.



            With bash you can "read" a string into an array (mapfile -td: <<< "$PATH" path). But using arrays is usually not a good idea, because they can't be stored transparently in environment variables or passed as a single argument to external commands.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 41 mins ago









            ilkkachu

            55.9k784155




            55.9k784155










            answered 1 hour ago









            pizdelect

            35916




            35916












            • Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
              – ilkkachu
              38 mins ago










            • No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
              – Stéphane Chazelas
              30 mins ago










            • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
              – Stéphane Chazelas
              29 mins ago




















            • Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
              – ilkkachu
              38 mins ago










            • No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
              – Stéphane Chazelas
              30 mins ago










            • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
              – Stéphane Chazelas
              29 mins ago


















            Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
            – ilkkachu
            38 mins ago




            Using arrays is often an excellent idea, as a number of answers here on unix.SE show. It's almost impossible to handle lists of strings with arbitrary data without using an array. You only need lists of paths with whitespace, or a list of command arguments to get the issue. Of course you can use the positional parameters instead of an array, but those aren't any better regarding the points you mention: they can't be sanely pushed through the environment, nor passed as a single argument to external commands.
            – ilkkachu
            38 mins ago












            No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
            – Stéphane Chazelas
            30 mins ago




            No, you need the set -f to take effect before the $PATH expansion. So it should be set -o noglob; set -- $PATH""
            – Stéphane Chazelas
            30 mins ago












            That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
            – Stéphane Chazelas
            29 mins ago






            That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
            – Stéphane Chazelas
            29 mins ago















            1














            In POSIX shells, $IFS is a field delimiter, not separator, so a $PATH value like /bin:/usr/bin: would be split into /bin and /usr/bin instead of /bin, /usr/bin and the empty string (meaning the current directory). You need:



            IFS=:; set -o noglob
            for var in $PATH""; do
            printf '<%s>n' "$var"
            done


            To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh:



            for var in "${(s/:/@)PATH}"; do
            printf '<%s>n' "$var"
            done


            Though in that case, zsh already has the $path array tied to $PATH like in csh/tcsh, so:



            for var in "$path[@]"; do
            printf '<%s>n' "$var"
            done





            share|improve this answer


























              1














              In POSIX shells, $IFS is a field delimiter, not separator, so a $PATH value like /bin:/usr/bin: would be split into /bin and /usr/bin instead of /bin, /usr/bin and the empty string (meaning the current directory). You need:



              IFS=:; set -o noglob
              for var in $PATH""; do
              printf '<%s>n' "$var"
              done


              To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh:



              for var in "${(s/:/@)PATH}"; do
              printf '<%s>n' "$var"
              done


              Though in that case, zsh already has the $path array tied to $PATH like in csh/tcsh, so:



              for var in "$path[@]"; do
              printf '<%s>n' "$var"
              done





              share|improve this answer
























                1












                1








                1






                In POSIX shells, $IFS is a field delimiter, not separator, so a $PATH value like /bin:/usr/bin: would be split into /bin and /usr/bin instead of /bin, /usr/bin and the empty string (meaning the current directory). You need:



                IFS=:; set -o noglob
                for var in $PATH""; do
                printf '<%s>n' "$var"
                done


                To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh:



                for var in "${(s/:/@)PATH}"; do
                printf '<%s>n' "$var"
                done


                Though in that case, zsh already has the $path array tied to $PATH like in csh/tcsh, so:



                for var in "$path[@]"; do
                printf '<%s>n' "$var"
                done





                share|improve this answer












                In POSIX shells, $IFS is a field delimiter, not separator, so a $PATH value like /bin:/usr/bin: would be split into /bin and /usr/bin instead of /bin, /usr/bin and the empty string (meaning the current directory). You need:



                IFS=:; set -o noglob
                for var in $PATH""; do
                printf '<%s>n' "$var"
                done


                To avoid modifying global settings, you can use a shell with explicit splitting operators like zsh:



                for var in "${(s/:/@)PATH}"; do
                printf '<%s>n' "$var"
                done


                Though in that case, zsh already has the $path array tied to $PATH like in csh/tcsh, so:



                for var in "$path[@]"; do
                printf '<%s>n' "$var"
                done






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 25 mins ago









                Stéphane Chazelas

                299k54564913




                299k54564913






























                    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.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • 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%2f491706%2fcould-path-contain-newlines%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

                    Михайлов, Христо

                    Центральная группа войск

                    Троллейбус