!(notThisDir)の正しい出力は何ですか? 1つを除くすべてのディレクトリのコピー

!(notThisDir)の正しい出力は何ですか? 1つを除くすべてのディレクトリのコピー

1つのファイルのみを残してすべてをコピーするには:私は通常式!(noThisFile)(passable 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を..明示的に無視するようにパターンを拡張できます。つまり、隠しandを使用できます。...!(.git|.|..)GLOBIGNORE...

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

GLOBIGNORE(null以外の値に設定するとsumは無視さ.れますが、..作る dotglob.)

または、ドットファイルを表示したくない場合は、そのdotglobファイルが無効になっていることを確認してから、*明示的な除外なしでを使用してください.git

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

Zshも.setを..使用している場合でもglobdotskshスタイルを使用するか、または!(.git)Zsh自体^.gitまたは*~.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を設定して.:..拡張を避けてください。...

関連情報