Systemabhängige Standartprogramme erkennen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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
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()`.
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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.
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Bei Mac müsstest du glaub ich `open` verwenden.
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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 ;-)
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

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.
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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.
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

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"
the more they change the more they stay the same
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 1023
Registriert: Montag 30. Januar 2012, 16:38

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:
Antworten