Dosya adlarını alıntılamak `xargs sudo rm -rf` yi çalıştırmak için yeterli güvenlik mi?


10

Bir klasördeki son iki dosya hariç tüm dosyaları silen bir komut dosyası yazdım:

#!/bin/bash
ls -1 --quoting-style=shell-always /path/to/some/folder \
    | head -n -2 \
    | xargs printf -- "'/path/to/some/folder/%s'\n" \
    | xargs sudo rm -rf

Bu script her gün bir cron işi olarak yürütülecek.

Akıl yürütme aşağıdaki gibidir:

  1. Kullanarak tüm dosyaların bir listesini elde ls -1(böylece satır başına bir dosya almak);

  2. Kullanarak son iki listeden çıkarın head -n -2;

  3. Yana lsbaskılar göreli yollar kullanmak xargs printfklasör yolunu başa ekleyerek şeyi ve mutlak bir yol yapmak;

  4. Onları sudo rm -rfkullanarak gönderin xargs.

Herkesin bu klasöre erişimi vardır, böylece herkes bu klasördeki dosyaları oluşturabilir ve silebilir.

Sorun şudur: sudo rm -rf korkutucu. xargs sudo rm -rfinanılmaz derecede korkutucu.

Silinecek akıllı dosyalar (yanlışlıkla veya bilerek) oluşturarak kimsenin diğer klasörlere / sistemlere zarar veremeyeceğinden emin olmak istiyorum. Bilmiyorum, zekice bir şey:

file with / spaces.txt

bu da çok korkutucu olabilir sudo rm -rf /.

EDIT: Benim hatam, dosya adları içeremez /, bu nedenle bu özel sorun olmaz, ancak başka riskler olup olmadığı sorusu hala duruyor.

Bu yüzden kullanıyorum --quoting-style=shell-always, bu boşluklu dosyaları olan hileleri önlemelidir. Ama şimdi birisinin dosya adındaki boşluklarla ve alıntılarla ekstra zeki olup olmadığını merak ediyorum .

Senaryom güvenli mi?


Not: sudoKlasöre uzaktan eriştiğim için kullanıyorum (kullanarak bir eşlenen ağ sürücüsünden mount) ve sudo olmadan çalışamadım.


3
Gibi bir şey yapmayı düşündün mü printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm?
steeldriver


3
@ Hayır Hayır, dosya adı eğik çizgi içeremez.
wjandrea

OP akıllı bir kişi dediğinde merak ediyordum ...
George Udosen

6
lsÇıktıyı ayrıştırdığınız için bu, alıntıda bile zaten kötü yazılmış bir komuttur. lsAyrıca, sıralama düzeni için yerel ayarı da kullanır, bu yüzden headson 2'yi kaldırmanın amacının ne olduğunu görmüyorum (kurtulmaya çalışmadığınız .ve ..iirc'in rmzaten argüman olarak izin verilmediği sürece find /path/to/folder -type f delete. hayır sudocron koşmak - cron zaten kök düzeyinde
Sergiy Kolodyazhnyy

Yanıtlar:


10

Linux'ta, herhangi bir karakter, aşağıdakiler haricinde geçerli bir dosya adı karakteridir:

  • \0 (ASCII NUL): C dilinde dize sonlandırması için kullanılır
  • / (eğik çizgi): yol ayrımı için kullanıldığı gibi

Öyleyse, yaklaşımınız birçok durumda kesinlikle işe yaramayacaktır, örneğin \ndosya adında bir newline ( ) işliyor mu? ( İpucu: Hayır ).

Birkaç not:

  • Ayrıştırma ls; özel araçlar kullanın (çoğu kullanım durumunda en az bir tane vardır)
  • Dosya adlarıyla uğraşırken, bu tür verilerle çalışan hemen hemen tüm GNU araçları tarafından sağlanan NUL ayrılmış çıktıdan yararlanmaya çalışın
  • Boruları döşerken dikkatli olun, her iki programın da NUL ayrımlarını anlayabildiğinden emin olun
  • Ne zaman çağırırsanız xargs, kaçabileceğinizi görün find ... -exec; çoğu durumda, findyalnız başına iyi olacaksın

