Yanlışlıkla çıkış yönlendirmesini> yerine bir boru |


21

Bir ay önce stdin'den MAC ve IP adreslerini eşlemek için bir Python betiği yazdım. Ve iki gün önce onu hatırladım ve çıktılarını filtrelemek için kullandım tcpdumpama bir yazım hatası nedeniyle yanlış gitti. yazdım

tcpdump -ne > ./mac_ip.py

ve çıktı hiçbir şey değildir. Ancak girdiyi ayrıştıramadığında çıktı "Bilinmiyor" olmalı, bu yüzden program yerine cat ./mac_ip.pytüm tcpdumpverileri buldum ve buldum . Sonra kullanmam gerektiğini anladım.

tcpdump -ne | ./mac_ip.py

Programımı geri almanın bir yolu var mı? Yine de programımı tekrar yazabilirim, ancak daha önemli bir programla tekrar olursa bir şey yapmalıyım. VEYA dosyayı kontrol etmek ve çalıştırılabilir olup olmadığını uyarmak için çıkış yönlendirmesini söylemenin herhangi bir yolu var mı?


18
Programınızı, üzerine yazmadan önceki son yedekten geri alabilirsiniz, aksi halde almazsınız. BTW kabuğunda belirtebileceğiniz set -o noglobberve bash artık varolan dosyalara yönlendirilmez. Detaylar için buraya bakınız: cyberciti.biz/tips/howto-keep-file-safe-from-overwriting.html
eckes

12
Önemli çalıştırmalara yazma izniniz olmamalı ...
Hagen von Eitzen

20
@eckesset -o noclobber
GSMH

38
@HagenvonEitzen Böyle bir tavsiyeden nefret ediyorum, sanki çalıştırmadan önce yazmış olduğunuz her defalık kabuk ve python betiğine uygun sahiplik ve izinler ayarlamışsanız (ve elbette, yeniden düzenlemek zorunda kalırsanız kısa bir süre geri dönün) ). Sadece, " >Kastettiğin zaman yazmamalısın" den daha az anlamlıdır |. Gerçekliği unutma.
Jason C,

30
Git depoları ucuzdur. Ne kadar küçük ve anlamsız olursa olsun tüm kodunuzu girin ve bunun gibi bir hata hızlı ve kolay bir çözümdür.
casey

Yanıtlar:


22

Maalesef yeniden yazmanız gerekeceğinden şüpheliyim. (Yedekleriniz varsa, bunları kaldırma zamanı geldi. Değilse, gelecek için bir yedekleme rejimi ayarlamanızı şiddetle tavsiye ederim. Çok sayıda seçenek var, ancak bu cevap için konu dışı.)

Çalıştırılabilir dosyaları ayrı bir dizine koymanın ve bu dizine dizinin eklenmesinin PATHfaydalı olduğunu biliyorum . Bu şekilde çalıştırılabilir dosyalara açık yoldan başvurma ihtiyacım yok. Kişisel (özel) komut dosyaları için tercih ettiğim programlar dizini "$HOME"/bin, program arama yoluna eklenebilir PATH="$HOME/bin:$PATH". Genelde bu, kabuk başlangıç ​​komut dosyalarına .bash_profileve / veya eklenir .bashrc.

Son olarak, tüm çalıştırılabilir programlarda kendiniz için yazma izninizi kaldırmanızı durduracak hiçbir şey yoktur:

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, kullanıcı tarafından oluşturulan çalıştırılabilir kodlar ve scriptler için standart konumdur
gardenhead

4
@gardenhead Sistemin nasıl kurulduğuna bağlıdır. /usr/localana bilgisayara özgü şeyler (bir ağ montajı aracılığıyla ana bilgisayarlar arasında paylaşılan bir dizinin aksine) içindir ve kök olmayan kullanıcılar tarafından yazılabilir veya olmayabilir.
chepner

4
@gardenhead, kesinlikle standart bir yer. Kullandığım /use/local/binyerel olarak yüklü komut ve birden fazla kullanıcı hesabı tarafından kullanılacak muhtemel programlar için ve $HOME/bintek bir kullanıcıya kişisel şeyler için. Her ikisinde de değer var.
roaima

