for loop folder list without expansion

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











up vote
2
down vote

favorite












I try to generate a command line for a backup script on bash shell.



Simple example:



EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*"; 
for FOLDER in $EXCLUDES; do printf -- '--exclude %bn' "$FOLDER" ; done


Should result in:



--exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'


But the problem is, that the folders get expanded from shell.
I did try many examples with echo / printf / quoting / IFS... but without the right result.



Any way to fix this?







share|improve this question























    up vote
    2
    down vote

    favorite












    I try to generate a command line for a backup script on bash shell.



    Simple example:



    EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*"; 
    for FOLDER in $EXCLUDES; do printf -- '--exclude %bn' "$FOLDER" ; done


    Should result in:



    --exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'


    But the problem is, that the folders get expanded from shell.
    I did try many examples with echo / printf / quoting / IFS... but without the right result.



    Any way to fix this?







    share|improve this question





















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I try to generate a command line for a backup script on bash shell.



      Simple example:



      EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*"; 
      for FOLDER in $EXCLUDES; do printf -- '--exclude %bn' "$FOLDER" ; done


      Should result in:



      --exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'


      But the problem is, that the folders get expanded from shell.
      I did try many examples with echo / printf / quoting / IFS... but without the right result.



      Any way to fix this?







      share|improve this question











      I try to generate a command line for a backup script on bash shell.



      Simple example:



      EXCLUDES="/home/*/.cache/* /var/cache/* /var/tmp/* /var/lib/lxcfs/cgroup/*"; 
      for FOLDER in $EXCLUDES; do printf -- '--exclude %bn' "$FOLDER" ; done


      Should result in:



      --exclude '/home/*/.cache/*' --exclude '/var/cache/*' --exclude '/var/tmp/*' --exclude '/var/lib/lxcfs/cgroup/*'


      But the problem is, that the folders get expanded from shell.
      I did try many examples with echo / printf / quoting / IFS... but without the right result.



      Any way to fix this?









      share|improve this question










      share|improve this question




      share|improve this question









      asked Jul 3 at 18:08









      Thomas

      344




      344




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          Whenever you have to specify a list of pathnames or pathnames with filename globs, or just generally a list that you are intending to loop over and/or use as a list of arguments to some command, use an array.



          If you don't use an array but a string, you will not be able to process things with spaces in them (because you use spaces as the delimiter in the string). It also makes it hard to loop over the contents of the string as you will have to invoke word splitting (by not quoting the variable expansion). But this will also cause filename globbing to happen, unless you explicitly turn this off with set -f.



          In most shells, even in plain /bin/sh, use an array instead. In sh, use the array of positional parameters ($@).



          For bash, use an array of quoted strings, like



          excludes=( '/home/*/.cache/*'
          '/var/cache/*'
          '/var/tmp/*'
          '/var/lib/lxcfs/cgroup/*' )


          Then,



          rsync_opts=( --verbose --archive )
          for excl in "$excludes[@]"; do
          rsync_opts+=( --exclude="$excl" )
          done


          Later,



          rsync "$rsync_opts[@]" source/ target


          Note that the quoting is important in all of the above variable expansions. The expansion "$array[@]" (as well as "$@" below) results in a list of individually quoted elements of the array in question (but only if double quoted!).



          For any /bin/sh shell:



          set -- '/home/*/.cache/*' 
          '/var/cache/*'
          '/var/tmp/*'
          '/var/lib/lxcfs/cgroup/*'

          for excl do
          set -- "$@" --exclude="$excl"
          shift
          done
          set -- --verbose --archive "$@"

          rsync "$@" source/ target





          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
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f453276%2ffor-loop-folder-list-without-expansion%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
            4
            down vote



            accepted










            Whenever you have to specify a list of pathnames or pathnames with filename globs, or just generally a list that you are intending to loop over and/or use as a list of arguments to some command, use an array.



            If you don't use an array but a string, you will not be able to process things with spaces in them (because you use spaces as the delimiter in the string). It also makes it hard to loop over the contents of the string as you will have to invoke word splitting (by not quoting the variable expansion). But this will also cause filename globbing to happen, unless you explicitly turn this off with set -f.



            In most shells, even in plain /bin/sh, use an array instead. In sh, use the array of positional parameters ($@).



            For bash, use an array of quoted strings, like



            excludes=( '/home/*/.cache/*'
            '/var/cache/*'
            '/var/tmp/*'
            '/var/lib/lxcfs/cgroup/*' )


            Then,



            rsync_opts=( --verbose --archive )
            for excl in "$excludes[@]"; do
            rsync_opts+=( --exclude="$excl" )
            done


            Later,



            rsync "$rsync_opts[@]" source/ target


            Note that the quoting is important in all of the above variable expansions. The expansion "$array[@]" (as well as "$@" below) results in a list of individually quoted elements of the array in question (but only if double quoted!).



            For any /bin/sh shell:



            set -- '/home/*/.cache/*' 
            '/var/cache/*'
            '/var/tmp/*'
            '/var/lib/lxcfs/cgroup/*'

            for excl do
            set -- "$@" --exclude="$excl"
            shift
            done
            set -- --verbose --archive "$@"

            rsync "$@" source/ target





            share|improve this answer



























              up vote
              4
              down vote



              accepted










              Whenever you have to specify a list of pathnames or pathnames with filename globs, or just generally a list that you are intending to loop over and/or use as a list of arguments to some command, use an array.



              If you don't use an array but a string, you will not be able to process things with spaces in them (because you use spaces as the delimiter in the string). It also makes it hard to loop over the contents of the string as you will have to invoke word splitting (by not quoting the variable expansion). But this will also cause filename globbing to happen, unless you explicitly turn this off with set -f.



              In most shells, even in plain /bin/sh, use an array instead. In sh, use the array of positional parameters ($@).



              For bash, use an array of quoted strings, like



              excludes=( '/home/*/.cache/*'
              '/var/cache/*'
              '/var/tmp/*'
              '/var/lib/lxcfs/cgroup/*' )


              Then,



              rsync_opts=( --verbose --archive )
              for excl in "$excludes[@]"; do
              rsync_opts+=( --exclude="$excl" )
              done


              Later,



              rsync "$rsync_opts[@]" source/ target


              Note that the quoting is important in all of the above variable expansions. The expansion "$array[@]" (as well as "$@" below) results in a list of individually quoted elements of the array in question (but only if double quoted!).



              For any /bin/sh shell:



              set -- '/home/*/.cache/*' 
              '/var/cache/*'
              '/var/tmp/*'
              '/var/lib/lxcfs/cgroup/*'

              for excl do
              set -- "$@" --exclude="$excl"
              shift
              done
              set -- --verbose --archive "$@"

              rsync "$@" source/ target





              share|improve this answer

























                up vote
                4
                down vote



                accepted







                up vote
                4
                down vote



                accepted






                Whenever you have to specify a list of pathnames or pathnames with filename globs, or just generally a list that you are intending to loop over and/or use as a list of arguments to some command, use an array.



                If you don't use an array but a string, you will not be able to process things with spaces in them (because you use spaces as the delimiter in the string). It also makes it hard to loop over the contents of the string as you will have to invoke word splitting (by not quoting the variable expansion). But this will also cause filename globbing to happen, unless you explicitly turn this off with set -f.



                In most shells, even in plain /bin/sh, use an array instead. In sh, use the array of positional parameters ($@).



                For bash, use an array of quoted strings, like



                excludes=( '/home/*/.cache/*'
                '/var/cache/*'
                '/var/tmp/*'
                '/var/lib/lxcfs/cgroup/*' )


                Then,



                rsync_opts=( --verbose --archive )
                for excl in "$excludes[@]"; do
                rsync_opts+=( --exclude="$excl" )
                done


                Later,



                rsync "$rsync_opts[@]" source/ target


                Note that the quoting is important in all of the above variable expansions. The expansion "$array[@]" (as well as "$@" below) results in a list of individually quoted elements of the array in question (but only if double quoted!).



                For any /bin/sh shell:



                set -- '/home/*/.cache/*' 
                '/var/cache/*'
                '/var/tmp/*'
                '/var/lib/lxcfs/cgroup/*'

                for excl do
                set -- "$@" --exclude="$excl"
                shift
                done
                set -- --verbose --archive "$@"

                rsync "$@" source/ target





                share|improve this answer















                Whenever you have to specify a list of pathnames or pathnames with filename globs, or just generally a list that you are intending to loop over and/or use as a list of arguments to some command, use an array.



                If you don't use an array but a string, you will not be able to process things with spaces in them (because you use spaces as the delimiter in the string). It also makes it hard to loop over the contents of the string as you will have to invoke word splitting (by not quoting the variable expansion). But this will also cause filename globbing to happen, unless you explicitly turn this off with set -f.



                In most shells, even in plain /bin/sh, use an array instead. In sh, use the array of positional parameters ($@).



                For bash, use an array of quoted strings, like



                excludes=( '/home/*/.cache/*'
                '/var/cache/*'
                '/var/tmp/*'
                '/var/lib/lxcfs/cgroup/*' )


                Then,



                rsync_opts=( --verbose --archive )
                for excl in "$excludes[@]"; do
                rsync_opts+=( --exclude="$excl" )
                done


                Later,



                rsync "$rsync_opts[@]" source/ target


                Note that the quoting is important in all of the above variable expansions. The expansion "$array[@]" (as well as "$@" below) results in a list of individually quoted elements of the array in question (but only if double quoted!).



                For any /bin/sh shell:



                set -- '/home/*/.cache/*' 
                '/var/cache/*'
                '/var/tmp/*'
                '/var/lib/lxcfs/cgroup/*'

                for excl do
                set -- "$@" --exclude="$excl"
                shift
                done
                set -- --verbose --archive "$@"

                rsync "$@" source/ target






                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jul 3 at 18:43


























                answered Jul 3 at 18:22









                Kusalananda

                101k13199312




                101k13199312






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f453276%2ffor-loop-folder-list-without-expansion%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?