'Rm -rf' से सुरक्षित निर्देशिका बनाना


9

मैंने फ़ोल्डर A में कुछ डेटा खो दिया है जो करने के बाद फ़ोल्डर B के अंदर था rm -rf B। इससे पहले कि मैं महसूस कर पाता कि मैंने क्या किया है, यह सब खत्म हो गया था। अब एक सबक सीखा गया है, मैं अगली बार से बचने के लिए अपने कुछ फ़ोल्डर को बेवकूफ-सबूत बनाना चाहता हूं जब मैं कुछ ऐसा ही करता हूं और खुद को मारना चाहता हूं।

एक तरह से मैं यह सोच सकता हूं कि एक बैश फंक्शन लिखना है और इसे उर्फ ​​करना है rm। यह फ़ंक्शन प्रत्येक उप-फ़ोल्डर में छिपी हुई फ़ाइल के लिए दिखेगा .dontdelete। जब मिला, यह पूछेगा कि क्या मैं वास्तव में जारी रखना चाहता हूं। मैं नहीं लिख सकता हूं क्योंकि एक प्रक्रिया है जो इस फ़ोल्डर में लगातार लिखती है। क्या इसे करने का कोई बेहतर तरीका है?


2
क्या आपने उर्फ rmको rm -iहटाने की कोशिश की :> -मैं हर हटाने से पहले या> -मैं एक बार में तीन से अधिक फ़ाइलों को हटाने से पहले या तुरंत हटाने पर। कम घुसपैठ से -आई, जबकि अभी भी सबसे गलतियों के खिलाफ सुरक्षा दे आप किसी भी समय अन्य झंडों के साथ उन पर अधिकार कर सकते हैं।
IBr

2
बाहर की जाँच करेंsafe-rm
sr_

इसे करने के लगभग एक दर्जन तरीके हैं। आपको अपने पर्यावरण के बारे में और विस्तार से जाने की आवश्यकता है।
इग्नासियो वाज़केज़-अब्राम्स


एक अन्य विचार यह है कि इसे एक फ़ंक्शन के लिए उर्फ ​​करें जो इसे केवल एक विशेष फ़ोल्डर में ले जाता है और फिर एक क्रोनजॉब tmpwatchबनाता है जो हर घंटे इस फ़ोल्डर से फ़ाइलों को हटाने के लिए चलता है।
ब्राचली

जवाबों:


14

आपके प्रश्न पर शोध करने में मुझे इस तकनीक का पता चला, जो भविष्य में आपकी मदद कर सकती है।

आप स्पष्ट रूप से निर्देशिका में किसी फ़ाइल को छू सकते हैं जैसे:

touch -- -i

अब जब आप rm -fr *एक डायरेक्टरी में कमांड चलाते हैं, जहां -iमौजूद है तो आपको इंटरेक्टिव प्रॉम्प्ट से प्रस्तुत किया जाएगा rm

$ ls
file1  file2  file3  file4  file5  -i

$ rm -fr *
rm: remove regular empty file `file1'? n
rm: remove regular empty file `file2'? n
rm: remove regular empty file `file3'? n
rm: remove regular empty file `file4'? n
rm: remove regular empty file `file5'? n

एक ही बात rmहमेशा के लिए जगह में एक उपनाम छोड़ कर प्राप्त किया जा सकता है rm -i। इससे गुस्सा आ सकता है। इसलिए अक्सर मैंने जो किया है, वह इस उपनाम को जगह में रखना है, और फिर इसे अक्षम करने के लिए जब आप वास्तव में संकेत दिए बिना हटाना चाहते हैं।

alias rm='rm -i'

अब निर्देशिका में आपको इस तरह से बधाई दी जाएगी:

$ ls
file1  file2  file3  file4  file5

$ rm -r *
rm: remove regular empty file `file1'?

उपनाम को ओवरराइड करने के लिए:

$ \rm -r *

यह अभी भी एक बंद नहीं करता है rm -fr। लेकिन यह आपको कुछ सुरक्षा प्रदान करता है।

संदर्भ


1
यह एक अच्छा, सुरुचिपूर्ण समाधान है जो अच्छी तरह से काम करता है यदि आप केवल निर्देशिकाओं के एक छोटे समूह की रक्षा करना चाहते हैं। और मैं पुराने जमाने का हो सकता हूं लेकिन मैं अभी भी इस धारणा के तहत जी रहा हूं कि अगर आप --forceकिसी चीज के लिए कहते हैं, तो आप वास्तव में इसका मतलब निकालते हैं।
बजे एक सीवी

