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 4 hours ago









      Gilles

      530k12810631591




      530k12810631591










      asked 4 hours ago









      millimoosemillimoose

      24315




      24315






















          2 Answers
          2






          active

          oldest

          votes


















          8














          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





            OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

            – Jesse_b
            4 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
            4 hours ago






          • 1





            (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
            4 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
            4 hours ago






          • 1





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

            – Isaac
            3 hours ago



















          5














          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









            8














            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





              OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

              – Jesse_b
              4 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
              4 hours ago






            • 1





              (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
              4 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
              4 hours ago






            • 1





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

              – Isaac
              3 hours ago
















            8














            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





              OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

              – Jesse_b
              4 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
              4 hours ago






            • 1





              (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
              4 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
              4 hours ago






            • 1





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

              – Isaac
              3 hours ago














            8












            8








            8







            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 4 hours ago









            Stéphane Chazelas

            300k54564916




            300k54564916










            answered 4 hours ago









            glenn jackmanglenn jackman

            50.6k570108




            50.6k570108








            • 1





              OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

              – Jesse_b
              4 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
              4 hours ago






            • 1





              (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
              4 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
              4 hours ago






            • 1





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

              – Isaac
              3 hours ago














            • 1





              OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

              – Jesse_b
              4 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
              4 hours ago






            • 1





              (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
              4 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
              4 hours ago






            • 1





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

              – Isaac
              3 hours ago








            1




            1





            OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

            – Jesse_b
            4 hours ago





            OP is using /bin/sh so maybe if ((!$#)); then or if [ $# -eq 0 ]; then?

            – Jesse_b
            4 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
            4 hours ago





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

            – millimoose
            4 hours ago




            1




            1





            (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
            4 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
            4 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
            4 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
            4 hours ago




            1




            1





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

            – Isaac
            3 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
            3 hours ago













            5














            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






























              5














              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




























                5












                5








                5







                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 2 hours ago









                Wildcard

                22.7k962164




                22.7k962164










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

                    What other Star Trek series did the main TNG cast show up in?

                    Berlina muro

                    Berlina aerponto