ubuntuusers.de

perl - KSnapshot mit DCOP Interface?

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

Dexi

Avatar von Dexi

Anmeldungsdatum:
17. Februar 2008

Beiträge: Zähle...

Hallo allerseids,

ich habe ein perl script für eine Anwendung geschrieben und bräuchte die Möglichkeit einen screenshot zu machen. Dazu würde ich aber ungern Module verwenden bzw zusätzlich installieren müssen.

Es gibt ja die Möglichkeit z.B.: Ksnapshot zu scripten mittels DCOP interface.

Leider habe ich davon wenig Ahnung, da ich mich erst seid kurzem mit Linux befasse und finde dazu auch relativ wenig im netz.

Kann mir jemand eventuell helfen ein kurzes Script zu machen oder link geben, wie ich einen Screenshot machen kann?

Das wäre prima.

Danke, lg

MrKanister

Anmeldungsdatum:
13. Oktober 2007

Beiträge: 2105

Hallo Dexi,

schau dir mal den Thread http://forum.ubuntuusers.de/topic/148939/ an. Dort geht es auch um die verwendung von "dcop" und "ksnapshot", allerdings nicht in Perl.

Vieleicht kannst du damit was anfangen 😉

Gruß martin

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

import aus dem Image-Magick-Paket als Subprozess aufzurufen wäre unabhängig von der verwendeten Desktop-Umgebung.

MrKanister

Anmeldungsdatum:
13. Oktober 2007

Beiträge: 2105

Lunar hat geschrieben:

import aus dem Image-Magick-Paket als Subprozess aufzurufen wäre unabhängig von der verwendeten Desktop-Umgebung.

Zu Subprozessen habe ich eine kurze Frage:
In wieweit ist es sinnvoll, eventuell auch besser für das Laufzeitverhalten, auf die in Perl integrierten Befehle zurückzugreifen, anstatt einen Subprozess zu starten?

zB. gibt es ja das Konsolen-Tools "mkdir" und die Perl-eigene Funktion "mkdir()".

Hintergrund ist, dass es ja nicht für alles auch ein entsprechendes Modul für Perl gibt.

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Mr. Kanister hat geschrieben:

Lunar hat geschrieben:

import aus dem Image-Magick-Paket als Subprozess aufzurufen wäre unabhängig von der verwendeten Desktop-Umgebung.

Zu Subprozessen habe ich eine kurze Frage:
In wieweit ist es sinnvoll, eventuell auch besser für das Laufzeitverhalten, auf die in Perl integrierten Befehle zurückzugreifen, anstatt einen Subprozess zu starten?

Über das Laufzeitverhalten kann man in solchen Fällen nur spekulieren, einfacher zu programmieren ist es dagegen eigentlich immer.

Mr. Kanister hat geschrieben:

Hintergrund ist, dass es ja nicht für alles auch ein entsprechendes Modul für Perl gibt.

Dann bleibt dir ja keine Wahl 😉

audax

Avatar von audax

Anmeldungsdatum:
15. September 2006

Beiträge: 1253

Mr. Kanister hat geschrieben:

Hintergrund ist, dass es ja nicht für alles auch ein entsprechendes Modul für Perl gibt.

Wie bitte? Gibt es, such nur besser. Es gibt immer ein Perl Modul 😀

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

zB. gibt es ja das Konsolen-Tools "mkdir" und die Perl-eigene Funktion "mkdir()".

Und der Befehl mkdir gibt es auf jedem OS für das es auch Perl gibt? Um mal ein paar OSe/Platformen zu nennen für das es Perl gibt.

Amiga, Atari, BeOS, BSD, Cygwin, MS-Dos, HP-UX, AIX, Solaris, Linux, Mac OS, NextStep, Plan 9, OS/2, Pocket PC, Psion, SGI, Symbian, VMS, Win32, WinCE, Win95/98/ME und etliche weitere Platformen/Betriebssysteme.

