गलती से एक पाइप के बजाय आउटपुट पुनर्निर्देशन का उपयोग किया


21

एक महीने पहले मैंने स्टड से मैक और आईपी पते को मैप करने के लिए पायथन स्क्रिप्ट लिखी थी। और दो दिन पहले मैंने इसे याद किया और आउटपुट को फ़िल्टर करने के लिए इस्तेमाल किया tcpdumpलेकिन यह एक टाइपो के कारण गलत हो गया। मैंने लिखा

tcpdump -ne > ./mac_ip.py

और आउटपुट कुछ भी नहीं है। लेकिन आउटपुट "अज्ञात" होना चाहिए यदि यह इनपुट को पार्स नहीं कर सकता है, तो मैंने प्रोग्राम के बजाय cat ./mac_ip.pyसभी tcpdumpडेटा किया और पाया । तब मुझे एहसास हुआ कि मुझे इसका इस्तेमाल करना चाहिए

tcpdump -ne | ./mac_ip.py

क्या मेरे कार्यक्रम को वापस लेने का कोई तरीका है? वैसे भी मैं अपने कार्यक्रम को फिर से लिख सकता हूं, लेकिन अगर यह अधिक महत्वपूर्ण कार्यक्रम के साथ फिर से होता है तो मुझे कुछ करने में सक्षम होना चाहिए। या फ़ाइल को जांचने के लिए आउटपुट पुनर्निर्देशन को बताने का कोई तरीका है और यह एक निष्पादन योग्य है या नहीं?


18
आप अपने प्रोग्राम को अपने बैकअप से पहले अंतिम बैकअप से वापस पा सकते हैं, अन्यथा नहीं। खोल में BTW आप निर्दिष्ट कर सकते हैं set -o noglobberऔर बैश अब मौजूदा फ़ाइलों में पुनर्निर्देशित नहीं करेंगे। विवरण के लिए यहाँ देखें: cyberciti.biz/tips/howto-keep-file-safe-from-overwriting.html
eckes

12
आपको महत्वपूर्ण निष्पादनों की अनुमति नहीं लिखनी चाहिए ...
हेगन वॉन एटिजन

20
@ ऐक्सset -o noclobber
GnP

38
@HagenvonEitzen मुझे इस तरह से नफरत है, जैसे कि आपने हर एक-बंद शेल और अजगर स्क्रिप्ट पर उचित स्वामित्व और अनुमतियाँ सेट की हैं, जिसे आपने इसे चलाने से पहले लिखा है (और, निश्चित रूप से, फिर से संक्षेप में अगर आपको इसे संपादित करना है )। यह "आप का >मतलब होने पर टाइप नहीं करना चाहिए" की तुलना में केवल थोड़ा अधिक सार्थक है |। वास्तविकता को मत भूलना।
जेसन सी

30
Git repos सस्ते हैं। अपने सभी कोड को कम करें, चाहे कितना भी छोटा और अर्थहीन हो और फिर इस तरह की गलती एक त्वरित और आसान फिक्स है।
केसी

जवाबों:


22

दुख की बात है कि मुझे संदेह है कि आपको इसे फिर से लिखना होगा। (यदि आपके पास बैकअप है, तो उन्हें बाहर निकालने का समय है। यदि नहीं, तो मैं आपको भविष्य के लिए एक बैकअप शासन स्थापित करने की जोरदार सलाह दूंगा। बहुत सारे विकल्प उपलब्ध हैं, लेकिन इस उत्तर के लिए विषय बंद करें।)

मुझे लगता है कि निष्पादक को एक अलग निर्देशिका में रखना, और उस निर्देशिका को जोड़ना PATHसहायक है। इस तरह मुझे स्पष्ट पथ द्वारा निष्पादकों को संदर्भित करने की आवश्यकता नहीं है। व्यक्तिगत (निजी) लिपियों के लिए मेरी पसंदीदा कार्यक्रम निर्देशिका है "$HOME"/binऔर इसे प्रोग्राम खोज पथ के साथ जोड़ा जा सकता है PATH="$HOME/bin:$PATH"। आमतौर पर इसे शेल स्टार्टअप स्क्रिप्ट .bash_profileऔर / या में जोड़ा जाएगा .bashrc

