!(notThisDir) 的正确输出是什么?复制除一个目录之外的所有目录

!(notThisDir) 的正确输出是什么?复制除一个目录之外的所有目录

为了复制除一个文件之外的所有文件:我通常使用表达式!(noThisFile)(可通过shopt -s extglob)。

在当前情况下,我想避免的是.git目录。令人惊讶的是我尝试过:

cp -r !(.git) my-target-dir

../但它也完全复制了目录的内容

事实上,当我

echo !(.git) 

输出开始于:

. .. myDir myDir2 myFile myFile2 

我不记得使用时复制时遇到过这样的问题当我检查文件名时,输出中!(notthisfile) 没有. ..

  • !(.avoidingDir)对于我的系统来说,还应该同时返回.和,这是否正确..
  • 如果是正确的,我应该怎样做才能避免这个问题?

答案1

这实际上有点有趣,因为至少 Bash 4.4 似乎也使用这种模式扩展到点文件,即使dotglob没有生效。也许模式中的前导.足以将它们带入,即使它位于否定之内。

如果正确与否,您必须询问 Bash 开发人员。它可能不应该这样做,因为在 Bash 5.0 中它不这样做。 (但如果dotglob设置了,您仍然可以获得所有点文件,包括...。)

要获取除.git, .and之外的所有内容..,您可以扩展模式以显式忽略.and ..,即!(.git|.|..),或使用GLOBIGNORE隐藏.and ..

$ mkdir .git .dot dir
$ echo !(.git|.|..)
dir .dot
$ GLOBIGNORE=.:..
$ echo !(.git)
dir .dot

(仅设置GLOBIGNORE为任何非空值都会忽略...,但也会使 dotglob.)

或者,如果您不想看到任何点文件,请确保dotglob已禁用,然后只需使用*,无需显式排除.git

$ unset GLOBIGNORE
$ shopt -u dotglob
$ echo *
dir

Zsh 也不会拉入.and ..,即使使用globdotsset,无论是使用 ksh 风格的!(.git)还是使用 Zsh 自己的^.gitor *~.git

答案2

答案是:视情况而定。

如果 GLOBIGNORE 未设置,则 glob(任何 glob)都将匹配点文件bash 选项 dotglob 已设置:

$ mkdir test; cd test; touch .git .one .two file myfile; \
  mkdir .dir .new dir here

test $ ls -a 
.  ..  .dir  dir  here  .new  file  .git  myfile  .one  .two

test $ unset GLOBIGNORE; shopt -s dotglob; echo *
.dir dir file .git here myfile .new .one .two

test $ unset GLOBIGNORE; shopt -u dotglob; echo *
dir file here myfile

test $ unset GLOBIGNORE; shopt -u dotglob; echo .*
. .. .dir .git .new .one .two

因此,如果未设置 dotglob,则点文件将被忽略。.*例如,除非明确包含上述内容。

请注意,即使设置了,.也必须显式匹配。..dotglob

关于!(.git)

但是,是的,“!(.git)”(与任何带有起始点的东西一样)会触发“.”和“..”以及所有点文件的匹配。
shopt -u dotglob; echo !(.a); shopt -s dotglob; echo !(.a)
dir file here myfile
. .. .dir dir file .git here myfile .new .one .two

您可以通过设置 GLOBIGNORE 来避免包含.和。..请记住,设置GLOBIGNORE也会设置dotglob,取消设置GLOBIGNORE也会取消设置dotglob

test $ shopt -u dotglob; GLOBIGNORE="."; shopt -p dotglob; echo !(.a)
shopt -s dotglob
.dir dir file .git here myfile .new .one .two

test $ shopt -s dotglob; unset GLOBIGNORE; shopt -p dotglob; echo !(.a)   
shopt -u dotglob
dir file here myfile

因此,作为解决方法,请将 GLOBIGNORE 设置为以避免和.:..的扩展。...

相关内容