1
Fedora'nın zorlamaya çalıştığını unutmayın$HOME/.local/bin
Zan Lynx

1
@Zan eeeww! Cidden, teşekkür ederim. RH, ~/.local"geleneksel" yerinden taşınan başka bir öğe olduğu için herşeyi zorlamaya çalışıyor gibi görünüyor .
roaima

38

Yönlendirme tarafından üzerine yazılır olmaktan mevcut dosyaları engellemek için >kullanım noclobberseçeneği bashveya herhangi POSIX gibi (aynı zamanda kabuk (t)cshyapmanız olsa özelliği aslında nereden kaynaklandığı set noclobberyerine set -o noclobber/ set -Cvar). Ardından, bir dosyayı değiştirmeye zorlamanız gerekirse, >|yeniden yönlendirme işlecini ( >!in (t)csh) kullanın.

Örnek:

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

Btw, mevcut ayarları ile kontrol edebilirsiniz set -o:

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

Bu soruya mükemmel cevap verirken bunu tavsiye etmem. 1. >|Bunun yerine yazmak |, yazmaktan daha az olası değildir >. 2. Yedekleme yapmak kolaydır ve tavsiye edilir (adına değer veren bir editör son sürümü kaydedebilir; orada cronvb.). 3. Her kod parçası, küçük komut dosyaları bile sürüm kontrolü altına alınmalıdır. YMMV.
maaartinus

2
@maaartinus, 1) biri yerine iki ayrı karakter yazmak açıkça daha az olası. 2) Belli ki yedeklemeler esastır, hiç kimse OP'ye yedekleme yapmamasını tavsiye etmedi, bu cevap hiçbir şekilde yedeklememeyi önermiyor ve editör yedeklemeleri dosyayı düzenleyicide düzenlediğinizi varsayıyor. 3) Yine, OP'nin sadece bu özel örnekte olduğu gibi yazdığı kodu düşünüyorsunuz, ancak soru ve bu cevap, sistem çalıştırılabilir dosyaları dahil olmak üzere makinedeki herhangi bir dosya için geçerlidir .
terdon

8

@ Casey'nin yorumunda belirtildiği gibi, uzaktan eşzamanlı olarak ( süslü, kendi kendine barındırılan bir platformun yapacağı) bir git deposunda önemli komut dosyalarının bulunmasını şiddetle tavsiye ederim .

Bu şekilde, dosyayı önceki çalışma durumuna geri döndürmek ve tekrar yürütmek gibi kötü insan hatalarından korunursunuz.


4

Dosya kurtarılabilir mi?

Kısa cevap: Genelde değil.

@Mark Plotnick yorumlarda işaret ediyor, Uncompyle kullanarak .pydosyaları kurtarabilirsiniz . Bu, durumunuz için mükemmel olmalıdır..pyc

Genel olarak, yine de, bu daha zordur. Teorik olarak, dosyaları geri almak için adli tıp araçlarını kullanabilirsiniz. Muhtemelen kullandığım en kolay testdisk(aka "PhotoRec"). Sadece bazen çalışır ve yavaş bir işlemdir. Genelde buna değmez, yani evet, mümkün , ancak gerçek cevap "hayır".

Can > üzerine yazma yürütülebilir değil değiştirilebilir?

Hayır. Kabuğa asla yalnızca çalıştırılabilir olarak işaretlenmiş dosyaları yeniden yönlendirmemesini söylemenin standart bir yolu yoktur. Çalıştırılabilir olsun ya da olmasın, var olan dosyalara yönlendirmeyi engelleyen "noclobber" var ancak bu konudaki yorumlarımı gör.