अंत में, सभी निष्पादन योग्य कार्यक्रमों पर अपने लिए लिखने की अनुमति को हटाने से आपको कोई रोक नहीं है:

touch some_executable.py
chmod a+x,a-w some_executable.py    # chmod 555, if you prefer

ls -l some_executable.py
-r-xr-xr-x+ 1 roaima roaima 0 Jun 25 18:33 some_executable.py

echo "The hunting of the Snark" > ./some_executable.py
-bash: ./some_executable.py: Permission denied

2
/usr/local/binउपयोगकर्ता-निर्मित निष्पादक और स्क्रिप्ट के लिए मानक स्थान है
18

4
@gardenhead यह निर्भर करता है कि सिस्टम कैसे सेट किया गया है। /usr/localमेजबान-विशिष्ट चीजों के लिए अभिप्रेत है (जैसा कि एक नेटवर्क माउंट के माध्यम से मेजबानों में साझा की गई निर्देशिका के विपरीत), और गैर-रूट उपयोगकर्ताओं द्वारा लेखन योग्य हो सकता है या नहीं भी हो सकता है।
चेपनर

4
@gardenhead यह निश्चित रूप से एक मानक स्थान है। मैं /use/local/binस्थानीय रूप से स्थापित लिपियों और कार्यक्रमों के लिए उपयोग करता हूं, जिनका उपयोग कई उपयोगकर्ता खातों और $HOME/binएकल उपयोगकर्ता के लिए व्यक्तिगत चीजों के लिए होने की संभावना है । दोनों में मूल्य है।
रोइमा

1
ध्यान दें कि फेडोरा का उपयोग करने की कोशिश कर रहा है$HOME/.local/bin
Zan Lynx

1
@Zan eeeww! गंभीरता से हालांकि, धन्यवाद। ऐसा लगता है कि आरएच सब कुछ को धक्का देने की कोशिश कर रहा है ~/.localक्योंकि अभी तक एक और वस्तु अपने "पारंपरिक" स्थान से चली गई है।
रोइमा

38

मौजूदा फ़ाइलों को पुनर्निर्देशन से अधिलेखित होने से रोकने के लिए या किसी POSIX- जैसे शेल में विकल्प का >उपयोग करें (यह भी कि वास्तव में यह सुविधा कहां से उत्पन्न हुई, हालांकि आप इसके बजाय / वहां करते हैं)। फिर, यदि आपको फ़ाइल बदलने के लिए बाध्य करने की आवश्यकता है, तो पुनर्निर्देशन ऑपरेटर ( में ) का उपयोग करें ।noclobberbash(t)cshset noclobberset -o noclobberset -C>|>!(t)csh

उदाहरण:

$ echo abc > file
$ set -o noclobber
$ echo xyz > file
bash: file: cannot overwrite existing file
$ echo xyz >| file
$ cat file
xyz

BTW, आप के साथ वर्तमान सेटिंग्स की जाँच कर सकते हैं set -o:

$ set -o
...
monitor         on
noclobber       on
noexec          off
...

हालांकि यह पूरी तरह से सवाल का जवाब देता है, मैं इसकी सिफारिश नहीं करूंगा। 1. टाइप >|करने के बजाय टाइप करने से |बहुत कम संभावना नहीं है >। 2. बैकअप बनाना आसान है और यह सलाह दी जाती है (इसके नाम के लायक संपादक अंतिम संस्करण को बचा सकता है; वहां cronआदि)। 3. कोड के प्रत्येक टुकड़े को संस्करण नियंत्रण में रखा जाना चाहिए, यहां तक ​​कि छोटी स्क्रिप्ट भी। YMMV।
मातरिनस

