Toon posts:

[python] directory watch

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Voor vele zal het eenvoudig zijn maar voor mij het eerste python script, dus dat geeft aan dat ik nog niet diep in de materie zit.
Ik wil een script maken dat ik straks op mijn debian server als daemon kan draaien die dan enkele directories in de gaten houdt en acties onderneemt als er bestanden of directories bij komen of weg gaan.
De basis hierbij is het volgende:
code:
1
2
3
4
5
6
7
while 1:
  time.sleep (2)
  after = dict ([(f, None) for f in os.listdir (path_to_watch)])
  added = [f for f in after if not f in before]
  removed = [f for f in before if not f in after]
  if added: print "Added: ", ", ".join (added)
  if removed: print "Removed: ", ", ".join (removed)


Hierbij heb ik een mailscript in verwerkt tot het volgende;
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import os, time, smtplib

path_to_watch = "."
before = dict ([(f, None) for f in os.listdir (path_to_watch)])


def mail(serverURL=None, sender='', to='', subject='', text=''):
  """
  Usage:
  mail('somemailserver.com', 'me@example.com', 'someone@example.com', 'test', 'This is a test')
  """
  headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (sender, to, subject)
  message = headers + text
  mailServer = smtplib.SMTP(serverURL)
  mailServer.sendmail(sender, to, message)
  mailServer.quit()

while 1:
  time.sleep (2)
  after = dict ([(f, None) for f in os.listdir (path_to_watch)])
  added = [f for f in after if not f in before]
  removed = [f for f in before if not f in after]
  if added:
      print "Added: ", ", ".join (added)
      mail('localhost', 'afzender@test.invalid', 'ontvanger@test.invalid', 'bestand verwijderd', 'mailinhoud')
  if removed:
      print "Removed: ", ", ".join (removed)
      mailinhoud = 'ls -al'
      mail('localhost', 'afzender@test.invalid', 'ontvanger@test.invalid', 'bestand verwijderd', 'mailinhoud')
  before = after

Nu moet de functie mail aangeroepen worden met als text in de mail de output van mailinhoud. Dit lukt alleen niet.
Ik begrijp niet hoe ik de output van het commando "ls -al" (nu geprobeerd vast te leggen in mailinhoud) als variabele mee kan geven aan het commando mail.

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
quotes rond 'mailinhoud' weghalen?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt voor de snelle reactie maar helaas, ik krijg nu de letterlijke tekst van de variabele mailinhoud als tekst in mijn mail.
De inhoud van de mail is dus: "ls -al" in plaats van de output van het commando ls -al.

Acties:
  • 0 Henk 'm!

  • Flipke84
  • Registratie: Juli 2008
  • Laatst online: 09-11-2024
Volgens mij ben je ook vergeten om mailinhoud te definiëren in het geval "added".

Je zou het volgende eens kunnen proberen:
code:
1
mailinhoud = os.system('ls -al')

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dit brengt me een stap verder, maar zoals waarschijnlijk altijd, doet het volgende probleem zich voor;
Ik heb nu het volgende gebruikt;
code:
1
mailinhoud = os.system('ls -al')

en dit geeft de volgende fout;
code:
1
2
3
4
5
6
Traceback (most recent call last):
  File "./pywatch", line 41, in ?
    mail('afzender@test.invalid', 'ontvanger@test.invalid', 'bestand verwijderd', mailinhoud)
  File "./pywatch", line 14, in mail
    message = headers + text
TypeError: cannot concatenate 'str' and 'int' objects

Als ik er een print mailinhoud tussen zet krijg ik netjes de output van ls -al te zien dus dat klopt wel maar dit is waarschijnlijk een te grote output (te veel regels, te veel namen of zo) om de in de functie mail de mail samen te stellen.... hmmm moet ik ergens met "" gaan werken om dit bij elkaar te houden net als in bash?

Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
os.system geeft een code terug die aangeeft of het uitvoeren gelukt is. Dat is een integer en daar gaat de foutmelding over.

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb de variabele nu even in de mailfunctie gezet en heb gelezen dat als ik de output van een variabele weg wil schrijven dat ik dit in string vorm kan doen door back-quotes en daarmee kwam ik tot het volgende:
code:
1
2
3
4
5
6
  text = os.system('ls -al')
  headers = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (sender, to, subject)
  message = headers + `text`
  mailServer = smtplib.SMTP(serverURL)
  mailServer.sendmail(sender, to, message)
  mailServer.quit()

