Pass $@ to command, preserving quotes

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












I am trying to amend the behavior of git, using the approach outlined here, but I am stumbling on how to properly pass on the contents of $@ without losing the quotes of the original input.



Basically, I have this:



# foo.sh

#!/bin/bash
cmd=$1
shift
args=$@
if [ $cmd == "bar" ]; then args=('--baz' "$args[@]"); fi
echo git $cmd $args[@]


But when I run ./foo.sh bar -a "one two three", it outputs (and thus would have run), ./foo.sh bar --baz -a one two, rather than ./foo.sh bar --baz -a "one two" as I would have needed.



I can't figure out how to properly pass on $@ to another command and preserve quoted arguments. Is it possible? How?










share|improve this question









New contributor




Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.























    up vote
    0
    down vote

    favorite












    I am trying to amend the behavior of git, using the approach outlined here, but I am stumbling on how to properly pass on the contents of $@ without losing the quotes of the original input.



    Basically, I have this:



    # foo.sh

    #!/bin/bash
    cmd=$1
    shift
    args=$@
    if [ $cmd == "bar" ]; then args=('--baz' "$args[@]"); fi
    echo git $cmd $args[@]


    But when I run ./foo.sh bar -a "one two three", it outputs (and thus would have run), ./foo.sh bar --baz -a one two, rather than ./foo.sh bar --baz -a "one two" as I would have needed.



    I can't figure out how to properly pass on $@ to another command and preserve quoted arguments. Is it possible? How?










    share|improve this question









    New contributor




    Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am trying to amend the behavior of git, using the approach outlined here, but I am stumbling on how to properly pass on the contents of $@ without losing the quotes of the original input.



      Basically, I have this:



      # foo.sh

      #!/bin/bash
      cmd=$1
      shift
      args=$@
      if [ $cmd == "bar" ]; then args=('--baz' "$args[@]"); fi
      echo git $cmd $args[@]


      But when I run ./foo.sh bar -a "one two three", it outputs (and thus would have run), ./foo.sh bar --baz -a one two, rather than ./foo.sh bar --baz -a "one two" as I would have needed.



      I can't figure out how to properly pass on $@ to another command and preserve quoted arguments. Is it possible? How?










      share|improve this question









      New contributor




      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I am trying to amend the behavior of git, using the approach outlined here, but I am stumbling on how to properly pass on the contents of $@ without losing the quotes of the original input.



      Basically, I have this:



      # foo.sh

      #!/bin/bash
      cmd=$1
      shift
      args=$@
      if [ $cmd == "bar" ]; then args=('--baz' "$args[@]"); fi
      echo git $cmd $args[@]


      But when I run ./foo.sh bar -a "one two three", it outputs (and thus would have run), ./foo.sh bar --baz -a one two, rather than ./foo.sh bar --baz -a "one two" as I would have needed.



      I can't figure out how to properly pass on $@ to another command and preserve quoted arguments. Is it possible? How?







      bash






      share|improve this question









      New contributor




      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited Oct 1 at 14:46









      Goro

      7,02252965




      7,02252965






      New contributor




      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked Oct 1 at 14:43









      Tomas Lycken

      1012




      1012




      New contributor




      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Tomas Lycken is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          7
          down vote













          When using "$args[@]" you assume that args is an array, but it's not.



          For args to be an array, you must assign to it with an array assignment, such as



          args=( "$@" )


          To have the elements of the array individually quoted when you expand $args[@], you must double quote the expansion (just as with "$@"):



          echo git "$cmd" "$args[@]"


          In this simple example, the separate args array is not really needed at all:



          #!/bin/sh

          cmd=$1
          shift

          if [ "$cmd" = "bar" ]; then
          set -- --baz "$@"
          fi

          echo git "$cmd" "$@"


          Note that the quotes won't be outputted by the echo command above. But you can rest assured that echo gets exactly two arguments (git and $cmd) plus however many things are in $@ at that point. This is because the shell does quote removal on the command before executing it. You can compare this with what e.g. echo "one two" three outputs.



          A better way to output the the command for visual inspection would maybe be



          printf 'Arg: %sn' git "$cmd" "$@"


          This would print each separate argument to printf on its own line (prefixed by the string Arg:).



          Your git command, git "$cmd" "$@" (or git "$cmd" "$args[@]" if you use a separate array), would run correctly (given that the variables makes sense, ordinary git doesn't have a bar sub-command with a --baz option, for example).



          Related:



          • Why does my shell script choke on whitespace or other special 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',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );






            Tomas Lycken is a new contributor. Be nice, and check out our Code of Conduct.









             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f472589%2fpass-to-command-preserving-quotes%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            7
            down vote













            When using "$args[@]" you assume that args is an array, but it's not.



            For args to be an array, you must assign to it with an array assignment, such as



            args=( "$@" )


            To have the elements of the array individually quoted when you expand $args[@], you must double quote the expansion (just as with "$@"):



            echo git "$cmd" "$args[@]"


            In this simple example, the separate args array is not really needed at all:



            #!/bin/sh

            cmd=$1
            shift

            if [ "$cmd" = "bar" ]; then
            set -- --baz "$@"
            fi

            echo git "$cmd" "$@"


            Note that the quotes won't be outputted by the echo command above. But you can rest assured that echo gets exactly two arguments (git and $cmd) plus however many things are in $@ at that point. This is because the shell does quote removal on the command before executing it. You can compare this with what e.g. echo "one two" three outputs.



            A better way to output the the command for visual inspection would maybe be



            printf 'Arg: %sn' git "$cmd" "$@"


            This would print each separate argument to printf on its own line (prefixed by the string Arg:).



            Your git command, git "$cmd" "$@" (or git "$cmd" "$args[@]" if you use a separate array), would run correctly (given that the variables makes sense, ordinary git doesn't have a bar sub-command with a --baz option, for example).



            Related:



            • Why does my shell script choke on whitespace or other special characters?





            share|improve this answer


























              up vote
              7
              down vote













              When using "$args[@]" you assume that args is an array, but it's not.



              For args to be an array, you must assign to it with an array assignment, such as



              args=( "$@" )


              To have the elements of the array individually quoted when you expand $args[@], you must double quote the expansion (just as with "$@"):



              echo git "$cmd" "$args[@]"


              In this simple example, the separate args array is not really needed at all:



              #!/bin/sh

              cmd=$1
              shift

              if [ "$cmd" = "bar" ]; then
              set -- --baz "$@"
              fi

              echo git "$cmd" "$@"


              Note that the quotes won't be outputted by the echo command above. But you can rest assured that echo gets exactly two arguments (git and $cmd) plus however many things are in $@ at that point. This is because the shell does quote removal on the command before executing it. You can compare this with what e.g. echo "one two" three outputs.



              A better way to output the the command for visual inspection would maybe be



              printf 'Arg: %sn' git "$cmd" "$@"


              This would print each separate argument to printf on its own line (prefixed by the string Arg:).



              Your git command, git "$cmd" "$@" (or git "$cmd" "$args[@]" if you use a separate array), would run correctly (given that the variables makes sense, ordinary git doesn't have a bar sub-command with a --baz option, for example).



              Related:



              • Why does my shell script choke on whitespace or other special characters?





              share|improve this answer
























                up vote
                7
                down vote










                up vote
                7
                down vote









                When using "$args[@]" you assume that args is an array, but it's not.



                For args to be an array, you must assign to it with an array assignment, such as



                args=( "$@" )


                To have the elements of the array individually quoted when you expand $args[@], you must double quote the expansion (just as with "$@"):



                echo git "$cmd" "$args[@]"


                In this simple example, the separate args array is not really needed at all:



                #!/bin/sh

                cmd=$1
                shift

                if [ "$cmd" = "bar" ]; then
                set -- --baz "$@"
                fi

                echo git "$cmd" "$@"


                Note that the quotes won't be outputted by the echo command above. But you can rest assured that echo gets exactly two arguments (git and $cmd) plus however many things are in $@ at that point. This is because the shell does quote removal on the command before executing it. You can compare this with what e.g. echo "one two" three outputs.



                A better way to output the the command for visual inspection would maybe be



                printf 'Arg: %sn' git "$cmd" "$@"


                This would print each separate argument to printf on its own line (prefixed by the string Arg:).



                Your git command, git "$cmd" "$@" (or git "$cmd" "$args[@]" if you use a separate array), would run correctly (given that the variables makes sense, ordinary git doesn't have a bar sub-command with a --baz option, for example).



                Related:



                • Why does my shell script choke on whitespace or other special characters?





                share|improve this answer














                When using "$args[@]" you assume that args is an array, but it's not.



                For args to be an array, you must assign to it with an array assignment, such as



                args=( "$@" )


                To have the elements of the array individually quoted when you expand $args[@], you must double quote the expansion (just as with "$@"):



                echo git "$cmd" "$args[@]"


                In this simple example, the separate args array is not really needed at all:



                #!/bin/sh

                cmd=$1
                shift

                if [ "$cmd" = "bar" ]; then
                set -- --baz "$@"
                fi

                echo git "$cmd" "$@"


                Note that the quotes won't be outputted by the echo command above. But you can rest assured that echo gets exactly two arguments (git and $cmd) plus however many things are in $@ at that point. This is because the shell does quote removal on the command before executing it. You can compare this with what e.g. echo "one two" three outputs.



                A better way to output the the command for visual inspection would maybe be



                printf 'Arg: %sn' git "$cmd" "$@"


                This would print each separate argument to printf on its own line (prefixed by the string Arg:).



                Your git command, git "$cmd" "$@" (or git "$cmd" "$args[@]" if you use a separate array), would run correctly (given that the variables makes sense, ordinary git doesn't have a bar sub-command with a --baz option, for example).



                Related:



                • Why does my shell script choke on whitespace or other special characters?






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Oct 1 at 16:43

























                answered Oct 1 at 14:59









                Kusalananda

                108k14210333




                108k14210333




















                    Tomas Lycken is a new contributor. Be nice, and check out our Code of Conduct.









                     

                    draft saved


                    draft discarded


















                    Tomas Lycken is a new contributor. Be nice, and check out our Code of Conduct.












                    Tomas Lycken is a new contributor. Be nice, and check out our Code of Conduct.











                    Tomas Lycken is a new contributor. Be nice, and check out our Code of Conduct.













                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f472589%2fpass-to-command-preserving-quotes%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?