2
@maaartinus पर आते हैं, 1) एक के बजाय दो अलग-अलग अक्षर टाइप करना स्पष्ट रूप से कम संभावित है। 2) स्पष्ट रूप से बैकअप आवश्यक हैं, किसी ने भी ओपी को बैकअप बनाने की सलाह नहीं दी है, यह जवाब किसी भी तरह से बैकअप नहीं होने का सुझाव देता है, और संपादक बैकअप मान लेते हैं कि आपने फ़ाइल को एक संपादक में संपादित किया है। 3) फिर, आप केवल उस कोड के बारे में सोच रहे हैं जो ओपी ने लिखा है, जैसा कि इस विशेष उदाहरण में है, लेकिन सवाल और यह उत्तर मशीन पर किसी भी फाइल पर लागू होता है , जिसमें सिस्टम निष्पादन भी शामिल है।
terdon

8

जैसा कि @ केसी की टिप्पणी कहती है, मैं एक git रेपो के तहत महत्वपूर्ण लिपियों को दूर से सिंक करने की सलाह देता हूं (एक फैंसी स्व-होस्टेड प्लेटफॉर्म करेगा)।

इस तरह आप बुरी मानवीय गलतियों से बच जाते हैं जैसे कि फ़ाइल को पिछली कार्यशील स्थिति में वापस भेजना और उसे फिर से निष्पादित करना।


4

क्या फ़ाइल पुनर्प्राप्त करने योग्य है?

संक्षिप्त उत्तर: आमतौर पर नहीं।

@ मर्क प्लॉटनिक टिप्पणियों में बताते हैं, आप Uncompyle का उपयोग .pyकरने से फ़ाइलों को पुनर्प्राप्त कर सकते हैं । यह आपकी स्थिति के लिए एकदम सही होना चाहिए।.pyc

सामान्य तौर पर, हालांकि, यह बहुत कठिन है। सैद्धांतिक रूप से आप फ़ाइलों को हटाना रद्द करने के लिए फोरेंसिक टूल का उपयोग कर सकते हैं। संभवतः मैंने जो सबसे आसान प्रयोग किया है, वह है testdisk(उर्फ "PhotoRec")। यह केवल कभी-कभी काम करता है और यह एक धीमी प्रक्रिया है। यह आमतौर पर इसके लायक नहीं है, इसलिए, हाँ, यह संभव है , लेकिन असली जवाब "नहीं" है।

कर सकते हैं > अधिलेखित निष्पादनयोग्य नहीं बदला जा?

नहीं, निष्पादन योग्य के रूप में केवल फाइलों को पुनर्निर्देशित करने के लिए शेल को बताने का कोई मानक तरीका नहीं है। वहाँ "noclobber" है जो मौजूदा फ़ाइलों में पुनर्निर्देशन को रोक देगा, निष्पादन योग्य या नहीं, लेकिन उस पर मेरी टिप्पणियों को देखें।