Dit geeft geen foutcode maar maakt de inhoud/tekst van de mail alleen maar; "0"

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op woensdag 26 november 2008 @ 01:21:
Dit geeft geen foutcode maar maakt de inhoud/tekst van de mail alleen maar; "0"
Juup schreef op woensdag 26 november 2008 @ 01:03:
os.system geeft een code terug die aangeeft of het uitvoeren gelukt is. Dat is een integer

[ Voor 3% gewijzigd door RobIII op 26-11-2008 01:56 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@RobIII; de opmerking van Jaap over de foutcode die os.system geeft dat het een integer is, daarop had ik gezocht en kwam tot de conclusie dat middels de back-quotes dit als string aan de bestaande variabele kan worden toegevoegd. Toch lukt dit niet.
Als ik de variabele text gewoonweg print middels "print text" krijgt is netjes de output van ls -al maar als ik dit aan de variabele message toevoeg geeft dit een de foutcode "cannot concatenate 'str' and 'int' objects". als ik echter de backquotes gebruik: message = headers + `text` dan is de uitkomst 0. Dit gebeurt ook als ik de text eerst naar een string omzet middels text = str(text).
Verder heb ik het ook met subproces en Popen geprobeerd, maar dat werkt ook niet en lijkt enkel een nettere manier om het commando ls -al uit te voeren.
Ik geloof dat ik toch niet helemaal begrijp waar het mis gaat...

Acties:
  • 0 Henk 'm!

  • sub0kelvin
  • Registratie: September 2002
  • Laatst online: 10-08-2023
os.system geeft geen output terug, enkel de exit code van het programma dat het uitvoert. Wil je de output afvangen (en dat wil je) zul je met popen of liever nog subprocess willen werken.

Bijvoorbeeld os.popen:
code:
1
2
3
import os
output = os.popen("ls -al", 'r')
print output.read()


Echter werken met subprocessen is netter en veel krachtiger
code:
1
2
3
from subprocess import Popen, PIPE
output = Popen(["ls", "-al"], stdout=PIPE).communicate()[0]
print output


edit:
Je kunt ook nog de (oude) commands module gebruiken:
code:
1
2
3
import commands
output = commands.getoutput("ls -al")
print output

[ Voor 14% gewijzigd door sub0kelvin op 26-11-2008 09:08 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb de tweede optie gebruikt en daarmee is het gelukt. Het probleem zat er in dat de output niet terug naar de variabele ging, ik had het ook gevonden door os.popen("ls -al").read()
Ik denk dat ik er toch aan moet wennen, dit soort verschillen in de programmeertalen.

Maar goed, conclusie; probleem opgelost, iedereen dank en topic mag dicht...

Acties:
  • 0 Henk 'm!

  • Elijan9
  • Registratie: Februari 2004
  • Laatst online: 25-09 22:45
Ik wil je Python avontuur niet verstoren ;) , maar je hebt tegenwoordig ook "incron". Dit is een soort cron die scripts kan gaan uitvoeren op het moment dat er aan je filesystem iets verandert en dit werkt via de "inotify" functionaliteit. Dit is veel efficiënter dan elke 2 seconden te gaan checken op wijzigingen.

Mocht je het wel zelf willen schrijven in Python, dan kun je ook eens kijken naar PyInotify

En topics gaan hier niet zomaar dicht, anderen kunnen hier later ook nog wat aan hebben...

[ Voor 10% gewijzigd door Elijan9 op 26-11-2008 11:37 ]

War is when the young and stupid are tricked by the old and bitter into killing each other. - Niko Bellic

Pagina: 1