1) Befehle in Perl sind also deswegen zu bevorzugen da du Platformunabhängiger bist.
2) Zur Performance ist es in der Regel langsamer externe Befehle zu verwenden. Da jeder externe Aufruf ein fork startet oder eine subshell und du den befehl ausführen musst. Wenn du nur Perl nutzt hast du ein einzigen Prozess der läuft. (betonung liegt auf "in der regel")
3) Kannst du Sicherstellen das der aufruf von einem shell Befehl wie mkdir auch die gleichen Optionen auf den unterschiedlichen Systemen hat. Oder ob es überhaupt das gleiche macht? Das ganze ist natürlich eine rhetorische Frage. Du kannst es nicht. Du weist auch nicht ob jemand dir ein anderes mkdir untergeschoben hat das etwas ganz anderes macht. Unterschiedliche Optionen von Shell befehlen findest du schon zwischen den einzelnen Versionen. Große unterschiede findest du z.B wenn du BSD, oder Unix Shell Befehle mit dennen unter einem GNU/Linux System vergleichst.
4) Es ist ansonsten noch unsicherer. Befehle einem externen Kommando zu übergeben ist einfach Fehleranfällig.
5) Die Programmierung mit Modulen ist eigentlich immer einfacher als mit der Shell vernünftig zu hantieren.

Einen Subprozess zu starten sollte man aber wenn Möglich so gut wie immer vermeiden. Aber es hängt trotzdem vom Anwendungsfall ab was man tut. Manchmal geht es evtl. auch nicht anders.

Hintergrund ist, dass es ja nicht für alles auch ein entsprechendes Modul für Perl gibt.

Dann schreib ein Perl Modul dafür. 😉

Zum Thema Screenshot:

use Imager::Screenshot qw(screenshot);
my $image = screenshot();
$image->write( file => 'screenshot.png', type => 'png' )
    or die $image->errstr;

Funktioniert angeblich zumindest auf Win32 und Linux.

–-

Die Generelle Aussage das man aber möglichst alles ohne Module machen möchte finde ich einfach nur dämlich.

MrKanister

Anmeldungsdatum:
13. Oktober 2007

Beiträge: 2105

@Irgendein Admin:
Da ich nicht mit der Fülle an Antworten gerechnet habe, ist es vielleicht sinnvoll diesen Teil abzutrennen und in einen eigenen Thread auszulagern, etwas unter dem Namen: "Notwendigkeit von Subprozessen in Perl"
Danke 😉

@Lunar, audax und Sid Burn:
Danke für eure Antworten...
Ich muss sagen, dass mich das Argument der Platformunabhängigkeit am meisten überzeugt hat. Daran hatte ich garnicht gedacht.

Auch habe ich (Schande über mein Haupt), das Archiv von CPAN deutlich unterschätzt...ich bin gerade praktisch perplex, was es da alles gibt oO

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Sid Burn hat geschrieben:

2) Zur Performance ist es in der Regel langsamer externe Befehle zu verwenden. Da jeder externe Aufruf ein fork startet oder eine subshell und du den befehl ausführen musst. Wenn du nur Perl nutzt hast du ein einzigen Prozess der läuft. (betonung liegt auf "in der regel")

Zumindest unter Linux ist das Erzeugen eines neuen Prozesses relativ billig. Dagegen sind viele Operationen in dynamischen Sprachen wie Python relativ teuer, weil komplexe Bindungen aufgelöst werden müssen. Hinzu kommt, dass externe Kommandos oft auch nativ kompilierte Dateien sind, die unter Umständen performanter sind als entsprechende Implementierungen in der Sprache selbst. Ein konkretes Beispiel, in dem der Aufruf eines Subkommandos sinnvoll ist, wäre Videokodierung: Ein in Perl implementierter MPEG-Codec kann nie so effizient sein, wie die transcode oder ffmpeg Implementierungen, die mitunter Assembler oder zumindest hochoptimiertes C nutzen, und noch dazu Gebrauch von allerhand moderner Befehlssatzerweiterungen machen.

Natürlich trifft das auf mkdir jetzt nicht so richtig zu, aber das Aufrufen von Subkommandos ist nicht generell falsch.

Sid Burn hat geschrieben:

3) Kannst du Sicherstellen das der aufruf von einem shell Befehl wie mkdir auch die gleichen Optionen auf den unterschiedlichen Systemen hat. Oder ob es überhaupt das gleiche macht? Das ganze ist natürlich eine rhetorische Frage. Du kannst es nicht. Du weist auch nicht ob jemand dir ein anderes mkdir untergeschoben hat das etwas ganz anderes macht. Unterschiedliche Optionen von Shell befehlen findest du schon zwischen den einzelnen Versionen. Große unterschiede findest du z.B wenn du BSD, oder Unix Shell Befehle mit dennen unter einem GNU/Linux System vergleichst.

