Dosyayı kaldırın, ancak yalnızca bir simge bağlantısı varsa


11

İdeal olarak böyle bir komut istiyorum

rm --only-if-symlink link-to-file

çünkü dosyayı işaret eden sembolik bağlantı yerine yanlışlıkla dosyayı sildim. Bu özellikle sudo söz konusu olduğunda kötü olabilir. Şimdi tabii ki ls -algerçekten bir symlink ve böyle emin olmak için yapmak ama bu operatör hatası (benzer şekilde adlandırılmış dosya, yazım hatası, vb) ve yarış koşulları (eğer birisi bir nedenle bir dosyayı silmemi istiyorsa) savunmasız. Bir dosyanın bir sembolik bağlantı olup olmadığını kontrol etmenin ve yalnızca bir komutta olması durumunda silmenin bir yolu var mı?


1
Yarış koşulunun bir endişe olması gerektiğini düşünmüyorum. Symlink'i kaldırabilecek ve bir dosya ile değiştirebilecek herkes, dizinde yazma iznine ihtiyaç duyacaktır, bu da dosyayı kendileri de silebilecekleri anlamına gelir.
Nate Eldredge

Yanıtlar:


19
 $ rm_if_link(){ [ ! -L "$1" ] || rm -v "$1"; }

 #test
 $ touch nonlink; ln -s link
 $ rm_if_link nonlink
 $ rm_if_link link
   removed 'link'     

4
Şüphesiz kaldırmak için daha net olacağını !ve değişim ||için&&
Glenn Jackman

5
@glennjackman ||Formu tercih etmeyi alışkanlık haline getirdim . &&Eğer set -emoddaysanız işleri yıkar.
PSkocik

@PSkocik İlginç bir durum (dosya var ve bir sembolik bağlantı) ve [ ! -L $1 ]geçersiz bir işleç ( [ ! -l foo ]), hatta sözdizimi hatası ( [ ! -q foo || echo foo)
l0b0 21:16

2
@XiongChiamiov Sorun rm_if_link(){ [ -L "$1" ] && rm -v "$1"; }şu ki, bir bağlantısız set -e modda çalıştırılması kabuk işleminizi öldürecektir. Sen eklemek olabilir || :ama sonra, daha az net IMHO olur ! ||sürümü ve bir önleyecektir rmsizi öldürmesini başarısızlık set -eolasılığı istenmeyen bir durumdur. ! ||oldukça özlü ve açıktır ve bu sorunların hiçbirinden muzdarip değildir.
PSkocik

1
Hayır . Diğer seçenekler: a) rmtestinizin içine koyun , b) gerçek bir if ifadesi kullanın, c) -eetkileşimli kabukların içinde dolaşmayın (ve senaryolarınızı test edin!). Okunabilirlik hakkında tartışmak istiyorsanız if, bir şeyin bir bağlantı olup olmadığını test etmek için kullanmak oldukça kazanır.
Monica Cellio için Boycott SE

5

Kullanabilirsiniz findve -type ltest koşulu (bulunan nesnenin l mürekkep olup olmadığını görmek için test eder )

Örneğin foo, geçerli dizinde çağrılan bir dosyanız varsa, bunu yapabilirsiniz:

$ find . -type l -iname "foo" -delete

Bunu aşağıdakilerle basitleştirebilirsiniz:

$ find . -maxdepth 1 -type l -delete

Bu, geçerli dizindeki tüm simgeleri silecektir.

Uyarı:

Bu -deleteseçenek findgerçekten çok tehlikelidir. BULMA KOMUTUNUN SONUNDA YERLEŞTİRDİĞİNİZDEN EMİN OLUN. Yanlış yerleştirirseniz, sonuçların koşulunuza uyup uymadığına bakılmaksızın bulduğu her şeyi siler.

Yorumlarda önerildiği gibi, daha güvenli bir seçenek kullanmak olabilir findve rm -i(sizi dosya kaldırmayı onaylamaya zorlar) birlikte:

$ $ find . -type l -iname "foo" | xargs rm -i

Şahsen -exec trash {} \;dosyaları geçici olarak silmek için kullanıyorum çünkü kendiniz gibi rmgeçmişte yanmıştım . Double yanlış yerleştirilmiş bir -deletebayrağa gider .

http://slackermedia.ml/trashy


1
-Delete yerine sadece yazdırabilir ve xargs'a iletebilirsiniz: find . -type l -iname "foo" | xargs rm -i daha güvenlidir.
Boban P.

1
Eminim@BobanP.'nin rm -igüvenlik için kullanımını seviyorum .
Klaatu von Schlacker

3
"Bu, geçerli dizindeki tüm simgeleri silecektir" ... ve altındaki herhangi bir noktayı silecektir.
Joseph

1
@JosephR olarak. dedi, tüm yol boyunca gidecek. Bulmak için -maksupde 1 ekleyin.
Boban P.

1
Hala boşluklu dosya adlarını bozuyor. -print0İçin findve -0için kullanmanızı öneririz xargs.
Wildcard

4
zsh -c 'rm foo(@)'

@bir glob niteleyicisidir ; desen foo(@)eşleşenlerle fooeşleşir, sadece sembolik bağlarla eşleşir.

foo(-@)yalnızca bozuk sembolik bağlantılarla eşleşir. foo(@,L0)yalnızca sembolik bağlantılar ve boş dosyalarla eşleşir.

Tabii ki, ilk etapta zsh çalıştırıyorsanız, sadece yazmanız gerekir rm foo(@). EnterYazmadan önce basmamaya dikkat etmeniz gerekir (@).


1
Bunun gibi cevaplar gördüğümde Zsh giderek daha güçlü geliyor.
Jeff Schaller
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.