Η τελευταία παρασκευή του ιουλίου είναι η
χρόνια πολλά σε όσους γιορτάζουν,
μακάρι το uptime σας να είναι αντιστρόφως ανάλογο με τον μισθό σας
Ο μιντόρι web browser είναι ένας αρκετά ελαφρύς (και γρήγορος) gtk2 περιηγητής ιστού, βασισμένος στο webkit. Ακριβώς επειδή βασίζεται στο webkit μπορεί να περνάει από αρκετά WaSP, ένα από αυτά είναι το acid3:
Με την έκδοση 3.5 του firefox, ο firefox ανέκτησε αρκετό από το χαμένο έδαφος που είχε να κάνει με τα εξής προβλήματα:
- κολλήματα
- αργός
- κρασαρίσματα
- 100% cpu usage
- 100% memory usage
Ήδη βρισκόμαστε την έκδοση 3.5.1, οπότε σκέφτηκα να δοκιμάσω εκ νέου το acid3 test, ορίστε τα αποτελέσματα:
Υπάρχει λοιπόν αρκετός δρόμος ακόμα για τον firefox μέχρι να κατακτήσεις τα web standards.
Στην διαμάχη Διαχειριστές Vs Προγραμματιστές να προσθέσω και το εξής:
αποφασίζει ο εκάστοτε super duper developer να αλλάξει το version control σύστημά του από subversion σε git, όχι επειδή του δίνει επιπλέον δυνατότητες - αλλά επειδή άκουσε ότι το έχει γράψει ο linus και είναι πολύ της μοδός.
Οκ ρε μάστορα, αφού την κάνεις την αλλαγή ΓΙΑΤΙ δεν ενημερώνεις και κανέναν ?
Η λογική (εάν θριάμβευε δλδ) θα τον έκανε να προσθέσει ένα ακόμα subversion commit που να γράφει στο log:
έεειι εσύ, ναι εσύ, εσύ που χρησιμοποιείς το πρόγραμμά μου και το ανανεώνεις μέσω subversion:
να ξέρεις, έχει πάψει να υπάρχει. Δες εδώ: ….. για το git
Τι μυστικοπάθεια είναι αυτή ρε γμτ, ο λόγος γίνεται γιατί στην προσπάθειά μου να ανανεώσω το midori, έπρεπε να ανανεώσω το webkit που έπρεπε να ανανεώσω το libsoup το οποίο τράβαγα από subversion και η latest έκδοση του ΔΕΝ ικανοποιούσε κανέναν.
Τελικά έχουν δίκιο για τους gnome developers (η ακακία μου)
Αυτές τις μέρες προσπάθησα να ασχοληθώ λίγο με το PIrsyncD.
Πρόσθεσα την δυνατότητα να ορίζει κανείς τους καταλόγους (source/destination) από την γραμμή εντολών κατά την εκκίνησή, ώστε να μην χρειάζεται να ανοίγει το αρχείο και να τροποποιεί τις μεταβλητές. Οι προκαθορισμένοι κατάλογοι παραμένουν οι εξής:
source: /tmp/data
destination: /tmp/data2
Πρόσθεσα επίσης παραμέτρους ώστε να εμφανίζει την τρέχουσα έκδοση και μία μικρή βοήθεια.
Θα προσπαθήσω τον επόμενο καιρό να προσθέσω νέες επιλογές και δυνατότητες.
Πλέον τα inotify events που παρακολουθεί το PIrsynD είναι τα εξής:
- IN_ATTRIB
- IN_CLOSE_WRITE
- IN_CREATE
- IN_DELETE
- IN_MODIFY
- IN_MOVED_TO
- IN_MOVED_FROM
- IN_DELETE_SELF
Τέλος προσπάθησα να καταγράψω μερικές ερωτήσεις/απαντήσεις και έτσι δημιουργήθηκε ένα μικρό faq, στο οποίο προσπαθώ να εξηγήσω καλύτερα τι είναι και τι κάνει το PIrsynD
Always the latest version is here: PIrsyncD
Σίγουρα έστω και μία φορά έχει χρειαστεί να χρησιμοποιήσεις dhcp σε κάποιο μηχάνημα.
Η δυνατότητα να παίρνει αυτόματα όλες τις ρυθμίσεις σου λύνει τα χέρια.
Απλά βάζει το καλώδιο του δικτύου σε μία πρίζα και voila - δεν χρειάζεται να κάνεις τπτ.
Το πρόβλημα:
Όταν ο υπολογιστής σου συνδέεται σε πολλά και διαφορετικά δίκτυα στα οποία ΔΕΝ είσαι πάντα ο διαχειριστής. Έχεις φτιάξει τόσα χρόνια ωραία και όμορφα το routing tables σου, έχει ορίσει τους dns servers κ.λ.π.-κ.λ.π.
Και με το τρέχει το dhclient σου διαλύει τα πάντα !!!
Πως λες στο dhcpclient να ΜΗΝ αλλάξει το /etc/resolv.conf αρχείο σου;
- Εύκολα, απλά κάνεις το εξής:
# cat > /etc/dhclient-enter-hooks << EOF
make_resolv_conf() {
echo "doing nothing to resolv.conf"
}
EOF
Η ερώτηση μου είναι η εξής:
Πως λες στο dhcpclient να ΜΗΝ σου αλλάξει το routing table;
Ένα από τα πράγματα που με εκνευρίζουν είναι όταν οι developers ΔΕΝ ξέρουν τι κάνουν.
Και παραθέτω το εξής: η βιβλιοθήκη jpeg έχει φτάσει στην έκδοση 7
Όταν ένας developer θέλει να ελέγξει ή να κάνει χρήση της βιβλιοθήκης τότε απλά πρέπει να προσθέσει το εξής: -ljpeg κατά το compilation.
Οι περισσότερες διανομές έχουν την εξής βιβλιοθήκη: libjpeg ή jpeg-dev ή κάπως έτσι.
Αυτό που χρειαζόμαστε πραγματικά είναι η ύπαρξη της εξής βιβλιοθήκης:
[ebal@myhome:~]€ ldd /usr/lib/libjpeg.so
linux-gate.so.1 => (0xb7fe8000)
libc.so.6 => /lib/libc.so.6 (0xb7e54000)
/lib/ld-linux.so.2 (0xb7fe9000)
η οποία είναι συνήθως (99%) link στην αντίστοιχη έκδοση:
[ebal@myhome:~]€ ls -l /usr/lib/libjpeg.so
lrwxrwxrwx 1 root root 16 2009-06-27 12:54 /usr/lib/libjpeg.so -> libjpeg.so.7.0.0
Τώρα γιατί ΜΑ ΓΙΑΤΙ ένας developer να έχει ορίσει το libjpeg.so.62 με το χέρι στον κώδικά του δεν μπορώ να το καταλάβω?
Το αποτέλεσμα είναι το παρακάτω γελοίο μήνυμα:
error while loading shared libraries: libjpeg.so.62: cannot open shared object file: No such file or directory
Στο παραπάνω πρόβλημα σκέφτηκα τρεις (3) λύσεις :
a. ln -s /usr/lib/libjpeg.so /usr/lib/libjpeg.so.62
b. downgrade σε libjpeg.so.62
c. edit source code και rebuild όλα τα source προγράμματα !
Η έκδοση 7 περιέχει αλλαγές και προσθήκες αλλά όχι αλλαγή αρχιτεκτονικής, η δημιουργία ενός συνδέσμου (επιλογή a) και ένα email στον αρχικό δημιουργό ώστε να τροποποιήσει εκείνος τον κώδικά του σε κάτι πιο ….. σωστό μου φάνηκε ο πιο γρήγορος κι εύκολος τρόπος.
Φυσικά τέτοια προβλήματα είναι το τίμημα όταν έχεις πάντα ένα υβριδικό μοντέλο μίας base διανομής και όλα τα υπόλοιπα να είναι built from scratch
Δυστυχώς ΔΕΝ έχω ακόμα βρει (δεν ξέρω φυσικά εάν θα την βρω και ποτέ) την υπέρτατη τέλεια διανομή.
ΥΓ: το παραπάνω πρόβλημα είναι ένα από τα “κλασικά” όταν κάνεις update ή όταν θέλεις να είσαι bleeding edge (ή κοινός να έχει τόσο ελεύθερο χρόνο ώστε να κάνει το testing σε unstable προγράμματα).
Αρκετές φορές θέλετε να πείτε κάτι πιο εμπιστευτικά σε φίλους ή συνεργάτες που έχετε στο pidgin, όπως για παράδειγμα να “μοιραστείτε” το συνθηματικό του διαχειριστή για έναν απομακρυσμένο διακομιστή (ναι καλά τώρα, σε πίστεψα ότι ΔΕΝ το έχεις κάνει ποτέ).
Εάν όλες οι επικοινωνίες ήταν εξ’ αρχής κρυπτογραφημένες τότε ίσως να ήταν λίγο καλύτερα τα πράγματα.
Η πρόταση (κι αρκετά καλή λύση) είναι να μιλάς Off The Record
Το otr (off-the-record) είναι στην πραγματικότητα ένα library (OTR Messaging Library) και χρειάζεται να εγκατασταθεί πριν το OTR plugin for Pidgin
Ένα καλό παράδειγμα λειτουργίας/επικοινωνίας είναι το εξής
Πρόσθεσα τις εξής λειτουργίες:
- Πλέον το PIrsyncD παρακολουθεί τον πηγαίο κατάλογο για τα εξής events: WRITE,CREATE & DELETE
- Ελέγχει τις ρυθμίσεις κι εάν τις πληρεί θα εκκινήσει.
- Ξεκινάει ένα 1ο rsync κατά την εκτέλεση του προγράμματος.
- ΔΕΝ ξεκινάει το rsync άμεσα, δλδ κατά την ενεργοποίηση ενός event αλλά μετά από μία καθυστέρηση των 5 δευτερολέπτων ώστε να έχει όσο γίνεται το latest state του καταλόγου.
Προβλήμα που θέλω να λύσω:
Ξεκινάει ένα rsync command που διαρκεί για αρκετή ώρα π.χ. 10 λεπτά.
Τα αρχεία που γράφονται στον πηγαίο κατάλογο σε αυτά τα 10 λεπτά δεν αντιγράφονται παρά μόνο στο επόμενο inotify event που θα ενεργοποιήσει τον δαίμονα.
Τέλος, δημιούργησα μία ξεχωριστή σελίδα: PIrsyncD
και πάντα η τελευαία έκδοση του script θα είναι η εξής:
http://balaskas.gr/PIrsyncD/PIrsyncD.tbz2
Κοιτώντας λίγο την λειτουργία του PIrsyncD (Python Inotify Rsync Daemon) διαπίστωσα το εξής πρόβλημα:
Όταν στον πηγαίο κατάλογο γράφονται πάρα πολλά αρχεία κατά την διάρκεια που εκτελεί το rsync process, τότε δημιουργούνται πάρα πολλά rsync threads με αποτέλεσμα να αυξάνει το process and memory usage. Το πρόβλημα αυξάνει όταν το synchronization των καταλόγων γίνεται μέσω δικτύου.
Για να αποφύγω τέτοια προβλήματα σκέφτηκα να δημιουργήσω προσωρινά ένα lockfile το οποίο θα λειτουργεί ως ασπίδα προστασίας. Εάν υπάρχει σημαίνει ότι ακόμα εκτελείτε προηγούμενο rsync proccess. Μόλις ολοκληρωθεί το rsync process διαγράφεται και το temporarily lockfile.
Μπορείτε να κατεβάσετε το πρόγραμμα από εδώ: PIrsyncD_20090713
Παραθέτω τον κώδικα:
#!/usr/bin/env python
# Python Inotify Rsync Daemon
# Evaggelos Balaskas, ebalaskas AT ebalaskas DOT gr
# Last change: Mon Jul 13 12:01:31 EEST 2009
import pyinotify,os
source_path = "/tmp/data/"
dest_path = "/tmp/data2/"
# Variables for rsync to a remote server
dest_server = ""
#dest_server = "server:"
rsync_ssh = ""
# rsync_ssh = "-e ssh"
rsync_path = "/usr/bin/rsync"
rsync_args = "-az --delete"
rsync_command = rsync_path + " " + rsync_args + " " + source_path + " " + rsync_ssh + " " + dest_server + dest_path
# LockFile - failsafe mechanism
lockfile = "/tmp/.PIrsync.lock"
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CLOSE_WRITE
class PTmp(pyinotify.ProcessEvent):
def process_IN_CLOSE_WRITE(self, event):
if not os.path.exists(lockfile):
fd = os.open(lockfile, os.O_RDWR|os.O_EXCL|os.O_CREAT)
os.system(rsync_command)
os.remove(lockfile)
p = PTmp()
notifier = pyinotify.Notifier(wm, p)
wm.add_watch(source_path, mask, rec=True)
notifier.loop(daemonize=True, pid_file='/tmp/PIrsyncD.pid')
Mirroring directories with PIrsynD
Τον τελευταίο καιρό βρέθηκα αντιμέτωπος με το εξής πρόβλημα:
Real time Data Replication over network.
Έπρεπε να υλοποιήσω μία λύση ανάμεσα σε δύο συστήματα που θα λειτουργούν ως Active/Passive. Ξεκίνησα το οδοιπορικό μου, ρωτώντας φίλους και συνεργάτες για το μοντέλο που θα επέλεγαν οι ίδιοι.
Φυσικά και η απλούστερη λύση είναι το rsync, αλλά το rsync θα πρέπει να εκτελείτε από κάποιο δαίμονα (π.χ. crond). Το πρόβλημα εδώ είναι ότι υπάρχει time lug μεταξύ των δύο συστημάτων. Εάν βάλω τον δαίμονα ανά μία ώρα θα έχω μία τεράστια διαφορά των δεδομένων της τάξης μίας ολόκληρης ώρας, κατά την ατυχή περίπτωση failover. Εάν βάλω τον δαίμονα ανά 5 λεπτά υπάρχει περίπτωση να μην προλάβει στα 5 λεπτά να ολοκληρώσει το syncing. Γενικά πρέπει να δημιουργήσεις ένα custom script που θα ελέγχει όλα αυτά κι όχι μπορεί να προκύψουν και φυσικά η διαχειριστική ευθύνη και κόστος αυξάνει αρκετά.
Οι περισσότεροι μου πρότειναν το drbd με την χρήση του υπάρχοντος heartbeat. Απλά απαράδεκτο. Πάρα πολλοί περιορισμοί: Ανάγκη για ξεχωριστό δίσκο (block device), ΔΕΝ κάνει scale up, πολύ δύσχρηστο, αρκετή δουλειά μέχρι να το φέρεις στα μέτρα σου, δουλεύει μόνο ως Server/Client. Με απογοήτευσε αρκετά τολμώ να πω με θάρρος. Είναι όμως kernel module, το οποίο σημαίνει: ταχύτητα και διαφάνεια στον τρόπο που εργάζεται το υπόλοιπο σύστημα στο block device κι όντως έχεις Real time Data Replication
Η επόμενη επιλογή μου ήταν το gluster. Ένα από τα καλύτερα λογισμικά που έχω δει και δουλέψει. Μερικά από τα χαρακτηριστικά του είναι τα εξής: πανεύκολη εγκατάσταση, απλούστατο configuration, εξαιρετικό scale up (no limit πιστεύω), μπορείς να χρησιμοποιήσεις ως distribute filesystem, για replication, για striping, και μπορείς να υλοποιήσεις κάποια μοντέλα raid δια μέσου του δικτύου. Οι δυνατότητες που έχει, πιστεύω ότι μπορούν να καλύψουν τον οποιοδήποτε. Αλλά υλοποιείται με το μοντέλο server/client. Ορίζεις έναν client ο οποίος μπορεί να μιλήσει με n servers. Με δύο συστήματα μόνο ΔΕΝ μπορεί να δουλέψει και φυσικά μόνο όταν όλοι οι clients είναι linux.
Το επόμενο μου λογισμικό προς δοκιμή ήταν το incrond. Κάνει χρήση του inotify όταν αλλάζει ένα αρχείο οπότε με ελάχιστο scripting και λίγο rsync μπορείς να κάνεις αρκετά πράγματα. Αλλά και πάλι υπάρχει το διαχειριστικό κόστος, αρκετό scripting και φυσικά υπάρχει ένα θεματάκι με το recursive στους καταλόγους. Έχει όμως τρομερό documentation κι εάν το έχεις λίγο με τον προγραμματισμό μπορείς να δημιουργήσεις μία αρκετά καλή λύση.
Προσπαθώντας να βρω όντως την τέλεια λύση, στο μυαλό μου ήρθαν τα λόγια του Γιάννη Στοΐλη
- Γιάννη, έχεις δουλέψει ποτέ με κάποιο cluster file system ή κάτι παρόμοιο; Θέλω να βρω μία λύση για real time data replication
- Μπα, κάτι τέτοια τα αφήνω σε εσένα για δοκιμές, εγώ συνεχίζω να παίζω με custom rsync scripts
Τελικά το σκέφτηκα λίγο παραπάνω και μου ήρθε στο μυαλό η εξής εικόνα:
Ξεκίνησα λοιπόν να “ξαναβλέπω” το rsync ίσως με κάποιο inotify feature και voila: lsyncd
Μερικά δευτερόλεπτα μετά κι έτοιμο:
On server1:
lsyncd /data server2:/data
On server2:
lsyncd /data server2:/data
it’s just too simple
Αλλά … unbelievable αργό και buggy. Επίσης υπάρχει κι εδώ ένα θέμα με τo recursive, κρίμα γιατί μου άρεσε πάρα μα πάρα πολύ.
Σε αυτό το σημείο, σκέφτηκα να κάνω ένα βήμα πίσω και να ξαναδώ καλύτερα τις επιλογές μου. Αυτό που θέλω να υλοποιήσω είναι μία απλή και γρήγορη λύση για να συγχρονίζω δύο συστήματα. Στο μυαλό μου τριγύριζε η κουβέντα του Γιάννη: “Εγώ παίζω με custom rsync scripts” και σκέφτηκα: “What the fuck” ας κάνω κι εγώ κάτι τέτοιο. Έπρεπε όμως να βρω μία λύση να το συνδειάσω με το inotify.
Αναζητώντας στο διαδίκτυο για μία καλή υλοποίηση του inotify κατέληξα στο εξής: Pyinotify. Είναι η πιο πλήρης τεκμηριωμένη υλοποίηση του inotify, είναι γραμμένη σε python και έχει εξαιρετικά απλά παραδείγματα. Άρχισα να παίζω με τα παραδείγματα που έχει και να καταλαβαίνω καλύτερα το πως δουλεύει. Ίσως σε αυτό το σημείο να είναι καλό να αναφέρω ότι ΔΕΝ ξέρω python κι ότι ΔΕΝ έχω ξαναγράψει ποτέ κάποιο python script. Ξέρω όμως από προγραμματισμό και λίγο από εδώ - λίγο από εκεί κατέληξα στο εξής script: PIrsyncD!!!
To PIrsyncd σημαίνει: Python Inotify Rsync Daemon και είναι ένα εξαιρετικά απλό python script που τρέχει στο background ως δαίμονας. Ελέγχει συνεχώς έναν source κατάλογο που του έχουμε πει κι όταν γραφτεί κάτι σε αυτόν ή στους υποκαταλόγους του εκτελεί μία rsync εντολή ώστε να συγχρονίσει τους δύο καταλόγους. Το ενδιαφέρον εδώ είναι θα εκτελεστεί ΜΟΝΟ όταν γραφτεί κάτι, και ποτέ άλλοτε.
Παραθέτω τον κώδικα:
#!/usr/bin/env python
# Python Inotify Rsync Daemon
# Evaggelos Balaskas, ebalaskas AT ebalaskas DOT gr
# Last change: Sun Jul 12 22:50:17 EEST 2009
import pyinotify,os
source_path = "/tmp/data/"
dest_path = "/tmp/data2/"
# Variables for rsync to a remote server
dest_server = ""
#dest_server = "server:"
rsync_ssh = ""
# rsync_ssh = "-e ssh"
rsync_path = "/usr/bin/rsync"
rsync_args = "-az --delete"
rsync_command = rsync_path + " " + rsync_args + " " + source_path + " " + rsync_ssh + " " + dest_server + dest_path
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CLOSE_WRITE
class PTmp(pyinotify.ProcessEvent):
def process_IN_CLOSE_WRITE(self, event):
os.system(rsync_command)
p = PTmp()
notifier = pyinotify.Notifier(wm, p)
wm.add_watch(source_path, mask, rec=True)
notifier.loop(daemonize=True, pid_file='/tmp/PIrsyncD.pid')
Η αλήθεια είναι ότι είναι αρκετά buggy και θέλει δουλίτσα, αλλά δουλεύει και μάλιστα αρκετά καλά. Όσοι γνωρίζεται από python στείλτε μου τις παρατηρήσεις σας, είναι μάλιστα καλή ευκαιρία για να μάθω python.
Εάν θέλετε να το δοκιμάσετε τότε χρειάζεται να εγκαταστήσετε και την pyinotify ή μπορείτε να κατεβάσετε το εξής αρχείο: PIrsyncD_20090712
Ολοκλήρωσα αυτές τις μέρες την πλήρη μετάβασή σε όλα τα μηχανήματά μου σε archlinux.
Μπορεί να είναι μόνο 3:
- home desktop
- laptop
- work desktop
Αλλά ειδικά ο υπολογιστής στο γραφείο μου πήρε λίγο παραπάνω χρόνο από όσο περίμενα.
Σκέφτηκα λοιπόν, να τρέξω ένα gtkperf ώστε να ελέγξω εάν όντως είναι ταχύτερο το xfce στο archlinux σε σχέση με το ubuntu.
Ιδού το αποτέλεσμα μου:
GtkPerf 0.40 - Starting testing: Thu Jul 9 08:52:58 2009
GtkEntry - time: 0,00
GtkComboBox - time: 0,82
GtkComboBoxEntry - time: 0,68
GtkSpinButton - time: 0,09
GtkProgressBar - time: 0,04
GtkToggleButton - time: 0,05
GtkCheckButton - time: 0,05
GtkRadioButton - time: 0,10
GtkTextView - Add text - time: 0,54
GtkTextView - Scroll - time: 0,09
GtkDrawingArea - Lines - time: 0,51
GtkDrawingArea - Circles - time: 0,90
GtkDrawingArea - Text - time: 0,70
GtkDrawingArea - Pixbufs - time: 0,14
—
Total time: 4,71
Και μάλιστα το xfce είναι εγκατεστημένο από subversion (δλδ είναι unstable και αρκετά buggy)
[ebal@mywork ~] € xfwm4 –version
This is xfwm4 version 4.7.0svn.r30079 (revision 30079) for Xfce 4.7.0
4.71 πιστεύω ότι αποτελεί μία αρκετά καλή & γρήγορη επίδοση
Η παλαιότερη μέτρησή μου ήταν κοντά στο 6, see my old post
Επιτέλους ολοκλήρωσα σήμερα το migration στον υπολογιστή της δουλειάς σε archlinux και πλέον παντού βασικό λειτουργικό είναι το arch.
Σήμερα πέτυχα την εξής ανακοίνωση (εντελώς τυχαία):
nees_theseis_ergasias
Μπορεί κάποιον να ενδιαφέρει
Τελικά ο μοναδικός τρόπος να βελτιστοποιήσεις τον κώδικά σε ένα πρόγραμμα είναι απλά να το αφήσεις στην άκρη για λίγο καιρό.
Τις προηγούμενες ημέρες δέχθηκα ένα email για μία συνάρτηση στην php που είχα γράψει κάποτε.
Το email ήταν για την προσθήκη μίας επιπλέον δυνατότητας.
Σκέφτηκα ότι δεν είχα να χάσω και πολύ χρόνο, ήδη στο μυαλό μου είχα την λύση και ξεκίνησα να κάνω τις αλλαγές που έπρεπε.
ΞΑΦΝΙΚΑ σαν να με χτύπησε κεραυνός αφήνω το πληκτρολόγιο και κοιτάζω λίγο τον κώδικα.
- Τι σκατά έχω γράψει εδώ !!!
Μερικά λεπτά αργότερα, κι αφού έχω διαγράψει πάνω από το 50% του κώδικα βλέπω χαρούμενος το αποτέλεσμα.
Σήμερα προχώρησα με την αναβάθμιση του firefox στην έκδοση 3.5
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Μέχρι στιγμής φαίνονται όλα καλά, τόσο με την ταχύτητα όσο και με την απόδοση του συστήματός
Και σε ποιον δεν έχει τύχει να διαγράψει κατά λάθος ένα αρχείο.
Εάν όμως υπάρχει κάποια διεργασία που έχει “δεσμεύει” το αρχείο μας,
υπάρχουν αρκετές πιθανότητες να το ανακτήσουμε με την χρήση της lsof.
Η lsof μας δείχνει ποια είναι τα ανοιχτά αρχεία, δλδ τα αρχεία που αυτή την στιγμή έχουν “δεσμεύει οι διεργασίες του υπολογιστή μας.
Παραθέτω ένα πλήρες κι εύκολο παράδειγμα:
dmesg > dmesg.log
less dmesg.log
Ελέγχουμε το μέγεθος αλλά και το hash του αρχείου μέσω της md5sum για να πιστοποιήσουμε την ακεραιότητα παρακάτω:
ebal@myhome: € ls -l dmesg.log
-rw-r–r– 1 ebal ebal 28944 2009-07-02 21:46 dmesg.logebal@myhome: € md5sum dmesg.log
f8b02bca5b25244e71ada077a439a4cf dmesg.log
Διαγράφουμε το αρχείο, προσοχή το less που τρέχουμε παραπάνω είναι σε άλλο παράθυρο/τερματικό
ebal@myhome: € rm -f dmesg.log
ebal@myhome: € ls -l dmesg.log
ls: cannot access dmesg.log: Δεν υπάρχει τέτοιο αρχείο ή κατάλογος
Βλέπουμε εάν είναι “ανοιχτό” από κάποια άλλη διεργασία, περιμένουμε να δούμε την less
ebal@myhome: € lsof | grep dmesg.log
less 5412 ebal 4r REG 8,3 28944 6922 /tmp/dmesg.log (deleted)
Στην δεύτερη στήλη, ο αριθμός αυτός δηλώνει τον αριθμό της διεργασίας μας.
Κάθε φορά είναι διαφορετικός και σε κάθεναν θα είναι επίσης διαφορετικός.
Κάνοντας χρήση αυτού του αριθμού μέσω από το ψευδοαρχείο συστημάτων μας
μπορούμε να ανακτήσουμε το αρχείο που μόλις διαγράψαμε:
ebal@myhome: € cp /proc/5412/fd/4 /tmp/dmesg.log
Πριν συνεχίσουμε, μερικές πληροφορίες.
/proc : ο κατάλογος στον οποίο καταγράφουν όλες οι διεργασίες προσωρινά πληροφορίες
5412: o αριθμός διεργασίας της less
fd : file descriptor, εάν έχουν ανοιχτεί αρχεία
4 : Συνήθως είναι το αρχείο, με την εντολή ls -l στον κατάλογο /proc/5412/fd/4 το επιβεβαιώνουμε
Περισσότερα για το proc filesystem μπορείτε να διαβάσετε εδώ
Κι ελέγχουμε εκ νέου το μέγεθος και την ακεραιότητα του αρχείου μας.
ebal@myhome: € ls -l dmesg.log
-rw-r–r– 1 ebal ebal 28944 2009-07-02 21:54 dmesg.log
ebal@myhome: € md5sum dmesg.log
f8b02bca5b25244e71ada077a439a4cf dmesg.log
Οπότε την επόμενη φορά που θα διαγράψουμε ένα αρχείο, ρίχνουμε μια ματιά στην lsof.
Αρχική πηγή: linuxplanet