Windows fällt hier natürlich aus dem Rahmen, aber unter allen Unix-Derivaten und Linux-Distributionen gilt der POSIX-Standard in weiten Teilen. Solange man sich an den POSIX Standard hält, ist man weitestgehend auf der sicheren Seite.

Sicherstellen kannst du das im Übrigen auch nicht für Perl-Befehle. Die Garantie, dass Perl auf HP-UX das selbe macht wie unter Debian, ist nicht wirklich größer als die Garantie, die POSIX dir auf das Verhalten essentieller Shellbefehle gibt.

Sid Burn hat geschrieben:

4) Es ist ansonsten noch unsicherer. Befehle einem externen Kommando zu übergeben ist einfach Fehleranfällig.

Das bedarf einer Erläuterung!

Sid Burn hat geschrieben:

Die Generelle Aussage das man aber möglichst alles ohne Module machen möchte finde ich einfach nur dämlich.

ack. Die umgekehrte Aussage, immer möglichst alles mit Modulen zu machen, ist aber in vielen Fällen genauso dämlich. 😉

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4694

Wohnort: Berlin

Möglichst alles mit Modulen zu machen, für das es Module gibt, finde ich nicht so dämlich. Das Beispiel mit dem MPEG-Kodieren hinkt, weil solche Module kaum in reinem Perl geschrieben werden, sondern eine API zum Beispiel zu ffmpeg bereit stellen.

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Marc 'BlackJack' Rintsch hat geschrieben:

Möglichst alles mit Modulen zu machen, für das es Module gibt, finde ich nicht so dämlich. Das Beispiel mit dem MPEG-Kodieren hinkt, weil solche Module kaum in reinem Perl geschrieben werden, sondern eine API zum Beispiel zu ffmpeg bereit stellen.

Ich kenne mich mit Perl nicht aus, deswegen frage ich dich nach Python:
Kennst du ein Python-Modul für transcode, ffmpeg oder auch nur lame, welches nicht intern die entsprechenden Kommandos aufruft, sondern die API nutzt?

Sid Burn, fühle dich berufen, mir Perl-Module zu nennen, die diese Kriterien erfüllen!

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4694

Wohnort: Berlin

Och komm, lies doch bitte nochmal den ersten Satz meines Beitrags. Das man keine Module für Sachen benutzen kann, für das es keine gibt, ist ja wohl irgend wo klar.

So auf Anhieb fällt mir für Python kein Modul ein. Pymedia benutzt vielleicht ffmpeg. Und für OGG Vorbis gibt es das ogg.vorbis-Modul, mit dem man über libvorbis und libogg ohne Umweg über die Kommandozeilenprogramme (de)kodieren kann.

Und selbst wenn so ein Modul nur die externen Programme aufruft, ist es in der Regel vorzuziehen, weil man dann das Rad nicht noch einmal neu erfinden muss. Das problematische an externen Programmen ist ja, das man sich auf verschiedene Arten um Fehler kümmern muss, und wenn schon jemand anders das gemacht hat, und zum Beispiel Rückgabecodes von einem Programm in Ausnahmen übersetzt und dafür vielleicht stderr des externen Programms auswertet, dann muss ich das ja nicht alles noch einmal, wahrscheinlich schlechter, selbst implementieren.

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Marc 'BlackJack' Rintsch hat geschrieben:

Och komm, lies doch bitte nochmal den ersten Satz meines Beitrags. Das man keine Module für Sachen benutzen kann, für das es keine gibt, ist ja wohl irgend wo klar.

Das es dafür keine Module gibt, wusste ich gar nicht 😉 Das waren lediglich ein paar Beispiele für Programme, die ihre Funktionalität nicht über eine komfortable API exportieren.

Marc 'BlackJack' Rintsch hat geschrieben:

Und selbst wenn so ein Modul nur die externen Programme aufruft, ist es in der Regel vorzuziehen, weil man dann das Rad nicht noch einmal neu erfinden muss. Das problematische an externen Programmen ist ja, das man sich auf verschiedene Arten um Fehler kümmern muss, und wenn schon jemand anders das gemacht hat, und zum Beispiel Rückgabecodes von einem Programm in Ausnahmen übersetzt und dafür vielleicht stderr des externen Programms auswertet, dann muss ich das ja nicht alles noch einmal, wahrscheinlich schlechter, selbst implementieren.

