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












4















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





























    4















    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



























      4












      4








      4








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









      Gilles

      530k12810631591




      530k12810631591










      asked 1 hour ago









      millimoosemillimoose

      23315




      23315






















          1 Answer
          1






          active

          oldest

          votes


















          5














          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


























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

            – Jesse_b
            54 mins ago






          • 1





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

            – millimoose
            51 mins 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
            45 mins 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
            38 mins ago











          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

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          5














          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


























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

            – Jesse_b
            54 mins ago






          • 1





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

            – millimoose
            51 mins 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
            45 mins 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
            38 mins ago
















          5














          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


























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

            – Jesse_b
            54 mins ago






          • 1





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

            – millimoose
            51 mins 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
            45 mins 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
            38 mins ago














          5












          5








          5







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









          Stéphane Chazelas

          300k54564916




          300k54564916










          answered 59 mins ago









          glenn jackmanglenn jackman

          50.6k570108




          50.6k570108













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

            – Jesse_b
            54 mins ago






          • 1





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

            – millimoose
            51 mins 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
            45 mins 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
            38 mins ago



















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

            – Jesse_b
            54 mins ago






          • 1





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

            – millimoose
            51 mins 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
            45 mins 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
            38 mins ago

















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

          – Jesse_b
          54 mins ago





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

          – Jesse_b
          54 mins 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
          51 mins ago





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

          – millimoose
          51 mins 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
          45 mins 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
          45 mins 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
          38 mins 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
          38 mins ago


















          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

          Liste der Baudenkmale in Friedland (Mecklenburg)

          Single-Malt-Whisky

          Czorneboh