3

This is the output of tree:

[xyz@localhost Semester1]$ tree
.
├── Eng
├── IT
├── IT_workshop
├── LA
├── OS
├── OS_lab
├── Psy
├── Python
└── Python_lab

9 directories, 0 files

I want to create 3 common files (named credits, links and notes) in each of these directories using touch.

I tried this command:

[xyz@localhost Semester1]$ touch */{credits,links,notes}

and this was the output:

touch: cannot touch ‘*/credits’: No such file or directory
touch: cannot touch ‘*/links’: No such file or directory
touch: cannot touch ‘*/notes’: No such file or directory

Why did the command not work as I expected it to?

BTW, I'm using CentOS Linux 7.

1 Answers1

4

The problem is that globs (the */ is a glob) are expanded by the shell before launching the command. And brace expansions happen before globs. What this means is that */{credits,links,notes} becomes '*/credits' '*/links' '*/notes' and then these globs are expanded by the shell, and because the files haven't been created yet, the globs are expanded to themselves.

You can see the same behavior with any glob that doesn't match anything. For example:

$ echo a*j
a*j

While when it does match:

$ touch abj
$ echo a*j
abj

Coming back to your case, because the files don't actually exist, the command you are running becomes:

touch '*/credits' '*/links' '*/notes'

If you create one of them, you can see that things change:

$ touch Psy/credits
$ touch */{credits,links,notes}
touch: cannot touch '*/links': No such file or directory
touch: cannot touch '*/notes': No such file or directory

Since we now have one file that does match the */credits glob, the file Psy/credits, that one works but the other two give errors.

The right way to do what you are attempting is something like this:

for d in */; do touch "$d"/{credits,links,notes}; done

Which results in:

$ tree
.
├── abj
├── Eng
│   ├── credits
│   ├── links
│   └── notes
├── IT
│   ├── credits
│   ├── links
│   └── notes
├── IT_workshop
│   ├── credits
│   ├── links
│   └── notes
├── LA
│   ├── credits
│   ├── links
│   └── notes
├── OS
│   ├── credits
│   ├── links
│   └── notes
├── OS_lab
│   ├── credits
│   ├── links
│   └── notes
├── Psy
│   ├── credits
│   ├── links
│   └── notes
├── Python
│   ├── credits
│   ├── links
│   └── notes
└── Python_lab
    ├── credits
    ├── links
    └── notes
ilkkachu
  • 138,973
terdon
  • 242,166
  • @ilkkachu Are the quotes mandatory? What's the difference between having and not having quotes? – Random Person Nov 04 '22 at 17:35
  • @RandomPerson, they would be necessary if any of the dirs had a space in the name. See https://unix.stackexchange.com/q/131766/170373 – ilkkachu Nov 04 '22 at 17:38