Dem stimme ich ja auch zu... nur schreiben sich diese Module ja nicht von selbst 😉 Stände ich vor der Aufgabe, ein Modul für MP3-Konvertierung zu schreiben, würde ich das eher mithilfe von subprocess und lame implementieren als mit liblame und ctypes (oder gar einer Python-Extension) 😉

Im Übrigen gibt es ja auch noch Fälle, in denen eine interne Implementierung auch gar nicht möglich ist, wie z.B.: im Fall von ping.

Summa summarum: Natürlich ist es besser, ein gutes Modul für die Sprache zu nutzen, aber man sollte eben auch in Betracht ziehen, dass es Fälle gibt, in denen das nicht sinnvoll ist, wie z.B. wenn die Implementierung dadurch übermäßig kompliziert wird oder das Modul fehlerhaft ist.

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

Zumindest unter Linux ist das Erzeugen eines neuen Prozesses relativ billig. Dagegen sind viele Operationen in dynamischen Sprachen wie Python relativ teuer, weil komplexe Bindungen aufgelöst werden müssen. Hinzu kommt, dass externe Kommandos oft auch nativ kompilierte Dateien sind, die unter Umständen performanter sind als entsprechende Implementierungen in der Sprache selbst. Ein konkretes Beispiel, in dem der Aufruf eines Subkommandos sinnvoll ist, wäre Videokodierung: Ein in Perl implementierter MPEG-Codec kann nie so effizient sein, wie die transcode oder ffmpeg Implementierungen, die mitunter Assembler oder zumindest hochoptimiertes C nutzen, und noch dazu Gebrauch von allerhand moderner Befehlssatzerweiterungen machen.

Deswegen habe ich ja extra in Klammern nochmal angehangen

(betonung liegt auf "in der regel")

Das Argument was du nun bringst daran habe ich schon gedacht. Deswegen aber trotzdem bereits vorhandene Module nicht zu nutzen ergibt trotzdem keinen Sinn.

Denn wenn man ein Modul nutzt das ebenso nichts anderes tut als einen Subprocess zu starten, dann hat es keinen Vorteil wenn man es selber Manuel macht. Hier greiftt dann wiederrum Punkt 5) nämlich das die Programmierung einfacher ist. Und punkt 4) indem sinne auch. Nämlich das die größten Fallen wohl schon umgangen sind. Das FFmpeg Modul für Perl macht ja auch nichts anderes. Sollte FFmpeg als reines Perl Modul eingebunden sein. Sprich mit C-Code dann hast du so wie Marc sagte sowieso fast keinen Performance Unterschied da diese Sachen meist sowieso in C geschrieben sind.

Die einzelnen Argumenten kann man also nicht auseinander reißen sondern man muss sie zusammen sehen. Es kann sogar oft noch Punkt 3) damit abgedeckt werden. z.B. könnte ein Modul eine bestimmte Aufgabe mit Shell Befehlen verwenden. Allerdiengs je nachdem auf welchen OS du arbeitest ganz andere Shell Befehle genutzt werden. Du als Nutzer musst dich also auch nicht um die Platformunabhängigkeit kümmern da es jemand schon für dich getan hat. Und du hast wieder Punkt 4) und 5) als Vorteil vorallem ddeswegen da du eine einheitliche API hast.

Windows fällt hier natürlich aus dem Rahmen, aber unter allen Unix-Derivaten und Linux-Distributionen gilt der POSIX-Standard in weiten Teilen. Solange man sich an den POSIX Standard hält, ist man weitestgehend auf der sicheren Seite.

Sofern du den kompletten POSIX Standard auswendig kennst und genau weißt welchen Kommandozeilen Parameter POSIX ist und was nicht. Kannst du das gerne nutzen. Ich kenne den POSIX Standard nicht auswendig weder weiß ich welche Parameter von so einem Tool wie sed etc. nun POSIX sind und welche nicht. Ich weiß ehrlich gesagt noch nichtmal welche Kommndaozeilen Tools zu POSIX hinzugehören. Und ehrlich gesagt. Will ich es auch nicht Wissen. Bei Perl weiß ich das es ein m//, s///, mkdir(), grep(), ... gibt und sie immer das gleiche tun. Auch ohne POSIX Standard.

Weiterhin sei dazu gesagt. Die einzelnen Linux Distribution sind nicht Vollständig POSIX Kompatibel. Ansonsten ist Windows mehr POSIX Kompatibel alst du denkst. Mit SFU Windows_Services_for_Unix sollte es sogar vollständig POSIX Kompatibel sein. Und ab Windows Server 2003 R2 sind diese Teile sogar fest in Windows eingebaut.

