简体   繁体   中英

Bash brace expansion - operand behavior

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM