Forum Programmation.perl Problème avec exec() en Perl/Gtk

Posté par  (site web personnel) .
Étiquettes : aucune
0
8
sept.
2005
Bonjour :)

Voilà : j'adore le système des Alias sous bash. Le problème c'est que lorsque je tape un alias, qui va lui-même lancer un ou plusieurs programmes, la console est inutilisable tant que l'application lancée n'est pas fermée.

Il est possible d'intégrer le lanceur de programme (Alt+F2) dans ma barre d'outils (je suis sous xfce mais je crois qu'on peut faire pareil sous gnome ou kde), malheuresement ce lanceur de programme ne gère pas les alias (ce qui est normal puisqu'il ne passe pas par bash).

Donc ce que je voudrais, c'est un petit lanceur de programme qui passe par bash pour exécuter la commande que je lui transmet. Voilà une première version minimaliste :


#!/usr/bin/perl -w

use strict;

# Include
use Gtk2 '-init';

# Boolean management
use constant TRUE => 1 ;
use constant FALSE => 0 ;

# Main Window
my $window = Gtk2::Window->new( 'toplevel' );
$window->set_border_width(15);
$window->set_title( 'XeAm' );
$window->signal_connect( 'delete_event', \&close_windows );
$window->signal_connect( 'destroy' , \&destroy_window ) ;

# A text entry
my $entry = Gtk2::Entry->new;
$entry->signal_connect( 'activate', \&enter_callback, $entry );
$entry->select_region( 0, length( $entry->get_text() ) );
$window->add( $entry );
$entry->show();

$window->show();

Gtk2->main ;



### Subroutines

sub enter_callback
{
my ( $widget, $entry ) = @_;
my $command = $entry->get_text();
exec "bash -i -c $command";
}
sub close_windows
{
return FALSE;
}
sub destroy_window
{
Gtk2->main_quit;
return FALSE;
}


ça marche, mais dés que j'écris un alias et que je tape sur "entrer", le programme correspondant ce lance et mon petit programme en Perl se ferme aussitôt! Pourquoi se ferme-t-il ? Je voudrais qu'il reste ouvert en permanance et qu'il soit toujours prêt à recevoir une commande. Comment faire ?

Merci pour votre aide :)
  • # ne pas utiliser exec

    Posté par  . Évalué à 2.

    qui selon la documentation ( http://perldoc.perl.org/functions/exec.html(...) ), je cite :

    The exec function executes a system command and never returns-- use system instead of exec if you want it to return.

    en fait exec termine ton programme perl et lance à la place celui que tu veux. Il est préférable dans ton cas d'utiliser « system »
    • [^] # Re: ne pas utiliser exec

      Posté par  (site web personnel) . Évalué à 1.

      Merci Gart :)

      Effectivement mon prog ne se ferme plus, mais ça ne résout que le moitié du problème : lorsque je lance un programme, je suis obligé de le fermer pour pouvoir en lancer un autre. Comme si j'utilisait bash. Et c'est justement ce que je veux éviter.

      Une idée ?
      • [^] # Re: ne pas utiliser exec

        Posté par  (site web personnel) . Évalué à 1.

        Vire le '-i' de la commande bash
        • [^] # Re: ne pas utiliser exec

          Posté par  (site web personnel) . Évalué à 1.

          Bon alors si je supprime le "-i" le programme ne support plus les alias (puisque le bash invoqué n'est plus interactif) et je suis toujours obligé de fermer l'application que j'ai lancé afin de pouvoir me resservir de mon programme (qui s'appel xeam, histoire de lui donner un nom, ça simplifira les choses).
          Merci quand même...
  • # execve & fork

    Posté par  (site web personnel) . Évalué à 2.

    exec() en perl n'est qu'un front end vers l'appel systeme execve .

    exec/execv/execl/execle/execv/execvp sont aussi des front end sur execve ( dispo dans unistd.h )


    execve() permet de remplacer le processus courant par un autre processus en le chargeant depuis le disque.

    execve() ne sert a rien tout seul sauf si l'on veut un systeme monotache.

    l'interet de execve() vient avec fork() qui permet de dupliquer le processus courant.

    ... comme quoi, les bases programmation sous systeme UNIX ne sont pas connu de tous les developpeurs developpant sous UNIX.
    • [^] # Re: execve & fork

      Posté par  (site web personnel) . Évalué à 1.

      J'ai lu la documentation de fork() et les exemples fournis, mais bon... j'utilise linux depuis moins d'un an et je débute en perl, donc j'ai pas tout compris ^^

      Quelqun a un exemple concret ?
      • [^] # Re: execve & fork

        Posté par  (site web personnel) . Évalué à 2.

        il s'agit de programmation UNIX , donc un minimum de connaissance du monde UNIX est necessaire. il y a des tres bons bouquins à ce sujet chez nos amis les libraires.

        si tu souhaites faire un simple lanceur de processus, il suffit de faire un :
        exec($program) unless fork() ou $program contient le chemin complet vers le programme a executer. system( $program ) peut te remplacer avantageusement le bout de code precedent dans bien des cas.

        si tu souhaites communiquer avec ce programme, il vaut mieux se tourner vers le popen() perl connu sous open( my $handle, "-|", $program ) ou open( my $handle, "|-", $program ); . bien entendu tu as aussi, `$program` qui permet de recuperer tout ce que retourne l'execution de $program .

        de toute facon, la lecture de perldoc perlicp apres la lecture d'un bouquin de programmation unix te fera le plus grand bien.
        • [^] # Re: execve & fork

          Posté par  (site web personnel) . Évalué à 1.

          Merci beaucoup ! C'est exactement ce dont j'avais besoin.

          Arf... Il me reste une semaine une semaine avant la rentré pour apprendre la programmation unix... J'essairai ^^
        • [^] # Re: execve & fork

          Posté par  . Évalué à 1.

          « il suffit de faire un :
          exec($program) unless fork() »


          Ça fonctionne mieux avec while: En remplaçant
          exec "bash -i -c $command";
          par
          exec "bash -i -c $command" while fork();
  • # Meuh

    Posté par  (site web personnel) . Évalué à 2.

    Il est possible d'intégrer le lanceur de programme (Alt+F2) dans ma barre d'outils (je suis sous xfce mais je crois qu'on peut faire pareil sous gnome ou kde), malheuresement ce lanceur de programme ne gère pas les alias (ce qui est normal puisqu'il ne passe pas par bash).

    Pourquoi ne pas alors utiliser ton lanceur de programme avec bash devant ? Par exemple « bash -i monalias » au lieu de « monalias » ?
  • # ma méthode à moi...

    Posté par  . Évalué à 1.

    pour lancer une commande sous bash et récupérer la main dans la console, je fais comme ça :

    monalias &


    avec des redirections des stdout et stderr si besoin.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.