Sicherstellen kannst du das im Übrigen auch nicht für Perl-Befehle. Die Garantie, dass Perl auf HP-UX das selbe macht wie unter Debian, ist nicht wirklich größer als die Garantie, die POSIX dir auf das Verhalten essentieller Shellbefehle gibt.

Ich weiß aber das es die Kommandos gibt und das sie die gleichen Parameter haben. Und wichtiger ist, dass ich den POSIX Standard nicht auswendig kennen muss. Platformspezifisches ist Dokumentiert und kann ich nachschlagen. http://perldoc.perl.org/index-platforms.html Ansonsten hilft mir der VErweis auch nichts wenn ich weiß das das OS nicht POSIX Kompatible ist. Inwiefern hilft es mir jetzt das ich weiß das ein Default Windows nicht vollständig POSIX kompatibel ist? Ein Perl Programm das mkdir() aufruft Funktioniert da trotzdem. 😉

4) Es ist ansonsten noch unsicherer. Befehle einem externen Kommando zu übergeben ist einfach Fehleranfällig.

Das bedarf einer Erläuterung!

Unsicherer deswegen, weil du nie weißt ob der externe Befehl den du aufrufst auch wirklich der ist denn du meinst. Wenn ich Beispielsweise mkdir als Shell Befehl aufrufe, was wird dann genutzt? Es wird der genutzt der als erstes in $PATH gefunden wird. Ob es der ist den du meinst und haben möchtest ist jetzt eine Frage. Aus diesem Grund wird bei Perl auch im Taint Modus $ENV{$PATH} komplett gelöscht. Und du musst explizit einen Path angeben. Oder das Kommando mit einem absoluten Pfad aufrufen. Bei beiden Sachen verlierst du aber bei beiden die Platformunabhängigkeit. Auser natürlich du fragst es in deinem Programm ab und setzt es je nach OS anders.

Fehleranfällig deswegen: Stell dir vor du willst mittels SQL Daten zu einer Datenbank hinzufügen. Du kannst dann natürlich auch den "mysql" (im falle das MySQL genutzt wird) benutzen. Und dann die SQL generieren und es per Kommandozeile übergeben. Wie gut sowas ist solltest du selber Wissen. Richtig Fehleranfällig wird es aber wenn du Daten von Kommandos ausliest. z.B. von ls weil du die genaue Information ob dort nun Tabulator war oder paar Leerzeichen nichtmehr herausfinden kannst. Oder ob ein Newline jetzt zum Befehl hinzugehört. Wenn du ein SQL Select machst möchte ich sehen wie einfach du mal eben die Tabellenartige Ausgabe ausliest und parst.

In dem falle sei sogar hingewiesen das solch eine Lösung sogar langsamer ist. Zwar nutze ich mit mysql eine vorkompilierte Datei. Wenn ich aber etliche Daten hinzufüge muss mit jedem Aufruf von "mysql" eine Datenbankverbondung aufgebaut werden. Wenn ich DBI nutze muss dies nicht getan werden. Bei jedem Aufruf muss der SQL Statement geparsed werden. Bei DBI muss dank Prepared Statements sowas auch nicht getan werden.

ack. Die umgekehrte Aussage, immer möglichst alles mit Modulen zu machen, ist aber in vielen Fällen genauso dämlich. 😉

Finde ich nicht. Erklärung steht ja oben. Wenn es Module gibt selbst wenn sie Subprocesse starten kannst du ja wie ich oben schrieb etliche Vorteile haben.

Und eventuell kann es auch zu einem Späteren Zeitpunkt sein das ein Modul heraus kommt das dann in C Implementiert ist, aber die gleiche API hat, und du deswegen das Modul einfach austauschen kannst.

Dexi

(Themenstarter)
Avatar von Dexi

Anmeldungsdatum:
17. Februar 2008

Beiträge: 5

Moin Moin,

danke für die vielen Antworten ☺

Der Python link hat mir weitergeholfen, auch wenn der Fehler dann wo anders lag. Ich Superhirn habe nämlich dann nur im perl den Fehler gemacht dass ich geschrieben habe:

my $ks_pid = system("pgrep k..");

anstatt:

my $ks_pid = pgrep k...;

naja ich bin neu noch, ich darf das ... ☺

kann geschlossen werden.

lg

Antworten |