#!/usr/bin/perl use strict; use warnings; my $file='/tmp/test.txt'; # Datei erzeugen und mit irgendwas füllen # echo ist einfach am kürzesten :) system("echo Das ist ein test > $file"); # es gibt module, # die zuverlässig unbenutzte temporäre Dateienamen erzeugen. # für das Beispiel hier nutze ich sie nicht... # Die xdg-tools des LSB sind der portabelste Weg, # Benutzerspezifische Programme zu starten. # Editor starten system("xdg-open",$file) == 0 or die "$@"; # leider werden alle Prozesse unabhängig gestartet, # sodass xdg-open sofort zurückkehrt. # es wird also eine anderer weg benötigt, # um heraus zu finden, wann der Nutzer mit dem Editieren fertig ist. # Ein weg währe mittels "ps" abzufragen, # wer den Dateinamen als Kommandozeilenoption übergeben bekommen hat. # der Nachteil ist, dass es Möglichkeiten gibt # Kommandos an ein Programm zu übergeben, # die in der Kommandozeile nicht auftauchen. # Also schaue ich in /proc um zu sehen, # welche Programme die Datei geöffnet haben. # zusätzlich überprüfe ich die Kommandozeile, # vielleicht habe ich Glück. :) # auch das ist nicht zuverlässig, # denn das Programm könnte die Datei zwischenzeitlich schließen # ein wenig warten... select(undef,undef,undef,0.2); # herausfinden welches Programm die Datei geöffnet hat my @prgs; # /proc auflisten for my $prg (grep{m!/\d+$!}glob("/proc/*")) { # eigens Programm ausschließen next if($prg=~/$$/); # nur Programme des Benutzers sind interessant if(-o $prg) { # enthält die Kommandozeile den Dateinamen? my $cmdline=do{local(@ARGV,$/)="$prg/cmdline"; <>}; if($cmdline=~/\Q$file\E/) { my $exe = readlink("$prg/exe"); my ($pid) = $prg=~m!/(\d+)$!; push(@prgs,[$pid,$exe]); last; } # Dateinamen der geöffneten Dateien vergleichen for my $fd (map{readlink($_)}glob("$prg/fd/*")) { # Wenn die Pfade gleich sind haben wir es gefunden if($fd eq $file) { my $exe = readlink("$prg/exe"); my ($pid) = $prg=~m!/(\d+)$!; push(@prgs,[$pid,$exe]); last; } } } } # mal ausgeben wer es ist... for my $prg (@prgs) { print "Running $prg->[1] to edit $file\n"; } # darauf warten, dass das Programm beendet wird my $still_running=@prgs; while($still_running) { sleep 1; $still_running=0; for my $prg (@prgs) { $still_running++ if(-e "/proc/".$prg->[0] && readlink("/proc/".$prg->[0]."/exe") eq $prg->[1]) } } # Datei wieder einlesen my $data=do{ local(@ARGV,$/)=$file; <>; } warn "$!"; # Datei löschen unlink($file) or warn "$!"; # daten ausgeben/verarbeiten print "DATA:\n$data\n" if($data);