भविष्य में क्या करना है?

  1. यह मूर्खतापूर्ण लग सकता है, लेकिन भविष्य की गलतियों को रोकने के लिए, आपको शायद कुछ भी करने की आवश्यकता नहीं है। मेरी शर्त यह है कि आपने पहले ही यह सबक सीख लिया है।

    मैं बहुत लंबे समय से यूनिक्स का उपयोग कर रहा हूं और सिखा रहा हूं, जबकि लोग अक्सर एक बार यह गलती करते हैं, वे शायद ही कभी इसे दोहराते हैं। क्यों नहीं? इसी कारण से चाकू से अनुभव किया गया व्यक्ति खुद को नहीं काटता: मनुष्य सीखने में अच्छा होता है। आखिरकार, सही काम करना दूसरी प्रकृति बन जाता है।

  2. एक पाठ संपादक का उपयोग करें जो आपके लिए बैकअप बनाता है। उदाहरण के लिए, यदि आप उपयोग करते हैं emacs, तो आपके प्रोग्राम का पिछला संस्करण mac_ip.py ~ में सेव हो जाता है। अन्य संपादकों को इसी तरह काम करने के लिए कॉन्फ़िगर किया जा सकता है (उदाहरण के लिए, "बैकअप सेट करें" .nanorc)। संपादकों के लिए जो स्वचालित बैकअप का समर्थन नहीं करते हैं, आप अपने .bashrc में एक सरलीकृत कार्य कर सकते हैं:

    myeditor() { cp -p "$1" "$1~";  editor "$1"; }
    
  3. खुद के लिए प्रतियां बनाना आसान बनाएं। उदाहरण के लिए, जिस परियोजना पर आप काम कर रहे हैं, उसकी निर्देशिका में, आपके पास इस तरह के लक्ष्य के साथ मेकफाइल हो सकता है:

    # Use `make tar` to backup all files in this directory.
    # Tar filename will be ../<currentdirectory>-<date>.tar.gz 
    DIRNAME = $(shell basename `pwd`)
    TIMESTAMP = $(shell date +%s)
    tar:
        @echo "[Tarring up ${DIRNAME}.tar.gz]"
        (cd .. ; tar -zcvf "${DIRNAME}-${TIMESTAMP}.tar.gz" "${DIRNAME}")
    

    (नोट: स्टैकएक्सचेंज टीएबी को 4 रिक्त स्थान के रूप में गलत बता रहा है।)

  4. इसी तरह, आप एक ऐसा मेकफाइल लक्ष्य बना सकते हैं जो rsyncएक दूरस्थ यूनिक्स होस्ट के लिए करता है जिसे आप sshएक्सेस करते हैं। (उपयोग करें ssh-copy-idताकि आपसे आपका पासवर्ड बार-बार न पूछा जाए।)

  5. का उपयोग करें git। आरंभ करने पर कई उत्कृष्ट ट्यूटोरियल हैं। कोशिश करो man gittutorial, man gittutorial-2और man giteveryday। अपनी खुद की गिट रिपॉजिटरी सेट करना कठिन नहीं है, लेकिन आप github.com पर किसी भी कीमत पर एक रिमोट रिपॉजिटरी भी बना सकते हैं।

  6. यदि उपरोक्त समाधान बहुत भारी हैं, तो आप छोटी स्क्रिप्ट को gist.github.com पर सहेज सकते हैं । हालांकि वेब ब्राउज़र से पेस्ट या अपलोड करना संभव है, मैं चीजों को सुपर आसान बनाने के लिए कमांड लाइन जिस्ट इंटरफेस का उपयोग करने की सलाह देता हूं ।

मैं "noclobber" का उपयोग करके दृढ़ता से हतोत्साहित करता हूं।

हां, यदि आप चुनते हैं, set -o noclobberतो आप ऐसा कर सकते हैं जब भी आप किसी मौजूदा फ़ाइल को अधिलेखित करने का प्रयास करेंगे तो आपको त्रुटि संदेश मिलेंगे। यह एक बुरा विचार है, मेरी राय में। *

यह शेल को गैर-मानक तरीके से बनाता है जिसमें कोई भी दृश्य संकेत नहीं है कि क्या यह सक्षम है। आपको सामान्य चीजें करने के लिए एक अलग वाक्यविन्यास का उपयोग करना होगा। सबसे बुरी बात यह है कि अगर आपको नोबलर की आदत हो जाती है, तो किसी दिन आप एक और यूनिक्स मशीन का इस्तेमाल कर सकते हैं, बिना नोकबर्बर के और इस तरह की दुर्घटना फिर से हो सकती है।

जैसा कि आप शायद जानते हैं, यूनिक्स खोल विशेषज्ञों के लिए एक तेज उपकरण होने के लिए डिज़ाइन किया गया था। यह उपयोग करने के लिए तेज़ है और आपके रास्ते में नहीं आएगा - और यह आपको काट देगा यदि आप भूल जाते हैं कि कौन सा अंत नुकीला है। लेकिन, जितना अधिक आप इसका उपयोग करते हैं, उतना ही मुझे लगता है कि आप इसकी सराहना करेंगे कि यह एक अच्छी बात हो सकती है।


