Tüm sembolik bağları, bağlandıkları dosyayla değiştirmenin kolay bir yolu var mı?
Tüm sembolik bağları, bağlandıkları dosyayla değiştirmenin kolay bir yolu var mı?
Yanıtlar:
"Easy" un bazı tanımları için:
#!/bin/sh
set -e
for link; do
test -h "$link" || continue
dir=$(dirname "$link")
reltarget=$(readlink "$link")
case $reltarget in
/*) abstarget=$reltarget;;
*) abstarget=$dir/$reltarget;;
esac
rm -fv "$link"
cp -afv "$abstarget" "$link" || {
# on failure, restore the symlink
rm -rfv "$link"
ln -sfv "$reltarget" "$link"
}
done
Bu betiği argümanlar olarak link isimleriyle, örneğin find . -type l -exec /path/tos/script {} +
"$var"için "${var}"sh / bash bir noop olduğunu. Bir bashism'i kaldırdım ( [[), gerisi POSIX sh ile uyumlu.
cp, aynı dizindeki mv -fgeçici bir dosyaya, ardından bu geçici dosyayı orijinal haline getirmektir. Bu insanlar basılı gibi sorunlar karşı korumak gerekir Ctrl-Cveya dosya sistemi arasındaki dolduruyor rmve cp(böylece bile yeni engelleyen komutlar lnçalışmasını). Geçici dosya isimleri ls -a, gerektiğinde daha sonra temizlenmeleri için kolayca anlaşılabilir.
abstarget=$(readlink -f "$link")yerine neden kullanmadığımı hatırlayamıyorum , ancak taşınabilirlik sebepleri olabilirdi.
Verileri yeni bir dizine kopyalamak için sadece tar kullanmak daha kolay olabilir.
-H (c and r mode only) Symbolic links named on the command line will be followed; the target of the link will be archived, not the link itself.
Böyle bir şey kullanabilirsin
tar -hcf - sourcedir | tar -xf - -C newdir
tar --help:
-H, --format=FORMAT create archive of the given format
-h, --dereference follow symlinks; archive and dump the files they point to
tar -hcf - sourcedir | tar -xf - -C newdir
cp -Lbasit bir çözümdür
cpuygulamalar dizinleri kopyalayamaz.
Eğer seni doğru anladıysam -L, cpkomutun bayrağı tam olarak istediğini yapmalıydı.
Sadece tüm sembolik linkleri kopyalayın, işaret ettikleri dosyalarla değiştirin.
cp -L files tmp/ && rm files && cp tmp/files . Eğer
"Kolay", büyük olasılıkla bir işlevi olacaktır.
Muhtemelen sembolik olarak bağlantılı dosyaları bulmak için "find" komut satırı yardımcı programını kullanan bir komut dosyası yazardım, sonra dosyayı kaldırmak ve değiştirmek için rm ve cp'yi çağırır. Ayrıca, sym linkini de hareket ettirmeden önce yeterli boş alan olup olmadığını kontrol ederek find eyleminin çağrılması için de iyi iş çıkarırsınız.
Başka bir çözüm, söz konusu dosya sistemini, sym linklerini gizleyen bir şey (samba gibi) üzerine monte etmek olabilir, ardından sadece her şeyi kopyalayın. Ancak birçok durumda, bunun gibi bir şey diğer sorunları da beraberinde getirir.
Sorunuza daha doğrudan bir cevap muhtemelen "evet" dir.
Düzenleme: Daha spesifik bilgi isteğine göre Bulunacak man sayfasına göre , bu komut tüm sym link dosyalarını / dizininde 2 dizin derinliğinde listeleyecektir:
find / -maxdepth 2 -type l -print
Bulmak için bir şeyi yürütmek üzere bulmak için:
find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;
Yeni oluşturduğum komut dosyasını arayacağına ve yeni bulduğun dosya adını gireceğine inanıyorum. Alternatif olarak, dosyaya bulma çıktısını yakalayabilir ("find [blah]> symlinks.data", vb. Kullanın), ardından bu dosyayı orijinal bir şekilde zarifçe kopyalamayı işlemek için yazdığınız bir komut dosyasına geçirin.
-exec ./ReplaceSymLink.sh {} \;
Bu, kullandığım oneliner: tüm yerel dosyaların "kaynak" içerisindeki başka bir dosyaya bağlantılar olduğunu varsayalım. Dosya seçimini desenlerle daraltabilir veya "bul". Lütfen kullanmadan önce anlayın.
f * için; cp --remove-hedef kaynak / $ f $ f; tamam
Bu yardımcı olur umarım
find . -type l -exec cp --dereference --recursive '{}' '{}'.dereferenced \;
Bağlantılı her dosya / klasörün bir kopyasını oluşturacaktır <filename>.dereferenced, bu sadece doğrudan değiştirmekten daha güvenlidir (daha az uygunsa). Kopyalanan verileri sembolik bağlantıların dosya adlarına taşımak, okuyucunun alıştırması olarak bırakılmıştır.
find ./ -type l -print0|xargs -0 -n1 -i sh -c 'cp --remove-destination $(readlink "{}") "{}" '
dayalı /superuser//a/1301199/499386 MastroGeppetto arasında
Orada çok iyi cevaplar var ama ben kolay bir şey aradığından beri
for i in *; do link=$(readlink $i) && rm $i && mv $link $i; done
Normalde bağlantıyı takip edip dosyayı kopyalamayı beklediğinizde gwenview bağlantılarını kopyalarken de aynı sorunu yaşadım.
Tüm bağlantıları izleyerek ve tüm sivri dosyaları dizine kopyalayarak dizini 'temizlemek' için yaptığım, örneğin
"for file in `ls`; do cp -L $file scratchdir/$file; done; mv scratchdir/* ./"
Bu bir komut dosyası koymak için çok tehlikeli çünkü kontrol yok ama sorunumu düzeltti.
for f in *; do cp --remove-destination $(readlink "$f") "$f"; done
Tek satırlı bir sürüm yaptım, çünkü web sitem bash scriptlerine izin vermedi ve benim için iyi çalıştı:
before:
> find . -type l | wc -l
358
> for link in `find . -type l` ; do echo "$link : "; ls -al $link ; cp $link notalink; unlink $link; mv notalink $link ; ls -al $link; done
...
after:
> find . -type l | wc -l
0