1

When using brace expansion with certain commands, the actual behavior differed from what I expected- a member within the brace was evaluated as an argument in the other brace member's expansion.

For instance,

$ mkdir -p {folder1,folder2,folder3}/{folderA,folderB,folderC}

Works as expected -

$ tree .
    .
    ├── folder1
    │   ├── folderA
    │   ├── folderB
    │   └── folderC
    ├── folder2
    │   ├── folderA
    │   ├── folderB
    │   └── folderC
    └── folder3
        ├── folderA
        ├── folderB
        └── folderC

However, if we do

$ cp -r folder1/  folder2/{folderA,folderB}

Instead of folder1 being copied to both folder2/folderA and folder2/folderB, 'folderA' is interpreted as a second source. Thus we get -

.
├── folder1
│   ├── folderA
│   ├── folderB
│   └── folderC
├── folder2
│   ├── folderA
│   ├── folderB
│   │   ├── folder1
│   │   │   ├── folderA
│   │   │   ├── folderB
│   │   │   └── folderC
│   │   └── folderA
│   └── folderC
└── folder3
    ├── folderA
    ├── folderB
    └── folderC

Can anyone explain why this is the case? I would have thought the above to be evaluated as -

$ cp -r folder1/ folder2/folderA
$ cp -r folder1/ folder2/folderB
Jay
  • 19
  • 1
  • 1
    `cp` supports one or more sources but only one target; there are several workarounds (eg, see the answers in this [Q&A](https://askubuntu.com/q/432795) – markp-fuso Aug 24 '22 at 21:54

1 Answers1

2

Brace expansion doesn't result in multiple commands, it's just expanded in place in the original command. So the result is

cp -r folder1/ folder2/folderA folder2/folderB

When you get more than 2 arguments to cp, the last is the destination folder, the rest are source files and folders.

If you want multiple commands, you can use an explicit loop:

for dest in folder2/{folderA,folderB}; do
    cp -r folder1/ "$dest"
done
Barmar
  • 741,623
  • 53
  • 500
  • 612