2017-07-02 1 views
2

Je dois exécuter une fonction dans un fichier Perl, et passer des arguments dans la fonction.Perl passer les arguments dans le fichier de Bash

# program.pm 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 
} 

my %functions = (
    go => \&go 
); 

my $function = shift; 

if (exists $functions{$function}) { 
    $functions{$function}->(); 
} else { 
    die "There is no function called $function available\n"; 
} 

Ceci doit être exécuté et transmis à bash. Je dois être en mesure de préciser les args au hasard, quelque chose comme ceci:

$ perl program.pm go foo='bar' bar='fubar'

Je suis très familier avec Perl. Je googling autour et ne peux pas pour la vie de moi comprendre comment correctement analyser ces. Il semble qu'il y ait 4 façons différentes de le faire et aucune ne semble correspondre à mon cas d'utilisation.

J'ai essayé en vain aussi bien .:

$ perl program.pm -e 'go(foo=>"bar")'

+0

double possible de [Comment puis-je analyser les arguments de ligne de commande?] (Https://stackoverflow.com/questions/3972955/how-can-i-parse-command-line-arguments) –

Répondre

1

Vous pouvez "inclure" program.pm dans votre "un liner" à l'aide require.

shell/script bash

perl -e 'require "/path/program.pm" ; &go(1=>2)' 

program.pm

sub go 
{ 
    # sample subroutine 

    # print subroutine parameters 
    print "go-params: @_\n"; 
    # convert subroutine parameters into hash 
    my %hash = @_; 
    print "go-hash-1: $hash{1}\n" 
} 
# IMPORTANT: indicate proper module initialization 
1; 
+0

Brillant, merci tellement de. – dthree

+1

Pourquoi "exigez-vous" le programme plutôt que de simplement l'exécuter? Et que fait le '&' sur l'appel du sous-programme? –

+0

@DaveCross 1) Require est supposé rendre ** beaucoup de sous-programmes ** définis dans program.pl disponibles dans le "one liner". 2) '& 'n'est pas nécessaire dans ce cas pour appeler le sous-programme' go'. C'est mon style-guide préféré. 3) Vous répondez "style meilleur et recommandé". Ma réponse est "code court" et rend possible des utilisations beaucoup plus compliquées de sous-programme défini dans programme.pm – AnFi

4

La réponse que vous avez déjà accepté semble assez compliqué. C'est possible avec seulement quelques changements à votre code existant.

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 
    print "In go\nArgs are: @_\n"; 
} 

my %functions = (
    go => \&go 
); 

my $function = shift; 

if (exists $functions{$function}) { 
    # Pass remaining command-line args to the called subroutine 
    $functions{$function}->(@ARGV); 
} else { 
    die "There is no function called $function available\n"; 
} 

J'ai mis un appel print() à go() (donc je sais qu'il est appelé) et je l'ai passé @ARGV à la sous-routine trouvée dans le tableau de répartition.

Vous pouvez simplement l'appeler comme n'importe quel autre programme Perl.

$ perl program.pm go foo=bar bar=fubar 
In go 
Args are: foo=bar bar=fubar 

$ perl program.pm XX foo bar 
There is no function called XX available 

Mise à jour: Dans un commentaire, cette exigence a été ajouté:

Mais comment je fais diviser les valeurs dans un hachage?

Il y a deux réponses à cela. Et celui que vous choisissez dépend de ce que vous essayez réellement de faire.

Si vous voulez juste prendre une « foo = bar » chaîne et analyser dans une paire de clés/valeur stockée dans un hachage, vous pouvez remplacer le sous-programme go() avec le code comme ceci:

use Data::Dumper; 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 

    my %args = map { split /=/ } @_; 

    print "In go\nArgs are: " . Dumper(\%args) . "\n"; 
} 

vous obtenez alors cette sortie:

$ perl program.pm go foo=bar bar=fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

Si vous essayez réellement d'analyser les options de ligne de commande, vous devez utiliser un analyseur d'option de ligne de commande comme GetOpt::Long.

use Data::Dumper; 
use Getopt::Long 'GetOptionsFromArray'; 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 

    my %args; 

    GetOptionsFromArray(\@_, \%args, 'foo=s', 'bar=s'); 

    print "In go\nArgs are: " . Dumper(\%args) . "\n"; 
} 

Notez que pour que cela fonctionne, vous devrez passer des options appropriées de style Unix qui commencent par --.

$ perl program.pm go --foo=bar --bar=fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

Mais cette version est beaucoup plus souple dans ses exigences d'entrée:

$ perl program.pm go --f bar --b fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

Et il vous dira si vous utilisez des noms d'options non valides.

$ perl program.pm go --fu=bar --baz=fubar 
Unknown option: fu 
Unknown option: baz 
In go 
Args are: $VAR1 = {}; 
+0

Mais comment diviser les valeurs en un hachage? – dthree

+0

Oh. Je m'excuse de ne pas repérer une exigence que vous n'avez pas pensé à mentionner dans votre question :-) –

+0

Haha désolé! J'aime mieux ton chemin, s'il y a des gens faciles à analyser. – dthree