Sanırım bunlar şimdilik seni devam ettirecek. steeldriver zaten açıklama ( printf -- '%s\0' /path/to/some/folder/* | head -zn -2 | xargs -0 rm) NUL ayrılmış fikir sağladı, bunu bir başlangıç ​​noktası olarak kullanın.


Cevabınız için teşekkürler :) Sanırım sadece bahsetmek yerine steeldriver'ın yorumunu yapmanız gerektiğini düşünüyorum (yorumlar kalıcı olmadığından). Ben de bir göz atacağım find, öneri için teşekkürler.
Pedro A

Yine de bir sorum var: "Yaklaşımınız pek çok durumda kesinlikle işe yaramayacaktır," - "güvenli değil" ya da "güvensiz değil" gibi hayal bile edemeyeceğinizi anlamıyorum. Çünkü "yaklaşımınız" kötü niyetli kullanıcıya değil, bana atıfta bulunur ve önceki ifadelerin benim lehime olduğunu, bu yüzden kafam karıştı.
Pedro A

@PedroA Sen sensin :) Dediğim gibi, belirtilen iki dışında tüm karakterler geçerli olduğundan, lsayrıştırma yaklaşımınızın başarısız olacağı sayısız durumu hayal edebilmelisiniz, örneğin dosya adında yeni bir satırı hesaba kattınız mı?
heemayl

Dosya adında yeni bir satır ... Bunu hiç düşünmemiştim. Bunu da cevabınıza eklemek istemiyorsanız :) Ayrıca, sormak için üzgünüm, ama ne yapar head -z? Saçma gelebilir ama yok manne de infobenim CoreOS konteyner linux ... ya internette bulunamadı. Anladımhead: invalid option 'z'
Pedro A

Newline sadece bir durum, tahmin edebileceğiniz gibi birçok şey var . GNU'ya ihtiyacınız var head(GNU ile birlikte geliyor coreutils). İşte çevrimiçi sürümü: manpages.ubuntu.com/manpages/xenial/man1/head.1.html
heemayl

3

xargs bazı alıntıları destekler: tek tırnak, çift tırnak veya ters eğik çizgiyle rastgele argümanları kabul etmesini sağlar, ancak Bourne benzeri kabukların alıntı sözdiziminden farklı bir sözdizimiyle.

lsUbuntu'da bulunanın GNU uygulamasında , xargsgiriş biçimiyle uyumlu herhangi bir teklif modu yoktur .

Onun ls --quoting-style=shell-alwayssözdizimi alıntı ksh93, bash ve zsh kabukları ile uyumludur, ancak sadece çıktısı, çıktısıyla lsaynı yerde kabuk tarafından yorumlandığında ls. Ayrıca, BIG5, BIG5-HKSCS, GBK veya GB18030 kullananlar gibi bazı yerel ayarlardan da kaçınılmalıdır.

Yani bu mermilerle, aslında şunları yapabilirsiniz:

typeset -a files
eval "files=($(ls --quoting-style=shell-always))"
xargs -r0a <(printf '%s\0' "${files[@]:0:3}") ...

Ancak bunun çok az avantajı vardır:

files=(*(N))                 # zsh
files=(~(N)*)                # ksh93
shopt -s nullglob; files=(*) # bash

Yararlı olduğu tek durum , dosyaları mtime / atime / ctime veya / öğesine göre sıralamak -tseçeneğini kullanmak istediğiniz lszamandır . Ama o zaman bile, 's:-S-Vzsh

files=(*(Nom))

örneğin dosyaları mtime'a göre sıralamak için ( oLiçin -Sve niçin kullanın -V).

En son değiştirilen iki normal dosyayı hariç tümünü kaldırmak için:

rm -f -- *(D.om[3,-1])

Still hala bazı uzunluk sınırlamaları vardır ( execve()bazı GNU olmayan xargsuygulamalarda ve daha düşük keyfi olanlar) ve bazı GNU olmayan xargsuygulamalar, geçerli karakterler oluşturmayan bayt dizileri içeren girdi boğacaktır.

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.