Kilitli dosyaları içeren büyük bir dizinde grup sahibi nasıl değiştirilir


1

Grup sahibini tüm dizinde değiştirme komutu şöyledir:

chgrp -R newgroup dir_name

Örneğin:

chgrp -R staff .

Ancak kilitli dosyalar veya dizinler dir_nameiçerdiğinde , bu komut aşağıdakilerle başarısız olur:

chgrp -R staff .
chgrp: ./file.txt: Operation not permitted

Komutu süper kullanıcı ayrıcalıklarıyla çalıştırırsanız, başarısız da olur:

/usr/bin/sudo chgrp -R staff .
Password:
chgrp: ./file.txt: Operation not permitted

Kilitlenen dosya sayısı azsa, komutun kullanılması yoluyla el ile geçici bir çözüm vardır chflags.

Belirli uchgbir kilitlenmiş dosyayla ilişkili belirli bir bayrak ( ) olup olmadığını kontrol edin :

ls -@delO file.txt 
-rw-r--r--  1 bob  staff  uchg 32 Aug  8 11:38 file.txt

uchgBayrağı geçici olarak kaldırın :

chflags nouchg file.txt

Tekrarlayan bir şekilde grubu değiştirin:

chgrp -R admin .

İlk uchgbayrağını sıfırla :

chflags uchg file.txt

Ancak bu yöntem, yüzlerce kilitli dosyanın bulunduğu büyük bir dizin yapısına uyum sağlayamaz. Bu makbuz hiç ölçeklenmiyor.


Bu kilitli durumu korurken, kilitli dosyaları içeren tüm dizin yapısının grup sahibini değiştirmek için temel basit yöntem nedir?

Aynı sorun, kilitli dosyaları içeren dizinleri yönetmek için birçok komutla ortaya çıkar, ancak burada pratik ve basit bir duruma odaklandım.

Yanıtlar:


1

Aşağıdaki Ben oluşturarak sorunu gidermek için nasıl kullanıldığını açıklayan bir örnek sarıcı komut dosyası için chgrp komut bir üzerine hareket etmek , hedef dizinde bir sorunla karşılaştığınız kilitli dosyaları .

Bir kullanarak bash komut dosyası adını chgrpld, bunu aynı komut satırı argümanları (geçerdi seçenekleri , işlenen ve dizin ı yürütme olsaydı) chgrpbir üzerinde dizine . Benim adlandırma kuralı harfler eklemek için basitçe unutmayın ldtemsil kendisine kilitli dizini bunun üzerinde çalışır o, dizinleri vardır kilitli ve ya içeren, ya da değil dosya / dizinleri vardır kilitli de. Normalde nerede kullanacağımı, örneğin bir dizinichgrp -R staff foo nerede kullanacağımı . senaryofoochgrpld -R staff fooAyrıca , kilitli olmayan ve kilitli bir dosya sistemi nesnesi içermeyen bir dizinde çalışmak üzere kodlanmıştır ; bu nedenle , kilitli bir dosya sistemi nesnelerini kontrol etmek istemiyorsam, bir dizini hedeflerken düzenli bir yedek olarak kullanılmasına izin verir. önce ya da önce başarısız olsaydın, yine de kullanmak zorundasın .chgrpldchgrpchgrpchgrpld

Not: Bu komut dosyası , sınırlı test koşullarında çalışmak için yeterli miktarda sınırlı hata denetimi kullanır. O değil IMO ilk etapta oraya ait olmayan bir dosya sistemi nesne adına gömülü yeni satır işlemek için kodlanmış! İhtiyaç duyduğunuzda / ihtiyaçlarınızı karşılamak istediğinizde, istediğiniz zaman / istendiğinde ilave hata kontrolü ekleyerek değişiklik yapmaktan çekinmeyin.

Test ortamı, aşağıdaki listede gösterildiği gibi geçici bir dizinde OS X 10.11.5 idi , her biri bir dosyada ve kilitli dosyalardan birinde iki dizin var . Bir dizin / dosya kümesi içindedir grubun diğer grubu ise gruptaki ve ben olmak için her şeyi isteyen kulüpler grubunda . (Ek test bilgileri için bkz. Cevap sonunda Test Notu.)admin staff staff

Terminal çıkışı şunları gösterir:

  • Bir özyinelemeli dizin listesi.
  • chgrpHata çıktısını gösteren bir deneme girişimi .
  • Kullanımı chgrpld, hatasız çalıştırılması.
  • Başka bir özyinelemeli dizin listesi, grubun değiştiğini göstermek için .