* फुटनोट: शायद नमक के दाने के साथ मेरी राय लें। मैं भी उस तरह का व्यक्ति हूं जो सोचता है कि साइकिल प्रशिक्षण के पहिये एक बुरा विचार हैं।


मैंने कुछ समय के लिए यूनिक्स भी सिखाया है। मेरे कई छात्रों ने यूनिक्स की सीधी सादगी की सराहना नहीं की है; मैं उन्हें बताता हूं कि वे अकेले नहीं हैं, और कम से कम अभी भी यूनिक्स हैटर की हैंडबुक पर प्रशंसा करते हुए सीख सकते हैं, जो उनके लिए कुछ माइनफील्ड से बाहर का नक्शा देता है। simson.net/ref/ugh.pdf
जेसन

इसके अलावा: मैं मानता हूं - साइकिल पर प्रशिक्षण के पहिये किसी के लिए भी मददगार हैं कि वह तिपहिया वाहन चलाना सीखें।
जेसन

2

यदि आपने हाल ही में स्क्रिप्ट देखी या संपादित की थी और यह अभी भी मेमोरी बफर में था, तो आप डेटा को पुनर्प्राप्त करने में सक्षम हो सकते हैं। अन्यथा, आप भाग्य से बहुत बाहर हैं।

यदि आप (या इसके बजाय) के बजाय teeएक फ़ाइल (और साथ ही STDOUT) को लिखने के लिए पाइप करते हैं , तो आप आसानी से एक उपनाम, फ़ंक्शन, या सिम्लिंक को एक स्क्रिप्ट के साथ बदल सकते हैं जो उपयोगकर्ता को चेतावनी देती है कि क्या फाइल वे लिखने वाले हैं। निष्पादन योग्य है।>tee -a>>tee

निम्नलिखित किसी भी तरह से आदर्श नहीं है और इसे बहुत सुधार किया जा सकता है , लेकिन यह एक प्रारंभिक बिंदु है, बस इस बात का एक उदाहरण है कि यह कैसे संभव है:

wee.sh:

#!/bin/bash

if [ -n "${2}" ]; then
  if [ "$(ls -l "${2}" | awk '{print $1}' | grep x)" ]; then
    echo executable
  else
    tee -a "${2}"
  fi
elif [ "$(ls -l "${1}" | awk '{print $1}' | grep x)" ]; then
  echo executable
else
  tee "${1}"
fi

... तो बस echo 'alias tee="/path/to/wee.sh"' >> ~/.bashrcया कुछ इसी तरह।

उज्ज्वल पक्ष पर, कम से कम आपको अधिक अभ्यास मिलेगा और आपकी पायथन लिपि का दूसरा संस्करण संभवतः पहले से बहुत बेहतर होगा!


1

आपने निर्दिष्ट नहीं किया कि आप पीसी या सर्वर पर काम कर रहे हैं या नहीं। यदि आपकी फ़ाइलें एक समर्पित फ़ाइल सर्वर पर संग्रहीत की जाती हैं, तो अक्सर फ़ाइल सर्वर हार्डवेयर (OS पर) द्वारा स्वचालित बैकअप ("स्नैपशॉट") रखे जाते हैं।

लिनक्स के तहत

वर्चुअल, हिडन स्नैपशॉट निर्देशिका आपकी फ़ाइल सिस्टम में प्रत्येक निर्देशिका में मौजूद है।

प्रयत्न:

cd .snapshot   
ls -l

यदि वह निर्देशिका मौजूद है, तो आप भाग्य में हो सकते हैं। आपको कुछ निश्चित समय में स्वचालित रूप से संग्रहीत बैकअप रखने वाली निर्देशिकाओं की एक श्रृंखला देखनी चाहिए। नाम उस समय के सापेक्ष समय को इंगित करते हैं जिस पर स्नैपशॉट संग्रहीत किया गया था। उदाहरण के लिए:

