marlem
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Hallo, mit Hilfe von Mitgliedern des Forums habe ich herausgefunden, in welchem Verzeichnis die Libreoffice-Dateien sind bei Ubuntu.
Jetzt habe ich folgendes versucht:
| elif varkommando == "tabellenkalkulation ubuntu":
process = subprocess.Popen([os.path.abspath("/usr/lib/libreoffice/program/soffice --writer $@")],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
Dieser Code bringt folgende Fehlermeldung: > Traceback (most recent call last):
File "MarlemsPyAssistent.py", line 819, in <module>
mainmenu()
File "MarlemsPyAssistent.py", line 68, in mainmenu
pyassistent(kommando)
File "MarlemsPyAssistent.py", line 462, in pyassistent
process = subprocess.Popen([os.path.abspath("/usr/lib/libreoffice/program/soffice --writer $@")],
File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/libreoffice/program/soffice --writer $@' Frage:
Was habe ich falsch gemacht?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Kannst du ein bisschen was dazu erzählen, wie du auf os.path.abspath("/usr/lib/libreoffice/program/soffice --writer $@") gekommen bist? $@ kenne ich aus Shell-Skripten zum Weiterreichen der Argumente. Die Methoden aus dem subprocess-Modul erwarten standardmäßig eine Liste mit dem Programm und seinen Argumenten und aus Sicherheitsgründen findet standardmäßig auch keine Evaluation der Argumente durch eine Shell statt (was man ändern könnte). Ich vermute, dass du sowas willst:
| import sys
# [...]
elif varkommando == "tabellenkalkulation ubuntu":
process = subprocess.Popen(["/usr/lib/libreoffice/program/soffice", "--writer", sys.argv[1:]]),
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
subprocess.Popen muss man meistens nicht nutzen - moderne Python3-Versionen bringen subprocess.run mit, das ein bequemeres Interface hat. Statt ellenlangen if-else Statements könnte man z.B. auch ein Dictionary bemühen: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | actions = {
"tabellenkalkulation": ["/usr/lib/libreoffice/program/soffice", "--calc"],
"textverarbeitung": ["/usr/lib/libreoffice/program/soffice", "--writer"],
"präsentation": ["/usr/lib/libreoffice/program/soffice", "--impress"]
}
action = input("\n".join(
("Was willst du starten?",
*actions,
''),
)
).strip()
try:
args = actions[action]
except KeyError
print(f"unbekannte Auswahl {action}", file=sys.stderr)
args.extend(sys.argv[1:])
process = subprocess.run(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
seahawk1986 schrieb: Kannst du ein bisschen was dazu erzählen, wie du auf os.path.abspath("/usr/lib/libreoffice/program/soffice --writer $@") gekommen bist? $@ kenne ich aus Shell-Skripten zum Weiterreichen der Argumente.
den Pfad habe ich mit Hilfe von diesem Thread:
https://forum.ubuntuusers.de/topic/libreoffice-in-welchem-verzeichnis-finde-ich-d/ Generell die Lösung habe ich ergoogelt!
Statt ellenlangen if-else Statements könnte man z.B. auch ein Dictionary bemühen:
Der Code ist nur zum Testen ob es überhaupt geht, was ich vorhabe.
Wenn es geht, werden die Daten in einer JSON-Datei gespeichert. Dein Code hat leider nicht funktioniert: Eingabe bestätigen mit Enter-Taste: textverarbeitung ubuntu
Traceback (most recent call last):
File "MarlemsPyAssistent.py", line 819, in <module>
mainmenu()
File "MarlemsPyAssistent.py", line 68, in mainmenu
pyassistent(kommando)
File "MarlemsPyAssistent.py", line 458, in pyassistent
process = subprocess.Popen(["/usr/lib/libreoffice/program/soffice", "--writer", sys.argv[1:]],
File "/usr/lib/python3.8/subprocess.py", line 854, in init
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib/python3.8/subprocess.py", line 1637, in _execute_child
self.pid = _posixsubprocess.fork_exec(
TypeError: expected str, bytes or os.PathLike object, not list
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Ah, entschuldige, man muss die Liste noch mit einem Sternchen entpacken: | import sys
# [...]
elif varkommando == "tabellenkalkulation ubuntu":
process = subprocess.Popen(["/usr/lib/libreoffice/program/soffice", "--writer", *sys.argv[1:]]),
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
Wobei ich immer noch nicht sicher bin, ob du das überhaupt brauchst - akzeptiert dein MarlemsPyAssistent.py überhaupt Starargumente?
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Du Held! Funktioniert. Danke!
Nein, Startargumente akzeptiert meine Anwendung nicht!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
Dann kannst du *sys.argv[1:] auch weglassen.
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Hallo, Ich habe jetzt diese Pyhon-Funktion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | def programmezumausfuehrenlesen(jsondateiname,programmname):
with open(jsondateiname,"r", encoding="utf-8") as jsondatei:
jsondaten = json.load(jsondatei)
gefunden = 0
for eintrag in jsondaten:
veintrag = eintrag["Programmname"]
veintrag = veintrag.lower().lstrip()
vprogrammname = programmname.lower().lstrip()
if veintrag == vprogrammname:
process = subprocess.Popen([eintrag["Verzeichnis"]],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
gefunden = 1
if gefunden == 0:
print("Programm ist nicht bekannt und konnte deswegen nicht gestartet werden.")
time.sleep(6)
|
und diese JSON-Datei:
| > [
{"Programmname":"tabellenkalkulation ubuntu", "Verzeichnis":"/usr/lib/libreoffice/program/soffice --calc"},
{"Programmname":"textverarbeitung ubuntu", "Verzeichnis":"/usr/lib/libreoffice/program/soffice --writer"},
{"Programmname":"tabellenkalkulation windows", "Verzeichnis":"C:/Program Files/LibreOffice/program/scalc.exe"},
{"Programmname":"textverarbeitung windows", "Verzeichnis":"C:/Program Files/LibreOffice/program/swriter.exe"}
]
|
Die Aufrufe tabellenkalkulation windows und textverarbeitung windows unter Windows 10 funktionieren perfekt. Der Aufruf tabellenkalkulation ubuntu in der console von Ubuntu bringt folgender Fehlermeldung: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | > Eingabe bestätigen mit Enter-Taste: programm tabellenkalkulation ubuntu
Traceback (most recent call last):
File "MarlemsPyAssistent.py", line 822, in <module>
mainmenu()
File "MarlemsPyAssistent.py", line 68, in mainmenu
pyassistent(kommando)
File "MarlemsPyAssistent.py", line 474, in pyassistent
programmezumausfuehrenlesen(jsonpfad,vparameter)
File "MarlemsPyAssistent.py", line 451, in programmezumausfuehrenlesen
process = subprocess.Popen([eintrag["Verzeichnis"]],
File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/libreoffice/program/soffice --calc'
|
Frage:
Was habe ich falsch gemacht?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
marlem schrieb: Frage:
Was habe ich falsch gemacht?
Wie schon in meiner ersten Antwort erklärt erwarten die Subprocess Module eine Liste aus Argumenten. Eine Möglichkeit wäre das JSON umzustrukturieren - wenn man auf die Liste verzichtet, kann man sich das iterieren über die Einträge sparen und stattdessen einfach im Dictionary nachsehen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | {
"Programme": {
"tabellenkalkulation ubuntu": [
"/usr/lib/libreoffice/program/soffice",
"--calc"
],
"textverarbeitung ubuntu": [
"/usr/lib/libreoffice/program/soffice",
"--writer"
],
"tabellenkalkulation windows": [
"C:/Program Files/LibreOffice/program/scalc.exe"
],
"textverarbeitung windows": [
"C:/Program Files/LibreOffice/program/swriter.exe"
]
}
}
|
Und dann eine dazu passende Änderung im Code - ich würde empfehlen Exceptions zu nutzen, um Fehler abzufangen, das ist der Weg den Python dafür vorsieht, Flags zu setzen bringt da wenig:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | def programmezumausfuehrenlesen(jsondateiname, programmname):
with open(jsondateiname,"r", encoding="utf-8") as jsondatei:
jsondaten = json.load(jsondatei)
if (argumente := jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])):
try:
process = subprocess.run(argumente, check=True, capture_output=True)
except IOError as err:
print(f"Programm konnte nicht ausgeführt werden: {err}", file=sys.stderr)
except subprocess.CalledProcessError as err:
print(f"Das Ausführen von {argumente} ist fehlgeschlagen: {err}",
file=sys.stderr)
time.sleep(6) # wozu?
else:
print(f"Programmeintrag für {programmname} ist nicht bekannt und konnte deswegen nicht gestartet werden.",
file=sys.stderr)
|
PS: Brauchst du die Pipes für stdin und stdout des aufgerufenen Programms? Falls nicht würde ich das weglassen (bzw. das oben genutzte capture_output), sonst können dir Buffer vollaufen, wenn das gestartete Programm zu gesprächig ist. PPS: Generell stehe ich mit deutschen Variablennamen immer etwas auf Kriegsfuß, weil Python idealerweise so aussieht, dass es einen halbegs lesbaren englischen Satz ergibt und denglisch da nicht unbedingt hilfreich ist...
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Vielen Dank! Mein Python kommt mit folgender Zeile nicht klar:
| if (argumente := jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])):
|
ich nutze Python 3.7 und das kennt das irgendwie nicht.
time.sleep(6)
Damit der Anwender Zeit hat die Meldung zu lesen
Brauchst du die Pipes für stdin und stdout des aufgerufenen Programms?
Ich weiß nicht was Pipes sind
Ich lerne Python seit März 2020
PPS: Generell stehe ich mit deutschen Variablennamen immer etwas auf Kriegsfuß, weil Python idealerweise so aussieht, dass es einen halbegs lesbaren englischen Satz ergibt und denglisch da nicht unbedingt hilfreich ist...
ich kann gut englisch, aber irgendwie benenne ich gerne meine funktionen und variabeln in deutsch.
Macht der Gewohnheit!
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11179
Wohnort: München
|
marlem schrieb: Vielen Dank! Mein Python kommt mit folgender Zeile nicht klar:
| if (argumente := jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])):
|
ich nutze Python 3.7 und das kennt das irgendwie nicht.
Ja, das ist der mit Python 3.8 neu eingeführte Walrus-Operator - für ältere Python-Versionen würde das so aussehen:
| argumente = jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])
if argumente:
|
Brauchst du die Pipes für stdin und stdout des aufgerufenen Programms?
Ich weiß nicht was Pipes sind
Kommunikationskanäle zwischen Prozessen (vgl. z.B. Pipe_(Informatik)). Wenn du stdin=subprocess.PIPE angibst, dann hast du die Möglichkeit dem aufgerufenen Programm Daten zu senden und wenn du stdout=subprocess.PIPE nutzt, kannst du dessen Ausgaben auf stdout verarbeiten. Wenn man das nicht braucht, sollte man die Datei-Deskriptoren dafür nicht öffnen, damit sich da (gerade auf den Ausgabekanälen) keine Daten anstauen, die dann den dazugehörigen Puffer an seine Grenzen bringen können.
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Das erste Problem habe ich gelöst:
| argumente = jsondaten.get("Programme", {}).get(programmname.lower.lstrip())
if ( argumente, []):
|
Die nächste stelle die PyCharm meckert ist die hier:
| except IOError as err:\
^
SyntaxError: invalid syntax
|
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
marlem schrieb:
argumente = jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])
if argumente: }}}
okay, meine Lösung war nicht ganz richtig. Habe Deine jetzt übernommen.
Danke!
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Problem gelöst.
Die Einrückung hat ihm nicht gepasst!
Code compiliert jetzt wieder. Danke!
|
marlem
(Themenstarter)
Anmeldungsdatum: 12. Juli 2016
Beiträge: 139
Wohnort: Dußlingen
|
Leider noch immer nicht pefekt. Beim Ausführem vom Programm kommt diese Fehlermeldung:
1
2
3
4
5
6
7
8
9
10
11
12 | > Traceback (most recent call last):
File "MarlemsPyAssistent.py", line 843, in <module>
mainmenu()
File "MarlemsPyAssistent.py", line 70, in mainmenu
mainmenu()
File "MarlemsPyAssistent.py", line 69, in mainmenu
pyassistent(kommando)
File "MarlemsPyAssistent.py", line 495, in pyassistent
programmezumausfuehrenlesen(jsonpfad,vparameter)
File "MarlemsPyAssistent.py", line 446, in programmezumausfuehrenlesen
argumente = jsondaten.get("Programme", {}).get(programmname.lower.lstrip(), [])
AttributeError: 'list' object has no attribute 'get'
|
Da brauche ich Deine Hilfe, das blicke ich als Python-Neuling nicht.
|