Seite 1 von 1

Systemabhängige Standartprogramme erkennen

Verfasst: Sonntag 6. Mai 2012, 18:45
von Nobuddy
Hallo zusammen,

beschäftige mich gerade mit dem Öffnen einer Textdatei aus dem laufenden Script heraus, das aber nicht das Problem ist.
Dafür gibt es z.B.:

Code: Alles auswählen

os.system('kate ' + liste_untergruppenindex_path)
# ODER
subprocess.Popen(['kate', liste_untergruppenindex_path])
# ODER
process = subprocess.Popen(['kate', liste_untergruppenindex_path])
process.wait()
Was mich interessiert ist, wie ich eine Textdatei (z.B.) in verschiedenen Betriebssystemen öffnen kann, ohne deren Standartprogramme zu kennen.
Im obigen Beispiel, benutze ich kate.
Würde es dazu eine Möglichkeit geben, wie hier 'kate' anzusteuern, ohne daß der Namen im Script enthalten ist?

Grüße Nobuddy

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Sonntag 6. Mai 2012, 19:30
von BlackJack
@Nobuddy: Unter Linux würde ich ``xdg-open`` versuchen.

Code: Alles auswählen

$ xdg-open --help
xdg-open - opens a file or URL in the user's preferred application

Synopsis

xdg-open { file | URL }

xdg-open { --help | --manual | --version }

Use 'man xdg-open' or 'xdg-open --manual' for additional info.
Und unter Windows `os.startfile()`.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 09:15
von Nobuddy
Hallo BlackJack,

das mit 'xdg-open' funktioniert, ist mir noch aus der bash bekannt.

Code: Alles auswählen

os.system('xdg-open ' + liste_untergruppenindex_path)
# ODER
subprocess.Popen(['xdg-open', /pfad/zur/datei.endung])
# ODER
process = subprocess.Popen(['xdg-open', /pfad/zur/datei.endung])
process.wait()
Beim Googeln, bin ich auch auf `os.startfile()` für Windows gestoßen.

Ich arbeite ja mit Linux, aber um auch Windows zu berücksichtigen, dürfte das dann so funktionieren:

Code: Alles auswählen

linux = sys.platform.startswith('lin')
windows = sys.platform.startswith('win')

if linux:
    subprocess.Popen(['xdg-open', /pfad/zur/datei.endung])
elif windows:
    os.startfile(C:\pfad\zur\datei.endung)
else:
    print('Betriebssystem konnte nicht ermittelt werden.')
Bei MAC, bin ich mir nicht sicher, ob ich das auch das Linux-Konstrukt nehmen kann.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 09:45
von snafu
Bei Mac müsstest du glaub ich `open` verwenden.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 09:55
von Nobuddy
Bei mir öffnet sich gleich zweimal hintereinander kate mit der ausgewählten Datei, was ja nicht sein sollte.
Das ganze Konstrukt sieht so aus:

Code: Alles auswählen

def index_groupnumber():
    ###-1-## Basis-Haupt-/Untergruppen
    # LISTE_PRODUKTGRUPPEN.txt
    firstgroup = dict()
    secontgroup = dict()
    hauptgruppennummer = dict()
    untergruppennummer = dict()
    with codecs.open(liste_lieferproduktgruppen_path, "r") as infile:
        reader = csv.reader(infile, delimiter="\t", quotechar="^")
        for row in reader:
            firstgroup[row[0]] = row[0]
            secontgroup[row[1]] = row[1]
            if row[2] != '':
                hauptgruppennummer[row[0]] = row[2]
                untergruppennummer[row[1]] = row[2]


    ###-2-## Hauptgruppejn aktualisieren
    # LISTE_HAUPTGRUPPEN.txt
    daten = set()
    with codecs.open(liste_hauptgruppen_path, 'r') as infile:
            reader = csv.reader(infile, delimiter="\t", quotechar="^")
            for item in reader:
                if item[0] == '' and hauptgruppennummer.get(item[1]):
                    item[0] = hauptgruppennummer.get(item[1], item[0])

                daten.add(tuple(item))

    write_csv(liste_hauptgruppen_path, sorted(daten))


    for row in daten:
        if row[0] == '':
            linux = sys.platform.startswith('lin')
            windows = sys.platform.startswith('win')

            if linux:
                subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
            elif windows:
                pass
                # os.startfile(C:\pfad\zur\datei.endung)
            else:
                print('Betriebssystem konnte nicht ermittelt werden.')

    print('ende')
Wenn ich jetzt dies

Code: Alles auswählen

            if linux:
                subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
in

Code: Alles auswählen

            if linux:
                process = subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
                process.wait()
abändere, kommt die Fehlermeldung
line 51, in index_groupnumber
process.wait()
NameError: global name 'process' is not defined
was mich jetzt etwas ins Straucheln bringt.
wenn ich 'wait' hinten anhänge

Code: Alles auswählen

            if linux:
                subprocess.Popen(['xdg-open', liste_hauptgruppen_path]).wait
