How to have a script work with “$@” or a default list of parameters while not breaking paths with...












6















I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.



So far I have script.sh:



#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"


If I put this into a folder called "foo bar" and run it as:




foo bar/script.sh



I want it to should end up doing:



touch foo bar/aaa foo bar/bbb


i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.



Instead I get the error




touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory




(If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)










share|improve this question





























    6















    I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.



    So far I have script.sh:



    #!/bin/sh
    base=$(dirname "$0")
    exec touch "${@:-"$base/aaa" "$base/bbb"}"


    If I put this into a folder called "foo bar" and run it as:




    foo bar/script.sh



    I want it to should end up doing:



    touch foo bar/aaa foo bar/bbb


    i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.



    Instead I get the error




    touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory




    (If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)










    share|improve this question



























      6












      6








      6








      I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.



      So far I have script.sh:



      #!/bin/sh
      base=$(dirname "$0")
      exec touch "${@:-"$base/aaa" "$base/bbb"}"


      If I put this into a folder called "foo bar" and run it as:




      foo bar/script.sh



      I want it to should end up doing:



      touch foo bar/aaa foo bar/bbb


      i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.



      Instead I get the error




      touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory




      (If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)










      share|improve this question
















      I want a script that will run another utility over some default paths if no parameters are passed to it; ideally I want this safe for paths that contain spaces.



      So far I have script.sh:



      #!/bin/sh
      base=$(dirname "$0")
      exec touch "${@:-"$base/aaa" "$base/bbb"}"


      If I put this into a folder called "foo bar" and run it as:




      foo bar/script.sh



      I want it to should end up doing:



      touch foo bar/aaa foo bar/bbb


      i.e. create files "aaa" and "bbb" under "foo bar", the directory in which the script is located.



      Instead I get the error




      touch: cannot touch 'foo bar/aaa foo bar/bbb': No such file or directory




      (If I pass in parameters to the script it seems to work fine. Presumably removing the outer quotes in the last command would reverse my cases.)







      shell-script arguments






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 14 hours ago









      Gilles

      530k12810631591




      530k12810631591










      asked 14 hours ago









      millimoosemillimoose

      24315




      24315






















          2 Answers
          2






          active

          oldest

          votes


















          10














          It appears you can't set default parameters in an expansion of ${@:-...}, and "${@:-"$base/aaa" "$base/bbb"}" is expanded as a single string.



          If you want to set default parameters you might want to do this:



          base=$(dirname -- "$0")
          # test explicitly for no parameters, and set them.
          if [ "$#" -eq 0 ]; then
          set -- "$base/aaa" "$base/bbb"
          fi


          Then, the "$@" magically quoted parameter substitution can happen unabated:



          touch -- "$@"





          share|improve this answer





















          • 1





            @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

            – millimoose
            14 hours ago






          • 2





            (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

            – millimoose
            14 hours ago











          • About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

            – ilkkachu
            14 hours ago






          • 2





            Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

            – Isaac
            13 hours ago











          • @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

            – millimoose
            12 hours ago



















          6














          It IS possible to use several parameters in a default expansion ${@-...},



          like this:



          #!/bin/bash
          base=$(dirname "$0")
          arr=("$base/aaa" "$base/bbb")

          touch "${@:-"${arr[@]}"}"


          But only on shells that have arrays (ksh, zsh, bash, etc.).






          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%2f493980%2fhow-to-have-a-script-work-with-or-a-default-list-of-parameters-while-not-br%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









            10














            It appears you can't set default parameters in an expansion of ${@:-...}, and "${@:-"$base/aaa" "$base/bbb"}" is expanded as a single string.



            If you want to set default parameters you might want to do this:



            base=$(dirname -- "$0")
            # test explicitly for no parameters, and set them.
            if [ "$#" -eq 0 ]; then
            set -- "$base/aaa" "$base/bbb"
            fi


            Then, the "$@" magically quoted parameter substitution can happen unabated:



            touch -- "$@"





            share|improve this answer





















            • 1





              @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

              – millimoose
              14 hours ago






            • 2





              (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

              – millimoose
              14 hours ago











            • About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

              – ilkkachu
              14 hours ago






            • 2





              Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

              – Isaac
              13 hours ago











            • @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

              – millimoose
              12 hours ago
















            10














            It appears you can't set default parameters in an expansion of ${@:-...}, and "${@:-"$base/aaa" "$base/bbb"}" is expanded as a single string.



            If you want to set default parameters you might want to do this:



            base=$(dirname -- "$0")
            # test explicitly for no parameters, and set them.
            if [ "$#" -eq 0 ]; then
            set -- "$base/aaa" "$base/bbb"
            fi


            Then, the "$@" magically quoted parameter substitution can happen unabated:



            touch -- "$@"





            share|improve this answer





















            • 1





              @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

              – millimoose
              14 hours ago






            • 2





              (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

              – millimoose
              14 hours ago











            • About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

              – ilkkachu
              14 hours ago






            • 2





              Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

              – Isaac
              13 hours ago











            • @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

              – millimoose
              12 hours ago














            10












            10








            10







            It appears you can't set default parameters in an expansion of ${@:-...}, and "${@:-"$base/aaa" "$base/bbb"}" is expanded as a single string.



            If you want to set default parameters you might want to do this:



            base=$(dirname -- "$0")
            # test explicitly for no parameters, and set them.
            if [ "$#" -eq 0 ]; then
            set -- "$base/aaa" "$base/bbb"
            fi


            Then, the "$@" magically quoted parameter substitution can happen unabated:



            touch -- "$@"





            share|improve this answer















            It appears you can't set default parameters in an expansion of ${@:-...}, and "${@:-"$base/aaa" "$base/bbb"}" is expanded as a single string.



            If you want to set default parameters you might want to do this:



            base=$(dirname -- "$0")
            # test explicitly for no parameters, and set them.
            if [ "$#" -eq 0 ]; then
            set -- "$base/aaa" "$base/bbb"
            fi


            Then, the "$@" magically quoted parameter substitution can happen unabated:



            touch -- "$@"






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 14 hours ago









            Stéphane Chazelas

            300k55564916




            300k55564916










            answered 14 hours ago









            glenn jackmanglenn jackman

            50.6k571109




            50.6k571109








            • 1





              @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

              – millimoose
              14 hours ago






            • 2





              (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

              – millimoose
              14 hours ago











            • About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

              – ilkkachu
              14 hours ago






            • 2





              Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

              – Isaac
              13 hours ago











            • @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

              – millimoose
              12 hours ago














            • 1





              @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

              – millimoose
              14 hours ago






            • 2





              (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

              – millimoose
              14 hours ago











            • About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

              – ilkkachu
              14 hours ago






            • 2





              Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

              – Isaac
              13 hours ago











            • @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

              – millimoose
              12 hours ago








            1




            1





            @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

            – millimoose
            14 hours ago





            @Jesse_b It's a minor change and the rest works the same, but yes, that made it work for me

            – millimoose
            14 hours ago




            2




            2





            (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

            – millimoose
            14 hours ago





            (I like to stick to being dash-compatible if possible for scripts so as to not have to pull in bash into Docker images unnecessarily.)

            – millimoose
            14 hours ago













            About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

            – ilkkachu
            14 hours ago





            About that first sentence, set --; echo ${@:-default}; set -- a b; echo ${@:-default}; works (i.e. prints default and then a b) in all shells I tried. Though I don't think you should be able to give a list as a default value, the syntax only mentions a single word there.

            – ilkkachu
            14 hours ago




            2




            2





            Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

            – Isaac
            13 hours ago





            Sorry, but it is possible to use several parameters in a default expansion, but only with shells that have arrays. See my answer

            – Isaac
            13 hours ago













            @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

            – millimoose
            12 hours ago





            @ilkkachu - I mean in the context of my question I understood that sentence as “it’s impossible to do that and have it expand as OP wants”

            – millimoose
            12 hours ago













            6














            It IS possible to use several parameters in a default expansion ${@-...},



            like this:



            #!/bin/bash
            base=$(dirname "$0")
            arr=("$base/aaa" "$base/bbb")

            touch "${@:-"${arr[@]}"}"


            But only on shells that have arrays (ksh, zsh, bash, etc.).






            share|improve this answer






























              6














              It IS possible to use several parameters in a default expansion ${@-...},



              like this:



              #!/bin/bash
              base=$(dirname "$0")
              arr=("$base/aaa" "$base/bbb")

              touch "${@:-"${arr[@]}"}"


              But only on shells that have arrays (ksh, zsh, bash, etc.).






              share|improve this answer




























                6












                6








                6







                It IS possible to use several parameters in a default expansion ${@-...},



                like this:



                #!/bin/bash
                base=$(dirname "$0")
                arr=("$base/aaa" "$base/bbb")

                touch "${@:-"${arr[@]}"}"


                But only on shells that have arrays (ksh, zsh, bash, etc.).






                share|improve this answer















                It IS possible to use several parameters in a default expansion ${@-...},



                like this:



                #!/bin/bash
                base=$(dirname "$0")
                arr=("$base/aaa" "$base/bbb")

                touch "${@:-"${arr[@]}"}"


                But only on shells that have arrays (ksh, zsh, bash, etc.).







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 12 hours ago









                Wildcard

                22.7k962164




                22.7k962164










                answered 13 hours ago









                IsaacIsaac

                11.4k11652




                11.4k11652






























                    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%2f493980%2fhow-to-have-a-script-work-with-or-a-default-list-of-parameters-while-not-br%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

                    How to make a Squid Proxy server?

                    Is this a new Fibonacci Identity?

                    19世紀