[Python] NST0 tape content uitlezen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Obviously
  • Registratie: November 2009
  • Laatst online: 23-07 11:58
Ik vroeg mij af of misschien hier iemand mij verder kan helpen...

Ik moet een python script schrijven dat de content van een nst0 tape uitleest, het resultaat hiervan moet weggeschreven worden naar een bestand.

Een klein beetje meer duiding:

Ik moet de de content van een tape kunnen uitlezen met een script geschreven in python.

Je kan de content van een tape makkelijk uitlezen met:

code:
1
tar tvf /dev/nst0


Maar het probleem is dat je dan alleen de files krijgt van track 1.

Als je dan het volgende uitvoert:

code:
1
mt -f /dev/nst0 fsf 1


Dan kom je bij de volgende track uit en als je dan terug
code:
1
tar tvf /dev/nst0
uitvoert krijg je iets anders te zien dan eerst.

Dus ik moet een script schrijven dat al de tracks overloopt en deze content dan naar een file schrijft.

Om te kijken of de tape op zen laatste track is gekomen, is het voldoende om de exit code te controleren. Als deze verschillend is van 0 moet het script stop gezet worden.

Ik hoop dat mijn uitleg een beetje duidelijk is en dat jullie mij verder kunnen helpen.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17:52
Ik weet niet of Python de meest geschikte taal is voor dit soort dingen, aangezien je vrij OS-specifieke functionaliteit gebruikt, waar al wel goede externe tools voor bestaan maar misschien geen geschikte Python modules. Als je alleen de inhoud van de tape wil listen (dus "tar tvf" uitvoeren voor elk bestand op de tape) dan ben je waarschijnlijk een heel stuk beter af met een shell script à la:

Bash:
1
2
3
4
5
#!/bin/sh -e
TAPE=/dev/nst0
mt -f "$TAPE" rewind
tar tvf "$TAPE"
while mt -f "$TAPE" fsf; do tar tvf "$TAPE"; done


Je kunt die commando's ook wel vanuit Python aanroepen, maar wat is het voordeel daarvan?

Goed, dit terzijde; stel dat je wél ingewikkelde dingen wil doen met de inhoud van de tape, dan is Python misschien wel handig. Voor het lezen van tar-files kun je dan prima de tarfile module gebruiken. Spoelen in de tape gebeurt via ioctl-calls, die je in Python kunt doen met function ioctl() in de fnctl module.

Helaas is er geen specifieke support voor tape control, dus zul je zelf de argumenten voor ioctl in elkaar moeten knutselen, bijvoorbeeld met de struct module. Als je Linux gebruikt, kun je informatie over de ioctl's die de tape driver begrijpt vinden in de st manpage en details in include/linux/mtio.h in de Linux source code. Voor andere besturingssystemen is er vermoedelijk soortgelijke documentatie.

Acties:
  • 0 Henk 'm!

  • Obviously
  • Registratie: November 2009
  • Laatst online: 23-07 11:58
Soultaker schreef op maandag 18 april 2011 @ 16:56:
Ik weet niet of Python de meest geschikte taal is voor dit soort dingen, aangezien je vrij OS-specifieke functionaliteit gebruikt, waar al wel goede externe tools voor bestaan maar misschien geen geschikte Python modules. Als je alleen de inhoud van de tape wil listen (dus "tar tvf" uitvoeren voor elk bestand op de tape) dan ben je waarschijnlijk een heel stuk beter af met een shell script à la:

Bash:
1
2
3
4
5
#!/bin/sh -e
TAPE=/dev/nst0
mt -f "$TAPE" rewind
tar tvf "$TAPE"
while mt -f "$TAPE" fsf; do tar tvf "$TAPE"; done


Je kunt die commando's ook wel vanuit Python aanroepen, maar wat is het voordeel daarvan?

Goed, dit terzijde; stel dat je wél ingewikkelde dingen wil doen met de inhoud van de tape, dan is Python misschien wel handig. Voor het lezen van tar-files kun je dan prima de tarfile module gebruiken. Spoelen in de tape gebeurt via ioctl-calls, die je in Python kunt doen met function ioctl() in de fnctl module.

Helaas is er geen specifieke support voor tape control, dus zul je zelf de argumenten voor ioctl in elkaar moeten knutselen, bijvoorbeeld met de struct module. Als je Linux gebruikt, kun je informatie over de ioctl's die de tape driver begrijpt vinden in de st manpage en details in include/linux/mtio.h in de Linux source code. Voor andere besturingssystemen is er vermoedelijk soortgelijke documentatie.
Bedankt voor je reactie. Op de vraag waarom ik python moet gebruiken kan ik vrij kort zijn, omdat het mij gevraagd is.

Verder maak ik ook gebruik van programma's à la Bacula.

Ik ben echter ook al wat aan het knutselen geweest en heb ik het volgende bekomen:

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
31
32
33
34
#!/usr/bin/env python
import os
import sys

def main():

    cmd1 = "mt -f /dev/nst0 rewind"
    cmd2 = "tar -tvf /dev/nst0 >> inhoud"
    cmd = "mt -f /dev/nst0 fsf 1; echo $? > content"
    os.system(cmd1)
    os.system(cmd2)
    os.system(cmd)

    f = open('/home/uavdev/backup/content', 'r')
    line = f.read()
    f.close()
    print line

    while line[0] == "0":
        print "do something"
        os.system(cmd2)
        os.system(cmd)

        if line[0] != "0":
            break

    #else:

     #   print "exiting"
      #  sys.exit(1)


if __name__ == "__main__":
    main()


Let vooral niet op al de slordigheden en slechte programmeertaal, ik was maar wat aan het uittesten. Nu had ik nog wel een vraagje bij deze code. Als ik ze uitvoer krijg ik wel een tekstbestand (inhoud) waarin alle files staan die op tape staan.

Maar wat ik ook krijg is een infinite loop. Dit komt vast en zeker door de while loop. Echter heb ik de fout nog niet gevonden, misschien dat jullie de fout wel zien?

Alvast bedankt! :)

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 17:52
Die manier van coden, waarbij je steeds system() aanroept om een shellcommando uit te voeren, vind ik dus enorm lelijk, en heeft mijns inziens alleen maar nadelen ten opzichte van het schrijven van een shell script.
Maar wat ik ook krijg is een infinite loop. Dit komt vast en zeker door de while loop. Echter heb ik de fout nog niet gevonden, misschien dat jullie de fout wel zien?
Binnen de lus verandert line nooit, dus als je er eenmaal in zit, kom je er nooit meer uit.

Overigens kun je veel makkelijker de return value van system() gebruiken om te zien of je commando uitgevoerd kon worden.

Acties:
  • 0 Henk 'm!

  • Obviously
  • Registratie: November 2009
  • Laatst online: 23-07 11:58
Soultaker schreef op maandag 18 april 2011 @ 21:03:
Die manier van coden, waarbij je steeds system() aanroept om een shellcommando uit te voeren, vind ik dus enorm lelijk, en heeft mijns inziens alleen maar nadelen ten opzichte van het schrijven van een shell script.


[...]

Binnen de lus verandert line nooit, dus als je er eenmaal in zit, kom je er nooit meer uit.

Overigens kun je veel makkelijker de return value van system() gebruiken om te zien of je commando uitgevoerd kon worden.
Obviously schreef op maandag 18 april 2011 @ 19:16:
[...]
...
Let vooral niet op al de slordigheden en slechte programmeertaal, ik was maar wat aan het uittesten. ...
Ik ben een beginnend programmeur en ik ben een leek in het programmeren in python. Meer dan mijn best kan ik niet doen ;-)

Ik zal eens kijken welke functionaliteiten de return value van system() mij bieden...

Acties:
  • 0 Henk 'm!

  • Obviously
  • Registratie: November 2009
  • Laatst online: 23-07 11:58
Voor de geïnteresseerden:

Ik heb het momenteel zo opgelost:

Python:
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
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env python
import os
import sys

def main():

    cmd = "mt -f /dev/nst0 rewind"
    os.system(cmd)
    loopje()

def loopje():

    cmd1 = "mt -f /dev/nst0 rewind"
    cmd2 = "tar -tvf /dev/nst0 >> inhoud"
    cmd = "mt -f /dev/nst0 fsf 1; echo $? > content"

    if returnn() == 0:
        os.system(cmd2)
        os.system(cmd)
        print "a"
        returnn()
        loopje()
        print "b"

    else:
        print "c"
        sys.exit(1)

def returnn():
    f = open('/home/uavdev/backup/content', 'r')
    line = f.read()
    f.close

    if line[0] == "0":
        return 0
    else:
        return 1

if __name__ == "__main__":
    main()


De print commando's kan je natuurlijk weglaten, deze heb ik gebruikt om snel te kunnen debuggen. Misschien is het inderdaad omslachtig, maar het werkt alleszins voor mij.
Pagina: 1