wird zwar das Öffnen des zweiten Fensters verhindert, aber '.wait' sorgt auch nicht dafür. daß die letzte print-Anweisung erst nach dem Schließen des zuvor geöffneten Programmes geschieht.

Welche Fehler, habe ich hier gemacht?

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 10:40
von EyDu

Code: Alles auswählen

if linux:
    process = subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
    process.wait()
Stimmt denn die Einrückung bei diesem Stück Code oder hast du vielleicht noch etwas anderes geändert?

Code: Alles auswählen

if linux:
    subprocess.Popen(['xdg-open', liste_hauptgruppen_path]).wait
Es wird nicht gewartet, da du wait gar nicht aufrufst.

Welche Fehler, habe ich hier gemacht?[/quote]

Es heißt übrigens Standard und nicht Standart ;-)

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 11:40
von Nobuddy
Hallo EyDu,

das Stück Code ist aus obigem Gesamtcode und ist an gleicher Stelle.
Das mit der Fehlermeldung 'NameError' konnte ich selbst klären. Nach dem ich 'process.wait()' an vorderer Stelle im Konstrukt gerückt hatte, blieb die Fehlermeldung aus.

Was mich noch irritiert ist, daß zweimal kate mit der ausgewählten Datei gestartet wird.
Evtl. eine Idee, warum dies der Fall ist?

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 11:52
von EyDu
Nobuddy hat geschrieben:Was mich noch irritiert ist, daß zweimal kate mit der ausgewählten Datei gestartet wird.
Evtl. eine Idee, warum dies der Fall ist?
Ich würde einfach mal eine Menge print-Anweisungen im Code unterbringen (oder den Debugger verwenden) und schauen, wann wo welche Werte gebunden wurden. Dann solltest du recht schnell dahinter kommen.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 12:07
von Nobuddy
Das mit dem doppelten Programmaufruf konnte ich lösen, in dem ich habe dies

Code: Alles auswählen

    for row in daten:
        if row[0] == '':
            linux = sys.platform.startswith('lin')
            windows = sys.platform.startswith('win')

            if linux:
                subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
            elif windows:
                pass
                # os.startfile(C:\pfad\zur\datei.endung)
            else:
                print('Betriebssystem konnte nicht ermittelt werden.')
so abgeändert

Code: Alles auswählen

    for row in daten:
        if row[0] == '':
            edit = 'yes'
            linux = sys.platform.startswith('lin')
            windows = sys.platform.startswith('win')

    if edit == 'yes':
        if linux:
            process = subprocess.Popen(['xdg-open', liste_hauptgruppen_path])
            process.wait()
        elif windows:
            pass
            # os.startfile(C:\pfad\zur\datei.endung)
        else:
            print('Betriebssystem konnte nicht ermittelt werden.')
Leider funktioniert das mit dem 'wait', nicht wie gewünscht.
Eigentlich sollte erst nach dem Schließen des zuvor aufgerufenen Programmes, das Script weiterfahren.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 13:06
von Dav1d
Wenn dir die Ausgabe des gestarteten Programms egal ist würde ich subprocess.call verwenden.

Das hier funktioniert bei mir:

Code: Alles auswählen

from subprocess import call
call(['kate', 'test.py'])
print 'exit Kate'
Statt "edit = 'yes'", solltest du lieber True/False nutzen, "edit = True"

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 13:33
von Leonidas
Ich würde auch nicht auf das Betriebssystem prüfen, sondern gucken ob ``os.startfile`` existiert (= Windows) ansonsten ``xdg-open`` ausprobieren (Free Desktop) und wenn das nicht existiert dann ``open`` (Mac OS X). Bei letzterem vielleicht tatsächlich noch auf Mac prüfen, weil ``open`` ist ein doch etwas arg generischer Name.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 13:45
von Nobuddy
Leonidas, Danke für die Erläuterung, das kann ich dann noch nachträglich ändern.

Was mich momentan beschäftigt, ist daß ich eine Voraussetzung schaffe, die es ermöglicht das Script solange anzuhalten, bis `xdg-open` bei mir startet dann kate, bis dann wieder kate geschlossen ist.
Dann erst sollte es mit dem Scriptverlauf weitergehen.

Gibt es da eine Möglichkeit?

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 13:56
von Leonidas
Nobuddy hat geschrieben:Was mich momentan beschäftigt, ist daß ich eine Voraussetzung schaffe, die es ermöglicht das Script solange anzuhalten, bis `xdg-open` bei mir startet dann kate, bis dann wieder kate geschlossen ist.
Dann erst sollte es mit dem Scriptverlauf weitergehen.
Sowas unterstützt ``xdg-open`` nicht, habe gerade geschaut und es gibt dazu eine Reihe von Diskussionen im Internet.

Re: Systemabhängige Standartprogramme erkennen

Verfasst: Montag 7. Mai 2012, 17:29
von Nobuddy
Ich habe mir mal mit einer Ja/Nein-Abfrage beholfen.
Damit unterbreche ich dann das Script und nach Bestätigung mit 'Ja' läuft dann das Script weiter.

Ist vielleicht nicht so elegant, aber es funktioniert. :wink: