web-dev-qa-db-ja.com

`command。*`は親ディレクトリに作用します

私たちのチームの誰かが、ユーザーのホームディレクトリにあるすべての非表示ディレクトリのユーザー権限を再帰的に変更したいと考えていました。そのために、彼は次のコマンドを実行しました。

cd /home/username
chown -R username:groupname .*

.*..と等しいため、/ home内のすべてのユーザーディレクトリのアクセス許可を実際に再帰的に変更したことを知ったとき、私たちはかなり驚きました。 Linuxでこの動作を期待しましたか?

22
g000ze

何かのために。*を使用しようとすると、常にやけどを負い、ずっと前に文字クラスの使用に切り替えました。

chown -R username.groupname .[A-Za-z]*

私がこれをした方法です。

編集:._Libraryなどのドットファイルなど、これが得られないことを誰かが指摘しました。使用するすべての文字クラスをキャッチします

chown -R username.groupname .[A-Za-z0-9_-]*
17
pgoetz

文字.がワイルドカード一致から除外されるのは、それがファイル名の最初の文字であり、ワイルドカードによって一致する場合のみです。 .*パターンでは、*.で始まる文字列に一致するため、.*には..が含まれます(.*が空の文字列に一致します)。これはパターンマッチングルールの単純な結果であり、迷惑な場合もあります。

例外を作成し、...を体系的に一致から除外することは理にかなっていますが、これは歴史的にそうではなかったため、多くのBourne/POSIXシェル(shdashbash、AT&T kshyash…)(t)cshやfish 1.xと同様に、それらを含めます。いくつかのシェルは、すべてのワイルドカード一致から.および..を除外します:zsh、pdksh/posh/mksh(AT&T kshとは異なります)、fish ≥2.

GLOBIGNOREを空でない任意の値に設定すると、bashは、...を除外するという便利でありながら非標準的な動作に切り替わります一致します。 GLOBIGNOREを設定すると、ドットファイルを除外する動作もオフになります。 GLOBIGNORE='.*'を使用すると、ドットファイルを除く./*の通常の動作が得られますが、./.*はドットファイルのみに一致し、.または..には一致しません。 GLOBIGNORE=.:..(またはGLOBIGNORE=.)を設定して、./*がドットファイルを含め、...を除くすべてのファイルと一致するようにします。

Ksh93では、FIGNORE='@(.|..)'を設定して、.および..を一致から除外し、ドットファイルを含めます。したがって、.*はドットファイルに展開されますが、.または..は含まれません。

シェル固有の機能に頼ることなく、ドットファイルを次の2つのグロブと照合できます。

.[!.]* ..?*

および次の3つのグロブを持つすべてのファイル(.および..を除く):

..?* .[!.]* *

ただし、1つまたは複数のグロブがどのファイルとも一致しない可能性があるため、対応するパターンが展開されないままになるため、注意が必要です。

驚きを避けるために、findを使用する方が簡単な場合があります。 findは親ディレクトリに再帰しません(シンボリックリンクをたどるように指示されない限り)。

find /home/username/. -name . -o -Prune -name '.*' -exec chown -R username:groupname {} +

拡張グロビング(shopt -s extglob)、使用できます

.!(.|)

つまり、ドットの後にドットがない、または何もない。

10
choroba

find-maxdepthはPOSIX以外の拡張機能ですが、Linuxですぐに利用できるはずです)。

find . -maxdepth 1 -type d -name '.*' -exec chown -R user:group {} +
6
Chris Down

ディレクトリ自体がファイルと同じ所有権を共有している場合(非表示かどうかにかかわらず)、代わりに再帰的にchownできます。 -Rオプションは、現在のディレクトリ内で再帰するときに隠しファイルを含めます。

$ chown user:group . -R # Will include all hidden files
6
John WH Smith

具体的には、代わりにls -Aを使用できると思います。

chown -R username:groupname $(ls -A | grep '^\.')

これは、.*が期待することを実行し、..を除く、..で始まる現在のディレクトリ内のすべてのファイルと一致します。 ただし、スペースを含むファイルなど、ファンキーなファイル名と一致させる必要がある場合、これはbashグロブと同じように動作しないことに注意してください。

1
dimo414

非表示のディレクトリのみをフィルタリングし、-Rオプションを削除するChris Downソリューションのバリエーション。本来の要件は、隠しディレクトリの所有権とグループ分類を変更することであり、その内容を変更することではありませんでした。

find /home/username -maxdepth 1 -type d -name '.*' -exec chown user:group {} +
0
fd0