यह भी ध्यान दें कि rm -I(ऊपरी मामला i) एक उपनाम में उपयोगी हो सकता है, क्योंकि यह थोड़ा कम दखल है (मैन पेज के अनुसार, केवल संकेत देता है कि आप तीन से अधिक फ़ाइलों को हटा दें या पुनरावर्ती रूप से)।
एक सीवी

ध्यान दें कि touch ./-iट्रिक केवल GNU के साथ काम करती है rmऔर केवल तभी जब POSIXLY_CORRECT वैरिएबल सेट नहीं किया जाता है (POSIX कमांड तर्क के बाद विकल्पों को नहीं पहचानती)।
स्टीफन चेजलस

5

कई संभावनाएं:

  • alias rm='rm -i'- आरएम पूछेंगे - जब तक आप निर्दिष्ट नहीं करते -f...
  • chmod -w dir - सीधे उस निर्देशिका में फ़ाइलों की सुरक्षा करता है।
  • chattr +i यदि आप वास्तव में इसका मतलब है
  • rm के चारों ओर अपना स्वयं का आवरण लिखें
  • आदि...

लेकिन एक बेहतर तरीका शायद एक अच्छा बैकअप होना और महत्वपूर्ण डेटा को किसी प्रकार के संस्करण नियंत्रण (जैसे git) में रखना है , जो बहुत सारे अन्य फायदे भी लाता है।


1
इसका उल्लेख करने के लिए यहां आया हूं। मैं इसे पूरी तरह से सुरक्षित बनाने के लिए chattr + i का सुझाव दूंगा।
जेडेओला

मैंने पहले ही rm अलियास कर दिया है, rm -iलेकिन जैसा कि कोई अपेक्षा करेगा, यह -fविकल्प के साथ काम नहीं करता है। मैं कई अन्य उद्देश्य के लिए git का उपयोग करता हूं, लेकिन क्या होगा अगर मैं गलती rm -rf *से git में भी करूं?
दिलावर

गिट के साथ, यदि आप सिर्फ एक उपनिर्देशिका निकालते हैं तो आप इसे आसानी से अपने स्थानीय भंडार से पुनर्स्थापित कर सकते हैं। यदि आप पूरी रिपॉजिटरी को हटा देते हैं तो आप इसे फिर से क्लोन कर सकते हैं - इससे पहले कि आप इसे किसी अन्य स्थान पर धकेल दें।
माइकल

1

एक संस्करण नियंत्रण सॉफ़्टवेयर का उपयोग करें जैसे gitअपनी परियोजनाओं को एनकैप्सुलेट करना।

जब तक आप एक पूरी परियोजना को नहीं हटाते हैं, तब तक आपको निर्देशिका rm -rf .*को हटाने .gitऔर रोलबैक के लिए आवश्यक सभी डेटा खोने के लिए उद्देश्यपूर्ण रूप से टाइप करना होगा ।

इसका अतिरिक्त लाभ यह है कि आप अपने सामान के बैकअप को एक दूरस्थ सर्वर जैसे github या bitbucket पर धकेल सकते हैं।


1

यहां बताया गया है कि कैसे rm -rf dirकाम करता है:

  1. यह खुलता है dir, और इसकी सामग्री को सूचीबद्ध करता है।
  2. प्रत्येक प्रविष्टि के लिए, यदि यह एक निर्देशिका है, तो इसके लिए उसी प्रक्रिया को दोहराएं, यदि यह नहीं है, तो उस unlinkपर कॉल करें ।

यदि आप निर्देशिका सूचीकरण के लिए, पहले एक विशेष फ़ाइल नाम लौटा सकते हैं, और यदि आप unlinkमरने के लिए उस फ़ाइल पर एक प्रक्रिया कर सकते हैं , तो समस्या का समाधान होगा। यह एक फ्यूज फाइलसिस्टम का उपयोग करके किया जा सकता है।

उदाहरण के लिए, आप पर्ल फ्यूज मॉड्यूल से loopback.plउदाहरण को अनुकूलित कर सकते हैं जो सिर्फ एक डमी फाइल सिस्टम को लागू करता है जो कि केवल एक पास-थ्रू एक वास्तविक फ़ाइल सिस्टम के नीचे से गुजरता है (इसलिए नीचे भी देखें):

  • निर्देशिका को सूचीबद्ध करते समय, यदि इसमें एक प्रविष्टि नाम है .{{do-not-delete}}., तो दो फ़ाइलों के साथ प्रविष्टियों की सूची को प्रस्तुत करें: .{{do-not-delete}}!errorऔर.{{do-not-delete}}!kill
  • unlinkपहले एक के लिए प्रयास करते समय , EPERMकोड वापस करें ताकि rmएक त्रुटि संदेश प्रदर्शित हो
  • जब unlinkदूसरे के लिए कोशिश कर रहा है , तो प्रक्रिया मार दी जाती है।

