这是以下的输出tree
:
[xyz@localhost Semester1]$ tree
.
├── Eng
├── IT
├── IT_workshop
├── LA
├── OS
├── OS_lab
├── Psy
├── Python
└── Python_lab
9 directories, 0 files
我想在每个目录中使用touch
.
我尝试了这个命令:
[xyz@localhost Semester1]$ touch */{credits,links,notes}
这是输出:
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
为什么该命令没有按照我的预期工作?
顺便说一句,我使用的是 CentOS Linux 7。
答案1
问题是*/
shell 在启动命令之前扩展了 glob(这是一个 glob)。并且大括号扩展发生在全局之前。这意味着,*/{credits,links,notes}
然后'*/credits' '*/links' '*/notes'
这些 glob 由 shell 扩展,并且由于文件尚未创建,因此 glob 会扩展为自身。
对于任何不匹配任何内容的 glob,您都可以看到相同的行为。例如:
$ echo a*j
a*j
当它匹配时:
$ touch abj
$ echo a*j
abj
回到您的情况,因为这些文件实际上并不存在,所以您运行的命令变为:
touch '*/credits' '*/links' '*/notes'
如果您创建其中之一,您会看到事情发生了变化:
$ 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
由于我们现在有一个与 glob 匹配的文件*/credits
,即 file Psy/credits
,因此该文件可以工作,但其他两个会出错。
做你正在尝试的事情的正确方法是这样的:
for d in */; do touch "$d"/{credits,links,notes}; done
结果是:
$ 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