$ ls -lRO
total 0
drwxr-xr-x  3 user  staff  - 102 Aug  9 2:00 bar
drwxr-xr-x  3 user  admin  - 102 Aug  9 2:00 foo

./bar:
total 0
-rw-r--r--  1 user  staff  - 0 Aug  9 2:00 foo

./foo:
total 0
-rw-r--r--  1 user  admin  uchg 0 Aug  9 2:00 bar
$ chgrp -R staff foo
chgrp: foo/bar: Operation not permitted
$ chgrpld -R staff foo
$ ls -lRO
total 0
drwxr-xr-x  3 user  staff  - 102 Aug  9 2:00 bar
drwxr-xr-x  3 user  staff  - 102 Aug  9 2:00 foo

./bar:
total 0
-rw-r--r--  1 user  staff  - 0 Aug  9 2:00 foo

./foo:
total 0
-rw-r--r--  1 user  staff  uchg 0 Aug  9 2:00 bar
$ 

chgrpld Bash betiğini oluşturmak ve komut isteminde hazır bulundurmak için :

Terminalde:

  • Yazıp touch chgrpldtuşuna basın enter.
  • Yazıp open chgrpldtuşuna basın enter.

Tarayıcıdan:

  • Aşağıdaki kodu kopyalayıp yapıştırın, açılan chgrplddosyaya kaydedin ve kaydedin, ardından dosyayı kapatın.

Geri Terminalde:

  • Yazıp chmod +x chgrpldtuşuna basın enter.
  • Yazıp sudo mkdir -p /usr/local/bintuşuna basın enter. Temiz bir OS X 10.11.5 kurulumunda, bindizinin içinde /usr/localolmasına rağmen bulunmadığını unutmayın PATH.
    • Yazın şifreyi basın enter.
  • Yazıp sudo cp chgrpld /usr/local/bintuşuna basın enter.
    • Yazın şifreyi basın enter. (Eğer gerekliyse.)
  • chgrpldŞimdi sadece chgrp komut gibi, kullanılabilir olması gerekir .

Kaynak kodu için chgrpld:

#!/bin/bash

o="${@:1:$(($#-1))}"
d="${@: -1}"
if [ -d "$d" ]; then
    f=".locked_files_list_$(date "+%s")"
    find "$d" -flags uchg > "$f" 2>/dev/null
    if [ -s "$f" ]; then
        while read -r l; do
            chflags nouchg "$l"
        done<"$f"
            $(chgrp $o "$d")
        while read -r l; do
            chflags uchg "$l"
        done<"$f"
        rm "$f"
    else
        rm "$f"
        $(chgrp $o "$d")
    fi
else
    echo "  \"$d\" is not a directory!..."
    exit 1
fi
exit 0

Özet: chgrpld [−fhv][−R[−H | −L | −P]] group directory

  • Seçeneklerin ve işleneninman chgrp açıklaması için Terminal'e bakınız .group

  • directoryolan ad / yol adı hedef ait dizinde olduğu kilitli , ya da değil, ve ya içeren dosyalar / dizinleri vardır kilitli de. chgrpHangi nesnenin , örneğin group file ...üzerinde hareket etmesine izin verdiğinin aksine , bir seferde chgrpldbir hedef dizinde ve tekrarlı olarak -R seçenekle hareket etmek üzere kodlandığına dikkat edin .

  • Not: Kullanıcı yürütmesini chgrpld belirtilen ait olmalıdır grubun ve olmayacak sahibi bir dizinde ve kilitli dosya sistemi nesneleri veya olmak süper kullanıcı .

  • İşletim sisteminin SIP sürümlerinde beklendiği gibi, SIP etkinse , SIP korumalı dosya sistemi nesneleri üzerinde çalışmaz .


Aşağıdaki resimde bir sözdizimsel vurgulama gösterir kod hakkında biraz açıklamak için daha kolay okuma için aralıklı ve girintili yorumlarla kod yapıyor.

Kod görüntüsü


Sınama Notu: Yukarıda gösterilen sınama ortamı yine de sınırlı olmasına rağmen, daha çok kilitli yuvalanmış dizin ve dosyalarla, boşluk içeren adlarla ve dosya adı içinde ters eğik çizgiler olmadan, daha karmaşık bir hiyerarşik dizin yapısı altında test ettim. Açıkçası gösteri amaçlı olarak, sadece konsept kanıtı için çıplak bir minimum yapı gösteriyorum. Yukarıda belirtildiği gibi, yine " O değil IMO ilk etapta oraya ait olmayan bir dosya sistemi nesne, adına gömülü bir yeni satır işlemek için kodlanmış! ".


Basit ve temiz kod! Newlines hakkında sınırlama uyarısı için güzel;).
dan