$ ls -Ff dir/test
./  .{{do-not-delete}}.  foo/  ../  bar
$ ./rm-rf-killer dir
$ ls -Ff dir/test
.{{do-not-delete}}!error  .{{do-not-delete}}!kill  ./  .{{do-not-delete}}.   foo/  ../  bar
$ rm -rf dir/test
rm: cannot remove `dir/test/.{{do-not-delete}}!error': Operation not permitted
zsh: terminated  rm -rf dir/test
$ ls -Ff dir/test
.{{do-not-delete}}!error  .{{do-not-delete}}!kill  ./  .{{do-not-delete}}.   foo/  ../  bar

अवधारणा के प्रमाण के रूप में उस loopback.plउदाहरण के शीर्ष पर लागू करने के लिए एक पैच :

--- loopback.pl 2013-06-03 22:35:00.577316063 +0100
+++ rm-rf-killer    2013-06-03 22:33:41.523328427 +0100
@@ -7,2 +7,4 @@
 my $has_threads = 0;
+my $flag = ".{{do-not-delete}}";
+
 eval {
@@ -42,3 +44,4 @@

-use blib;
+#use blib;
+use File::Basename;
 use Fuse;
@@ -49,3 +52,3 @@

-my %extraopts = ( 'threaded' => 0, 'debug' => 0 );
+my %extraopts = ( 'threaded' => 0, 'debug' => 0, 'mountopts' => 'nonempty' );
 my($use_real_statfs, $pidfile);
@@ -64,3 +67,7 @@

-sub fixup { return "/tmp/fusetest-" . $ENV{LOGNAME} . shift }
+sub fixup {
+    my $f = shift;
+    $f =~ s#(/\Q$flag\E)!(error|kill)$#$1.#s;
+    return ".$f";
+}

@@ -78,3 +85,9 @@
 }
-    my (@files) = readdir(DIRHANDLE);
+    my @files;
+    
+    while (my $f = readdir(DIRHANDLE)) {
+        unshift @files, "$flag!error", "$flag!kill"
+            if ($f eq "$flag.");
+        push @files, $f;
+    }
 closedir(DIRHANDLE);
@@ -121,3 +134,12 @@
 sub x_readlink { return readlink(fixup(shift));         }
-sub x_unlink   { return unlink(fixup(shift)) ? 0 : -$!; }
+sub x_unlink   {
+    my $f = shift;
+    if (basename($f) eq "$flag!error") {return -EPERM()}
+    if (basename($f) eq "$flag!kill") {
+        my $caller_pid = Fuse::fuse_get_context()->{"pid"};
+        kill("TERM", $caller_pid);
+        return -EPERM();
+    }
+    return unlink(".$f") ? 0 : -$!;
+}

@@ -203,3 +225,2 @@
 sub daemonize {
-    chdir("/") || die "can't chdir to /: $!";
 open(STDIN, "< /dev/null") || die "can't read /dev/null: $!";
@@ -236,2 +257,3 @@

+chdir($mountpoint) or die("chdir: $!");
 daemonize();
@@ -239,3 +261,3 @@
 Fuse::main(
-    'mountpoint'    => $mountpoint,
+    'mountpoint'    => '.',
 'getattr'       => 'main::x_getattr',

-1

मैंने इस काम को आसान बनाने के लिए एक स्क्रिप्ट बनाई है। शेल स्क्रिप्ट रूट पासवर्ड पूछे बिना इंटरेक्टली फ़ोल्डरों की दी गई सूची को पढ़ने / लिखने की अनुमति और चैटट्रेट ध्वज को संशोधित करता है। आप नीचे दी गई लिंक से जिप फाइल को डाउनलोड कर सकते हैं।

https://drive.google.com/file/d/0B_3UYBZy2FVsMVpBSWdSWnFBYk0/edit?usp=sharing

मैंने सेटअप को आसान बनाने के लिए इंस्टॉलेशन स्क्रिप्ट को भी शामिल किया है। निर्देश ज़िप फ़ाइल में संलग्न हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.