Gelecekte ne yapmalı?

  1. Bu aptalca gelebilir, ancak gelecekteki hataları önlemek için muhtemelen hiçbir şey yapmanıza gerek yoktur. Benim iddiaya göre bu dersi çoktan öğrendiniz.

    Unix'i çok uzun zamandır kullanıyor ve öğretiyorum ve insanlar çoğu zaman bu hatayı bir kez yaparken nadiren tekrarlıyorlar. Neden olmasın? Muhtemelen aynı sebepten dolayı bıçakla tecrübe edilen bir insan kendini kesmiyor: insanlar öğrenmede iyidir. Sonunda, doğru olanı yapmak ikinci doğa haline gelir.

  2. Sizin için yedekleme yapan bir metin düzenleyici kullanın. Örneğin, kullanırsanız emacs, programınızın önceki sürümü mac_ip.py ~ içine kaydedilir. Diğer editörler de benzer şekilde çalışacak şekilde yapılandırılabilir (örneğin, "yedeklemeyi ayarla" .nanorc). Otomatik yedeklemeyi desteklemeyen editörler için, .bashrc'nizde basit bir işlev yapabilirsiniz:

    myeditor() { cp -p "$1" "$1~";  editor "$1"; }
    
  3. Kopyalama işlemini kendiniz için kolaylaştırın. Örneğin, üzerinde çalıştığınız projenin dizininde, şunun gibi bir hedefi olan bir Makefile olabilir:

    # 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}")
    

    (Not: stackexchange, yukarıdaki TAB'leri 4 boşluk olarak yanlış yapıyor.)

  4. Benzer şekilde, erişiminiz olan rsyncuzak bir Unix ana bilgisayarına yapılan bir Makefile hedefi oluşturabilirsiniz ssh. ( ssh-copy-idTekrar tekrar kullanın , şifreniz sorulmayacak.)

  5. Kullanın git. Başlamak için birçok mükemmel ders var. Deneyin man gittutorial, man gittutorial-2ve man giteveryday. Kendi git deponuzu oluşturmak zor değildir, ancak github.com'da ücretsiz olarak uzak bir depo da oluşturabilirsiniz

  6. Yukarıdaki çözümler çok ağırsa, küçük komut dosyalarını gist.github.com adresine kaydedebilirsiniz . Bir web tarayıcısından yapıştırmak veya yüklemek mümkün olsa da, işleri kolaylaştırmak için bir komut satırı kılavuzu arayüzü kullanmanızı öneririm .

"Noclobber" kullanmaktan kesinlikle vazgeçiyorum.

Evet, seçerseniz, set -o noclobbervarolan bir dosyanın üzerine yazmaya çalıştığınızda hata mesajları alırsınız. Bu bence kötü bir fikir. *

Kabuğun etkin olup olmadığına dair hiçbir belirti olmadan standart olmayan bir şekilde çalışmasını sağlar. Normal şeyler yapmak için farklı bir sözdizimi kullanmanız gerekir. Hepsinden kötüsü, noclobber'a alışırsanız, o zaman bir gün noclobber olmadan başka bir Unix makinesi kullanırsınız ve bu tür bir kaza yine olabilir.

Muhtemelen bildiğiniz gibi, Unix kabuğu uzmanlar için keskin bir araç olarak tasarlanmıştır. Kullanımı hızlıdır ve yolunuza çıkmaz - ve hangi ucun sivri olduğunu unutursanız sizi keser. Ancak, ne kadar çok kullanırsanız, bunun iyi bir şey olabileceğini takdir edersiniz.


* Dipnot: Belki de düşüncelerimi bir tuz tuzu ile alırım. Ayrıca bisiklet eğitim tekerleklerini kötü bir fikir olduğunu düşünen türden biriyim.


Ben de bir süre Unix'i öğrettim. Öğrencilerimin birçoğu, Unix'in doğrudan sadeliğini asla takdir etmedi; Onlara yalnız olmadıklarını ve en azından hala onlar için bazı mayın tarlalarını belirleyen Unix Hater El Kitabı'nı okurken öğrenebileceklerini söylüyorum. simson.net/ref/ugh.pdf
Jason

Ayrıca: Aynı fikirdeyim - bisikletle jantları eğitmek, üç tekerlekli bisiklet sürmeyi öğrenen herkes için faydalıdır.
Jason

2

Komut dosyasını yakın zamanda görüntülemiş veya düzenlemiş olsanız ve hala bellek arabelleğindeyseniz, ilk ortaya çıktıktan sonra verileri kurtarmanız mümkün olabilir. Aksi taktirde, şansınız tamamen tükenir.

Eğer yöneltilen Eğer teebir dosyaya yazmak için (yanı sıra STDOUTyerine) >(veya tee -ayerine >>), daha sonra kolayca yerini alabilir teeonlar yazma üzeresiniz dosyanın kullanıcıyı uyarır eğer bir komut dosyasına bir takma ad, fonksiyon veya sembolik bağla çalıştırılabilir.

Aşağıdakiler hiçbir şekilde ideal değildir ve birçok konuda geliştirilebilir , ancak bunun nasıl mümkün olduğuna bir örnek olarak, bir başlangıç ​​noktasıdır:

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

... sonra sadece echo 'alias tee="/path/to/wee.sh"' >> ~/.bashrcya da benzer bir şey.

Parlak tarafta, en azından daha fazla pratik yapacaksın ve Python betiğinin ikinci versiyonu muhtemelen ilkinden daha iyi olacak!


1

PC'de mi yoksa sunucuda mı çalışıldığını belirtmediniz. Dosyalarınız özel bir dosya sunucusunda saklanıyorsa, o zaman (işletim sistemi) dosya sunucusu donanımı tarafından tutulan otomatik yedeklemeler ("anlık görüntüler") vardır.

Linux altında

Sanal, gizli anlık görüntü dizini, dosya sisteminizdeki her dizinde bulunur.

Deneyin:

cd .snapshot   
ls -l

Bu dizin varsa, şansınız yaver gitmiş olabilir. Zamanında belirli noktalarda otomatik olarak saklanan yedekleri tutan bir dizi dizin görmelisiniz. Adlar, anlık görüntünün kaydedildiği geçmişte göreceli süreyi gösterir. Örneğin:

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

Yeterince eski olan herhangi bir zaman çizelgesi dizinine gidin (dosyanızın üzerine yazma hatasından önce). Zaman ../..noktası dizini içinde, geçmişte bu noktadan itibaren dizinin (ve tüm alt dizinlerin) durumunu görmelisiniz .

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

Notlar:

  1. ls -a.snapshotdizini göstermeyecek ; açıkça isimlendirmelisin. Neredeyse dosya sunucusu tarafından eklenir. Dosya sisteminizde gerçek bir dizin yok.
  2. Bu otomatik enstantaneler çığır açan bir geçmiş. Eski değişiklikler sonunda sona erer ve kaybolur. Bir dosyayı geri almanız gerektiğinin farkına vardıktan sonra bu tekniği mümkün olan en kısa sürede kullanmanız gerekir.

Windows altında

Gizli anlık görüntü dizini ~ anlık görüntü olarak adlandırılabilir ve yalnızca belirli bir sürücünün kök düzeyinde bulunabilir.

Tavsiye

Anlık görüntüler, çoğu zaman işe yarar, ancak her zaman işe yaramaz bir güvenlik ağıdır. gitÖnemsiz dosyalar için bile bir sürüm kontrol sistemi (örneğin ) kullanmak için diğer önerilere katılıyorum.


1

Daha önce söylendi ve tekrar söyleyeceğim. Bir revizyon kontrol sistemi kullanın.

Yedekler bir donanım arızasını gidermek içindir. Revizyon kontrolü, sizinki gibi durumlar içindir (ve başka birçok kullanım alanı vardır). Revizyon kontrol araçları, bir dosyanın geçmişini tutmanıza ve bu tarihin herhangi bir noktasına geri dönmenize izin verir.

Revizyon kontrol araçlarının örnekleri arasında yıkılma (SVN) (şimdi biraz eski, ama yine de iyi-ish), mercurial (hg) ve git (git) (kullanımı zor) bulunur. svn ofis dokümanları için iyidir ve diğer birleşebilirler, git ve hg diğer birçok rol için onu aştı. hg ve git, dağıtım ve yedekleme için çevrimdışı çalışmanıza ve uzak bir sunucu ile senkronize etmenize olanak tanır.

Revizyon kontrolünü okuyun, ardından revizyon kontrolünü dağıtın ve sonra bunları deneyin.


Revizyon kontrolü kullanmanın benimki gibi durumlar için en iyisi olduğu konusunda hemfikirim ancak dosyalara doğru izinleri vermek de aynı derecede önemli
Bharath Teja
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.