hourly.0
hourly.1
hourly.2
hourly.3
hourly.4
hourly.5
nightly.0
nightly.1
nightly.2
nightly.3
nightly.4
nightly.5
nightly.6
weekly.0
weekly.1
weekly.2

किसी भी समय-बिंदु निर्देशिका में जाएं, जो काफी पुरानी हो (आपकी फ़ाइल-ओवरराइट गलती से पहले)। समय-सीमा निर्देशिका के अंदर, आपको ../..अतीत में उस बिंदु के रूप में निर्देशिका (और सभी उपनिर्देशिका) की स्थिति को देखना चाहिए ।

cd nightly.6
ls  # look around   
tee < mac_ip.py  # check for the correct content
cp mac_ip.py ~/safekeeping/mac_ip.py  # save the old file

टिप्पणियाँ:

  1. ls -a.snapshotनिर्देशिका नहीं दिखाएगा ; आपको इसका नाम अन्वेषण करना चाहिए। यह फ़ाइल सर्वर द्वारा वस्तुतः डाला जाता है। यह आपके फाइल सिस्टम में एक वास्तविक निर्देशिका के रूप में मौजूद नहीं है।
  2. ये स्वचालित स्नैपशॉट एक रोलिंग इतिहास हैं। पुराने बदलाव अंत में समाप्त हो जाते हैं और खो जाते हैं। आपको इस तकनीक का उपयोग जल्द से जल्द करने की आवश्यकता है, जब आपको पता चलता है कि आपको फ़ाइल वापस चाहिए।

विंडोज के तहत

छिपी हुई स्नैपशॉट निर्देशिका का नाम ~ स्नैपशॉट हो सकता है और किसी दिए गए ड्राइव के मूल स्तर पर ही मौजूद हो सकता है।

सलाह

स्नैपशॉट एक सुरक्षा जाल है जो अधिकांश समय काम करते हैं, लेकिन हर बार नहीं। मैं gitतुच्छ फ़ाइलों के लिए भी एक संस्करण नियंत्रण प्रणाली (जैसे ) का उपयोग करने के लिए अन्य सिफारिशों के साथ जुट गया ।


1

यह पहले भी कहा जा चुका है, और मैं इसे फिर से कहूंगा। एक नियंत्रण प्रणाली का उपयोग करें।

बैकअप एक हार्डवेयर विफलता को पुनर्प्राप्त करने के लिए है। संशोधन नियंत्रण आपकी जैसी स्थितियों के लिए है (और इसके कई अन्य उपयोग हैं)। संशोधन नियंत्रण उपकरण आपको किसी फ़ाइल का इतिहास रखने और उस इतिहास के किसी भी बिंदु पर वापस जाने की अनुमति देते हैं।

संशोधन नियंत्रण उपकरणों के उदाहरणों में तोड़फोड़ (एसवीएन) (अभी थोड़ा पुराना है, लेकिन अभी भी अच्छा-ईश), मर्क्यूरियल (एचजी), और गिट (गिट) (उपयोग करने में कठिन) शामिल हैं। कार्यालय दस्तावेजों के लिए svn अच्छा है, और अन्य उम-मर्गेबल्स, गिट और एचजी ने इसे अन्य अन्य भूमिकाओं के लिए पार कर लिया है। hg और git आपको ऑफ-लाइन काम करने की अनुमति देता है, और वितरण और बैकअप के लिए एक दूरस्थ सर्वर के साथ सिंक्रनाइज़ करने के लिए।

संशोधन नियंत्रण पर पढ़ें, फिर संशोधन नियंत्रण वितरित किया, और फिर उन्हें आज़माएं।


मैं मानता हूं कि संशोधन नियंत्रण का उपयोग करना मेरी जैसी स्थितियों के लिए सबसे अच्छा है, लेकिन फाइलों को सही अनुमति देना भी उतना ही महत्वपूर्ण है
भरत तेजा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.