Ya "dosya" hidden,uchgya da gibi birden fazla bayrak varsa schg,uchg? Senaryonuzda güzel yorum.
fd0

@ fd0, Kilitli olan dosya sistemi nesnesinin senaryosunu kapsayan ve " İstediğiniz şekilde değişiklik yapmaktan çekinmeyin " senaryosunu içeren " Aşağıdaki, sorunu nasıl çözeceğimin bir örneğidir" demiştim . ihtiyaçlar aynı anda kilitli ve gizli olan kapaklar ". Sunmuş olduğum şey, şablon olarak kullanılacak bir geçici çözüm sarmalayıcı komut dosyasının bir örneğidir. Evet, uchg,hiddenbayraklar için bir kontrol eklemek ve işlem yapmak istiyorsanız, yapmak kolaydır. Kod yorumlamadaki tamamlayıcı için teşekkürler, 6 ay sonra tekrar bakmak istiyorum. ve ne ve neden böyle yazdığımı bil. :)
user3439894

@ fd0, boşta Meraktan kökü olarak ran bir program yazdım ve katma son ve oldukça temiz, birkaç kullanıcı programlarında Flags analiz, OS X 10.11.5 kurulumu ve sadece tek 1 dosya vardı uchgbayrağı seti ve 0 ile uchg,hiddenayarlanmış. Ancak, burada belirlenen her bireyin ve birleştirilmiş Bayrakların toplamı: 35270 sıkıştırılmış; 80 gizli; 242946 sınırlı; 268419 sınırlı, sıkıştırılmış; 20 kısıtlı, gizli; 3 kısıtlı, sunlnk; 1 sınırlı, uchg; 467 güneşten; 6 gün battı, gizli; 1 uchg. Biliyorum hiddendurduramaz chgrpdüzgün yürütülmesini, diğerlerini test etmedim.
user3439894

Öyle görünüyor ki, hiddenya da bu konuda compressed, opaque, nodump, archivebir dosyayı değiştirmeyi etkileyebilir.
fd0

0

2 mermi çözümü

Sonunda birçok denemeden sonra 2 kısa kabuk script çözümü oluşturdum.

Yapacak oldukça basit olan:

chflags, chgrp, chflags

Dizin yapısı geçişi yapacak daha ciddi bir tane:

find ... do the chgrp correctly

Küçük kabuk: chflags, chgrp, chflags

İşte chgrpld1.shtipik olarak içeriği tam olarak 2 argümanla bulunarak çağrılacak olan içerik .

#!/bin/sh
# shell script to chgrp a file or directory
# when there exists a lock flags (uchg)

_cn=`basename $0`

USAGE="Usage: ${_cn} group file"

case $# in
2)
        _group=$1
        _file="$2"
        ;;
*)
        echo "$USAGE" >&2
        exit 2
        ;;
esac

chflags nouchg "${_file}"
chgrp ${_group} "${_file}"
chflags uchg "${_file}"

Büyük kabuk: bulmak ... chgrp doğru yapmak

İçeriği chgrpld.sh, dizin yapıları üzerinde bir keşif yürütecek ve mümkün olduğu kadar önceden hata koşullarından kaçınacaktır.

#!/bin/sh
# shell script to recursively chgrp a file or directory
# when there exists files which are locked

_cn=`basename $0`

USAGE="Usage: ${_cn} group file..."

case $# in
0|1)
        echo "$USAGE" >&2
        exit 2
        ;;
*)
        _group=$1
        shift
        _file_list="$@"
        ;;
esac

TMPDIR=/tmp
_file_flags_list=`mktemp -t ${_cn}`

clean() { rm -f ${_file_flags_list} ; }

trap clean 0 1 2 3

# first check if we don't have any sort of flags thus blocking this
# script

find "${_file_list}" -flags +sappnd,schg,uappend -exec ls -@delO "{}" \; >${_file_flags_list}

if [ -s ${_file_flags_list} ] ; then
        echo "${_cn}: can't run because of other flags set:"
        cat ${_file_flags_list}
        exit 1
fi

# if flag present then call chgrpld1, else plain chgrp

find "${_file_list}" \( -flags uchg -exec chgrpld1 ${_group} "{}" \; \) -or \( -exec chgrp ${_group} "{}" \; \)

Yüklemek

Bu 2 kabuğu birlikte çalıştırmak için, her ikisini de içindeki yerel bir dizine yüklemek gerekir PATH. Benim durumumda /local/binPATH bileşenlerinin dışında ve paket yöneticileri tarafından kullanılanların dışında kalıyorum ( port, brew…).

Seçili dizindeki öncül 2 dosyayı kopyalayın:

chgrpld1.sh
chgrpld.sh

make chgrpld1 chgrpld

cp chgrpld1 chgrpld /local/bin

Ölçek

Her durumda bu kabuğun doğru çalıştığını doğrulamak için, bir hata olmadan başa çıkması gereken tüm imkansız dosya adlarıyla karşılaşılabilecek tüm bayrak kombinasyonlarını içeren bir test dizini hazırladım.

dir-okbetiğimde başarılı olması gereken dehşetleri içeren alt dizin, dir-failüzerinde başarısız olması gereken tüm durumu içeren dizindir:

% ls -blOR
total 0
drwxr-xr-x  2 bob  admin          - 204 Aug 16 16:50 dir-fail
drwxr-xr-x  3 bob  localaccounts  - 238 Aug 16 16:55 dir-ok

./dir-fail:
total 0
-rw-r--r--  1 bob  admin  schg,uchg 0 Aug  9 18:59 file-multi-flags
-rw-r--r--  1 bob  admin  sappnd    0 Aug 16 16:13 file-sappnd
-rw-r--r--  1 bob  admin  schg      0 Aug 16 16:11 file-schg
-rw-r--r--  1 bob  admin  uappnd    0 Aug 16 16:12 file-uappend

./dir-ok:
total 0
-rw-r--r--  1 bob  localaccounts  -      0 Aug 16 16:07 a\nb
-rw-r--r--  1 bob  localaccounts  -      0 Aug  9 19:34 a b
-rw-r--r--  1 bob  localaccounts  -      0 Aug  9 19:34 a'b
-rw-r--r--  1 bob  localaccounts  -      0 Aug 16 16:46 a\\b
drwxr-xr-x  2 bob  localaccounts  uchg 272 Aug 16 16:39 subdir

./dir-ok/subdir:
total 0
-rw-r--r--  1 bob  localaccounts  -      0 Aug 16 16:08 file
-rw-r--r--  1 bob  localaccounts  arch   0 Aug 16 16:12 file-arch
-rw-r--r--@ 1 bob  localaccounts  hidden 0 Aug 16 16:10 file-hidden
-rw-r--r--  1 bob  localaccounts  nodump 0 Aug 16 16:11 file-nodump
-rw-r--r--  1 bob  localaccounts  opaque 0 Aug 16 16:10 file-opaque
-rw-r--r--  1 bob  localaccounts  uchg   0 Aug 16 16:08 file-uchg
  • A doğru koş dir-ok

    $ chgrpld staff dir-ok
    $ ls -blOR dir-ok
    total 0
    -rw-r--r--  1 bob  staff  -      0 Aug 16 16:07 a\nb
    -rw-r--r--  1 bob  staff  -      0 Aug  9 19:34 a b
    -rw-r--r--  1 bob  staff  -      0 Aug  9 19:34 a'b
    -rw-r--r--  1 bob  staff  -      0 Aug 16 16:46 a\\b
    drwxr-xr-x  2 bob  staff  uchg 272 Aug 16 16:39 subdir
    
    dir-ok/subdir:
    total 0
    -rw-r--r--  1 bob  staff  -      0 Aug 16 16:08 file
    -rw-r--r--  1 bob  staff  arch   0 Aug 16 16:12 file-arch
    -rw-r--r--@ 1 bob  staff  hidden 0 Aug 16 16:10 file-hidden
    -rw-r--r--  1 bob  staff  nodump 0 Aug 16 16:11 file-nodump
    -rw-r--r--  1 bob  staff  opaque 0 Aug 16 16:10 file-opaque
    -rw-r--r--  1 bob  staff  uchg   0 Aug 16 16:08 file-uchg
    $
  • A doğru koş dir-fail

    $ chgrpld staff dir-fail/file-multi-flags 
    chgrpld: can't run because of other flags set:
    -rw-r--r--  1 bob  admin  schg,uchg 0 Aug  9 18:59 dir-fail/file-multi-flags
    
    $ chgrpld staff dir-fail/file-sappnd      
    chgrpld: can't run because of other flags set:
    -rw-r--r--  1 bob  admin  sappnd 0 Aug 16 16:13 dir-fail/file-sappnd
    
    $ chgrpld staff dir-fail/file-schg  
    chgrpld: can't run because of other flags set:
    -rw-r--r--  1 bob  admin  schg 0 Aug 16 16:11 dir-fail/file-schg
    
    $ chgrpld staff dir-fail/file-uappend
    chgrpld: can't run because of other flags set:
    -rw-r--r--  1 bob  admin  uappnd 0 Aug 16 16:12 dir-fail/file-uappend
    $
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.