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
























  • Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
    – Stéphane Chazelas
    20 mins ago
















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
























  • Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
    – Stéphane Chazelas
    20 mins ago














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 53 mins ago









ilkkachu

55.9k784155




55.9k784155










asked 4 hours ago









Isaac

11.2k11648




11.2k11648












  • Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
    – Stéphane Chazelas
    20 mins ago


















  • Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
    – Stéphane Chazelas
    20 mins ago
















Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
– Stéphane Chazelas
20 mins ago




Note that in the Bourne shell (contrary to POSIX shells), /bin::/usr/bin would be split into /bin and /usr/bin instead of /bin, "" and /usr/bin.
– Stéphane Chazelas
20 mins ago










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
    1 hour 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
    51 mins ago










  • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
    – Stéphane Chazelas
    51 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


In any case, yes, in theory $PATH like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH won't contain newline characters.






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
      1 hour 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
      51 mins ago










    • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
      – Stéphane Chazelas
      51 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
      1 hour 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
      51 mins ago










    • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
      – Stéphane Chazelas
      51 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 1 hour ago









    ilkkachu

    55.9k784155




    55.9k784155










    answered 2 hours 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
      1 hour 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
      51 mins ago










    • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
      – Stéphane Chazelas
      51 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
      1 hour 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
      51 mins ago










    • That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
      – Stéphane Chazelas
      51 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
    1 hour 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
    1 hour 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
    51 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
    51 mins ago












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






    That mapfile -td: <<< "$PATH" adds a trailing newline to the last element (and needs bash 4.4 or above).
    – Stéphane Chazelas
    51 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


    In any case, yes, in theory $PATH like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH won't contain newline characters.






    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


      In any case, yes, in theory $PATH like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH won't contain newline characters.






      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


        In any case, yes, in theory $PATH like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH won't contain newline characters.






        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


        In any case, yes, in theory $PATH like any variable could contain newline characters, the newline character is not special in any way when it comes to file path resolution. I don't expect anyone sensible would put a directory with newline (or wildcards) in their $PATH or name a command with newline in its name. It's also hard to imagine a scenario where someone could exploit a script that makes the assumption that $PATH won't contain newline characters.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 15 mins ago

























        answered 46 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

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu