perlrun - Comment utiliser l'interpréteur Perl |
perlrun - Comment utiliser l'interpréteur Perl
perl [ -CsTuUWX ] [ -hv ] [ -V[:configvar] ] [ -cw ] [ -d[:debugger] ] [ -D[number/list] ] [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal] ] [ -Idir ] [ -m[-]module ] [ -M[-]'module...' ] [ -P ] [ -S ] [ -x[dir] ] [ -i[extension] ] [ -e 'command' ] [ -- ] [ programfile ] [ argument ]...
La façon habituelle d'exécuter un programme Perl est de le rendre directement exécutable ou bien de passer le nom du fichier source comme argument de ligne de commande (Un environnement Perl interactif est aussi possible -- voir la page de manuel perldebug pour plus de détails sur son utilisation). Au lancement, Perl recherche votre script à un des endroits suivants:
Avec les méthodes 2 et 3, Perl démarre l'analyse du fichier d'entrée à partir du début, à moins de rajouter une option -x. Dans ce cas, il cherche la première ligne qui commence par #! et contient le mot «perl». L'interprétation commence à partir de cette ligne. C'est utile pour lancer un programme contenu dans un message plus grand (par exemple dans un courrier électronique ou un article Usenet, NDT). Dans ce genre de cas, la fin du programme doit être indiquée par __END__.
Lorsque la ligne commençant par #! est analysée, des options éventuelles sont toujours recherchées. Ainsi, si vous êtes sur une machine qui n'autorise qu'un seul argument avec la ligne #!, ou pire, ne reconnait pas la ligne #!, vous pouvez toujours obtenir un comportement homogène des options, quelque soit la manière dont Perl a été invoqué, même si -x a été utilisé pour trouver le début du programme.
Puisque historiquement certains systèmes d'exploitation arrêtaient l'interprétation de la ligne #! par le noyau à partir de 32 caractères, certaines options peuvent être passées sur la ligne de commande, d'autres pas ; vous pouvez même vous retrouver avec un «-» sans sa lettre au lieu d'une option complète, si vous n'y faites pas attention. Vous voudrez probablement vous assurer que toutes vos options tombent d'un côté ou de l'autre de la frontière des 32 caractères. La plupart des options ne se soucient pas d'être traitées de façon redondante, mais obtenir un «-» au lieu d'une option complète pourrait pousser Perl à essayer d'exécuter l'entrée standard au lieu de votre programme. Une option -I incomplète pourrait aussi donner des résultats étranges.
Certaines options sont sensibles au nombre de fois où elles sont
présentes sur la ligne de commande, par exemple, les combinaisons des
options -l et -0. Il faut soit mettre toutes les options après
la limite des 32 caractères (si possible), soit remplacer les
utilisations de -0digits par BEGIN{ $/ = "\0digits"; }
.
L'analyse des options commence dès que «perl» est mentionné sur la ligne. Les séquences «-*» et «- » sont spécialement ignorées de telle manière que vous puissiez écrire (si l'envie vous en prend), disons
#!/bin/sh -- # -*- perl -*- -p eval 'exec perl -wS $0 ${1+"$@"}' if $running_under_some_shell;
pour permettre à Perl de voir l'option -p.
Un truc similaire implique le programme env, si vous le possédez.
#!/usr/bin/env perl
Les exemples ci-dessus utilisant un chemin relatif vers l'interpréteur perl, atteignant la première version trouvée dans le chemin de l'utilisateur. Si vous voulez une version spécifique de Perl, disons, perl5.005_57, vous devez le placer directement dans le chemin de la ligne #! .
Si la ligne #! ne contient pas le mot «perl», le programme indiqué après le #! est lancé au lieu de l'interpréteur Perl. C'est assez bizarre, mais cela aide les gens qui utilisent des machines qui ne reconnnaissent pas #!, car ainsi ils peuvent indiquer à un programme que leur SHELL est /usr/bin/perl, et Perl va alors envoyer le program vers le bon interpréteur pour eux.
Après avoir localisé votre programme, Perl le compile en une forme interne. Si il y a ne serait-ce qu'un erreur de compilation, l'exécution du programme n'est pas tentée (c'est différent du script shell de base, qui peut être exécuté à moitié avant de détecter une erreur de syntaxe).
Si le programme est syntaxiquement correct, il est exécuté. Si le
programme se termine sans rencontrer un opérateur die()
ou exit(), un
exit(0)
implicite est ajouté pour indiquer une exécution réussie.
La technique #! d'Unix peut être simulée sur les autres systèmes:
extproc perl -S -vos_options
sur la première ligne de vos fichiers *.cmd
(le -S est dû à un
bug dans la manière dont cmd.exe gère `extproc').
ALTERNATIVE_SHEBANG
(«#!» se prononce She Bang,
cf. Jargon File, NDT). Pour plus d'informations à ce sujet, voir le
fichier dosish.h dans les sources de la distribution.
$ perl -mysw 'f$env("procedure")' 'p1' 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8' ! $ exit++ + ++$status != 0 and $exit = $status = undef;
au début de votre programme, où -mysw
représente toutes les options
de ligne de commande que vous voulez passer à Perl. Vous pouvez
désormais invoquer le programme directement, en disant perl
programme
, ou en tant que procédure DCL, en disant @programme
(ou
implicitement via DCL$PATH en utilisant juste le nom du programme).
Cette incantation est un peu difficile à mémoriser, bmais Perl
l'affichera pour vous si vous dites perl "-V:startperl"
.
Les interpréteurs de commandes des systèmes non-Unix ont des idées
plutôt différentes des shells Unix concernant l'isolement (quoting).
Il vous faudra apprendre quels sont les caractères spéciaux de votre
interpréteur de commande (*
, \
et "
sont courants), et
comment protéger les espaces et ces caractères pour lancer des
one-liners [Ndt] scripts sur une seule ligne [Fin de Ndt] (cf. -e
plus bas).
Sur certains systèmes, vous devrez peut-être changer les apostrophes (single-quote) en double (guillemets), ce qu'il ne faut pas faire sur les systèmes Unix ou Plan9. Vous devrez peut-être aussi changer le signe % seul en %%.
Par exemple:
# Unix perl -e 'print "Hello world\n"'
# MS-DOS, etc. perl -e "print \"Hello world\n\""
# Macintosh print "Hello world\n" (puis Run "Myscript" ou Shift-Command-R)
# VMS perl -e "print ""Hello world\n"""
Le problème, c'est qu'aucun de ces exemples n'est absolument sûr de marcher: cela dépend de la commande et il est possible qu'aucune forme ne fonctionne. Si l'interpréteur de commande était 4DOS, ceci marcherait probablement mieux :
perl -e "print <Ctrl-x>"Hello world\n<Ctrl-x>""
CMD.EXE dans Windows NT a récupéré beaucoup de fonctionnalités Unix lorsque tout le monde avait le dos tourné, mais essayez de trouver de la documentation sur ses règles d'isolement !
Sur Macintosh, cela dépend de l'environnement que vous utilisez. Le shell MacPerl, ou MPW, est très proche des shells Unix pour son support de différentes variantes d'isolement, si ce n'est qu'il utilise allègrement les caractères Macintosh non ASCII comme caractères de contrôle.
Il n'y a pas de solution générale à ces problèmes. C'est juste le foutoir.
Cela peut sembler évident, mais Perl est seulement utile quand les utilisateurs y ont facilement accès. Autant que possible, il est bon d'avoir /usr/bin/perl et /usr/local/bin/perl comme liens symboliques (symlinks) vers le bon binaire. Si cela n'est pas possible, les administrateurs systèmes sont encouragés à mettre (des symllinks vers) perl et ses utilitaires associés, dans un répertoire fréquemment présent présent dans le PATH des utilisateurs, ou encore dans un quelconque autre endroit pratique ou évident.
Dans cette documentation, #!/usr/bin/perl
dans la première ligne
d'un programme, indiquera ce qui marche sur votre système. Nous vous
conseillons d'utiliser un chemin spécifique si vous avez besoin d'une
version particulière.
#!/usr/local/bin/perl5.00554
ou si vous voulez juste utiliser une version minimale, placez une instruction telle que celle-ci au début de votre programme :
use 5.005_54;
Comme pour toutes les commandes standard, une option mono-caractère peut être combinée avec l'option suivante, le cas échéant.
#!/usr/bin/perl -spi.orig # équivalent à -s -p -i.orig
Les options comprennent:
$/
) en notation
octale. S'il n'y a pas de chiffres, le caractère nul (ASCII 0) est le
séparateur. D'autres options peuvent suivre ou précéder les
chiffres. Par exemple, si vous avez une version de find qui peut
afficher les noms de fichiers terminés par des caratères nul, vous
pouvez écrire ceci:
find . -name '*.orig' -print0 | perl -n0e unlink
La valeur spéciale 00 va indiquer à Perl d'avaler les fichiers en mode paragraphes. La valeur 0777, indique à Perl d'avaler les fichiers en entier car il n'y a pas de caractère avec cette valeur octale.
perl -ane 'print pop(@F), "\n";'
est équivalent à
while (<>) { @F = split(' '); print pop(@F), "\n"; }
Un autre séparateur [Ndt] que espace ' '[Fin Ndt] peut être spécifié avec -F.
${^WIDE_SYSTEM_CALLS}
reflète
l'état de cette option. Voir ${^WIDE_SYSTEM_CALLS} dans la page de manuel perlvar.
Cette caractéristique n'est couramment implémentée que sur la plate-forme Win32.
BEGIN
, CHECK
, et les
blocs use
, car ils sont considérés comme existants en dehors de
l'exécution de votre programme. Les blocs INIT
et END
seront
toutefois passés.
1 p Découpage en symboles et analyse 2 s Clichés de la pile 4 l Traitement des piles de contextes (Context (loop) stack processing) 8 t Exécution tracée (Trace execution) 16 o Résolution et surcharge de méthodes 32 c Conversions chaînes/nombres 64 P Affiche les commandes du pré-processeur pour -P 128 m Allocation mémoire 256 f Traitement des formats 512 r Analyse et exécution des expressions rationnelles 1024 x Affichage de l'arbre syntaxique 2048 u Vérification d'intégrité 4096 L Fuites de mémoire (nécessite -DLEAKTEST à la compilation de Perl) 8192 H Affiche les hash (usurps values()) 16384 X Allocation scratchpad 32768 D Nettoyage 65536 S Synchronisation des fils d'exécution
Tous ces drapeaux nécessitent -DDEBUGGING quand vous compilez
l'exécutable Perl. Voir le fichier INSTALL dans la distribution des
sources de Perl pour savoir comment le faire. Ce drapeau est
automatiquement rajouté si vous compilez avec l'option -g
quand
Configure
vous demande les drapeaux de votre optimiseur/débogueur.
Si vous essayez juste d'obtenir l'affichage de chaque ligne de code
Perl au fil de l'exécution, à la façon dont sh -x
le fournit pour
les scripts shell, vous ne pouvez pas utilise l'option -D de
Perl. Faites ceci à la place
# Syntaxe du Bourne shell $ PERLDB_OPTS="NonStop=1 AutoTrace=1 frame=2" perl -dS program
# Syntax csh % (setenv PERLDB_OPTS "NonStop=1 AutoTrace=1 frame=2"; perl -dS program)
Voir la page de manuel perldebug pour plus de détails et des variantes.
//
, ""
, ou ''
,
sinon il sera mis entre apostrophes.
<>
doivent
être édités en place. Cela est accompli en renommant le fichier
source, en ouvrant le fichier résultat sous le nom initial, et en
sélectionnant ce fichier de résultat comme sortie par défaut pour les
instructions print(). L'extension, le cas échéant, est utilisée pour
modifier le nom du fichier source pour faire une copie de sauvegarede,
suivant ces règles:
Si aucune extension n'est fournie, aucune sauvegarde n'est faite et le fichier source est écrasé.
Si l'extension ne contient pas d'étoile (*
), elle est ajoutée à la
fin du nom de fichier courant comme suffixe. Si l'extension contient
un ou plusieurs caractères *
, chacune des *
est remplacée par le
nom de fichier courant. En perl, on pourrait l'écrire ainsi :
($backup = $extension) =~ s/\*/$file_name/g;
Cela vous permet d'ajouter un préfixe au fichier de sauvegarde, au lieu (ou en plus) d'un suffixe:
$ perl -pi'orig_*' -e 's/bar/baz/' fileA # sauvegarde en 'orig_fileA'
Ou même de placer les sauvegardes des fichiers originaux dans un autre répertoire (à condition que ce répertoire existe déjà):
$ perl -pi'old/*.orig' -e 's/bar/baz/' fileA # sauvegarde en 'old/fileA.orig'
Ces exemples sont équivalents :
$ perl -pi -e 's/bar/baz/' fileA # écrase le fichier courant $ perl -pi '*' -e 's/bar/baz/' fileA # écrase le fichier courant
$ perl -pi '.orig' -e 's/bar/baz/' fileA # sauvegarde en 'fileA.orig' $ perl -pi '*.orig' -e 's/bar/baz/' fileA # sauvegarde en 'fileA.orig'
À partir du shell, écrire
$ perl -p -i.orig -e "s/foo/bar/; ... "
revient au même qu'utiliser le programme :
#!/usr/bin/perl -pi.orig s/foo/bar/;
qui est équivalent à
#!/usr/bin/perl $extension = '.orig'; LINE: while (<>) { if ($ARGV ne $oldargv) { if ($extension !~ /\*/) { $backup = $ARGV . $extension; } else { ($backup = $extension) =~ s/\*/$ARGV/g; } rename($ARGV, $backup); open(ARGVOUT, ">$ARGV"); select(ARGVOUT); $oldargv = $ARGV; } s/foo/bar/; } continue { print; # affiche le nom du fichier original } select(STDOUT);
si ce n'est que l'option -i ne compare pas $ARGV et $oldargv pour savoir quand le nom de fichier a changé. Cette option utilise par contre, ARGVOUT pour l'identificateur de fichier (filehandle). Notez que STDOUT est restauré comme sortie par défaut après la boucle.
Comme montré ci-dessus, Perl crée le fichier de sauvegarde même si la sortie n'est pas modifiée. C'est donc une manière amusante de copier des fichiers.
$ perl -p -i '/some/file/path/*' -e 1 file1 file2 file3... ou $ perl -p -i '.orig' -e 1 file1 file2 file3...
Vous pouvez utiliser eof
sans parenthèses pour localiser la fin de
chaque fichier d'entrée, au cas où vous voulez ajouter des choses à la
fin, ou réinitialiser le comptage des lignes (cf. exemples dans
eof dans la page de manuel perlfunc).
Si, pour un fichier donné, Perl n'est pas capable de créer de fichier de sauvegarde avec l'extension indiquée, il ne traitera pas le fichier et passera au suivant (s'il existe).
Pour une discussion des détaillée des permissions des fichiers et -i, voir Pourquoi Perl me laisse effacer des fichiers protégés en écriture ? Pourquoi -i écrit dans des fichiers protégés ? N'est-ce pas un bug de Perl ? dans la page de manuel perlfaq5
Vous ne pouvez pas utiliser -i pour créer des réperoires ou pour enlever des extensions à des fichiers.
Perl ne transforme pas les ~
en noms de fichiers, ce qui est une
bonne chose, puisque certains l'utilisent pour leurs fichiers de
sauvegarde :
$ perl -pi~ -e 's/foo/bar/' file1 file2 file3...
Enfin, l'option -i n'empêche pas l'exécution quand aucune fichier n'est donné sur la ligne de commande. Dans ce cas, aucune sauvegarde n'est faite (puisque l'original ne peut être déterminé), et le traitement se fait de STDIN vers STDOUT, comme on peut s'y attendre.
@INC
), et indiquent au pré-processeur C
où chercher les fichiers à inclure. Le pré-processeur C est appelé
avec -P; par défaut il cherche dans /usr/include et /usr/lib/perl.
$/
» (le séparateur
d'enregistrements en entrée) est automatiquement enlevé avec l'une des
options -n ou -p. Deuxièmement «$\
» (le séparateur
d'enregistrements en sortie) reçoit la valeur octnum de telle
manière que toutes les instructions print aient ce séparateur ajouté à
la fin [du print()]. Si octnum est omis, «$\
» prend la valeur de
«$/
». Par exemple, pour limiter les lignes à 80 colonnes :
perl -lpe 'substr($_, 80) = ""'
Notez que l'affectation $\ = $/
est faite quand l'option est
rencontrée, donc le séparateur en entrée peut être différent du
séparateur en sortie si l'option -l est suivie de l'option -0:
gnufind / -print0 | perl -ln0e 'print "found $_" if -p'
Cela affecte retour-chariot '\n' à $\
et ensuite affecte le
caractère nul (ascii 0) à $/
.
use
module ();
avant d'exécuter votre
programme.
-Mmodule exécute use
module ;
avant d'exécuter votre
programme. Vous pouvez utiliser des apostrophes pour ajouter du code
supplémentaire après le nom du module, par exemple, '-Mmodule
qw(toto titi)'
.
Si le premier caractère après -M ou -m est un moins (-
),
alors le 'use' est remplacé par 'no'.
Un peu de sucre syntaxique intégré permet d'écrire
-mmodule=toto,titi ou -Mmodule=toto,titi comme un raccouci de
'-Mmodule qw(toto titi)'
. Cela évite de recourir à des apostrophes
lorsqu'on importe des symboles. Le code généré par
-Mmodule=toto,titi est use module split(/,/,q{toto,titi})
. Notez
que la forme =
fait disparaître la distinction entre -m et
-M.
while (<>) { ... # votre script va là }
Notez que les lignes ne sont pas affichées par défaut. Cf. -p pour afficher les lignes traitées. Si un fichier passé en argument ne peut pas être ouvert, pour quelque raison que ce soit, Perl vous prévient, et passe au fichier suivant.
Un moyen efficcace d'effacer tous les fichiers agés de plus d'une semaine :
find . -mtime +7 -print | perl -nle unlink
C'est plus rapide que d'utiliser l'option -exec de find, car vous ne lancez plus un processus pour chaque fichier à effacer. Cela souffre du bug entraînant une mauvaise gestion des fins de lignes dans les chemins, que vous pouvez régler si vous... [phrase pas terminée dans la VO, NDT].
Les blocs BEGIN
et END
peuvent être utilisés pour prendre le
contrôle des opérations, avant ou après la boucle implicite du
programme, comme dans awk.
LINE: while (<>) { ... # votre programme va là } continue { print or die "-p destination : $!\n"; }
Si un fichier passé en argument ne peut pas être ouvert, pour quelque raison que ce soit, Perl vous prévient, et passe au fichier suivant. Notez que les lignes sont affichées automatiquement. Une erreur durant l'affichage est considérée comme fatale. Pour supprimmer les affichages, utilisez l'option -n. L'option -p prend le dessus sur -n.
Les blocs BEGIN
et END
peuvent être utilisés pour prendre le
contrôle des opérations, avant ou après la boucle implicite, comme
dans awk.
#!/usr/bin/perl -s if ($xyz) { print "$xyz\n"; }
Ceci est typiquement utilisé pour émuler le démarrage #! sur les plateformes qui ne le supportent pas. Cet exemple fonctionne sur de nombreuses plateformes ayant un shell compatible avec le Bourne shell:
#!/usr/bin/perl eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' if $running_under_some_shell;
Le système ignore la première ligne et donne le programme à /bin/sh,
qui essaye alors d'exécuter le programme Perl comme un script
shell. Le shell exécute la deuxième ligne comme une commande de shell
normale, et ainsi démarre l'interpréteur Perl. Sur certains systèmes,
$0 ne contient pas toujours le chemin complet, l'option -S dit donc
à Perl de rechercher le programme si nécessaire. Après que Perl ait
localisé le programme, il analyse les lignes et les ignore car la
variable $running_under_some_shell n'est jamais vraie. Si le programme
doit être interprété par csh, vous devrez remplacer ${1+"$@"}
par
$*
, même si cela ne comprend pas les espaces (et les autres
caractères équivalents) inclus dans la liste d'arguments. Pour
démarrer sh plutôt que csh, certains systèmes peuvent nécessiter le
remplacement de la ligne #! par une contenant juste un deux points,
qui sera poliment ignoré par Perl. D'autres systèmes ne peuvent pas
contrôler cela, et ont besoin d'une construction totalement diabolique
qui fonctionnera sous csh, sh, ou Perl, comme celle-ci :
eval '(exit $?0)' && eval 'exec perl -wS $0 ${1+"$@"}' & eval 'exec /usr/bin/perl -wS $0 $argv:q' if $running_under_some_shell;
Si le nom de fichier fourni contient des séparateurs de répertoires (i.e. si c'est un chemin absolu ou relatif), et si le fichier n'est pas trouvé, les plateformes qui ajoutent des extensions de noms de fichiers le feront et essayeront de trouver le fichier avec ces extensions ajoutées, les unes après les autres.
Sur les plateformes compatibles DOS, si le programme ne contient pas de séparateurs de répertoires, il sera d'abord recherché dans le répertoire courant avant d'être recherché dans le PATH. Sur les plateformes Unix, le programme sera recherché strictement dans le PATH.
dump()
à la place. Note:
la disponibilité de undump est spécifique à la plateforme et peut
ne pas être disponible pour un portage spécifique de Perl.
Cette option a été remplacée par le nouveau backend du compilateur générateur de code Perl. Voir B et la page de manuel B::Bytecode pour plus de détails.
$^W
) doit être utilisée en même temps que cette option
pour effectivement générer les avertissements de vérification de
souillure.
$ perl -V:man.dir
fournira des indices probants sur la valeur que devrait contenir votre variable MANPATH pour accéder à la documentation de Perl.
Cette option ne fait que valider la variable interne ^$W
. Vous
pouvez invalider certains avertissements ou les promouvoir en erreurs
fatales de façon spécifique en utilisant des hooks __WARN__
, comme
il est décrit dans la page de manuel perlvar et dans warn dans la page de manuel perlfunc. Voir aussi
la page de manuel perldiag et la page de manuel perltrap. Une nouvelle façon de gérer finement les
avertissements est aussi disponible si vous voulez en manipuler des
classes entières ; voir warnings ou perllexwarn.
no warnings
ou
de $^W
. Voir perllexwarn.
use warnings
ou de $^W
. Voir perllexwarn.
__END__
si des déchets doivent être ignorés après lui (si on le
désire, le programme peut traiter tout ou partie de ce qui le suit via
le handle de fichier DATA).
Lors d'une exécution avec vérifications de souillure (soit parce que le programme est exécuté en setuid ou setgid, soit parce que l'option -T est activée), aucune des deux variables n'est utilisée. Le script devrait dire à la place :
use lib "/my/directory";
BEGIN { require 'perl5db.pl' }
cmd.exe /x/c
sous
WindowsNT et command.com /c
sous Windows95. La valeur est
considérée comme délimitée par des espaces. Précédez tout caractère
devant être protégé (comme une espace ou une barre oblique inverse)
par une barre oblique inverse.
Notez que Perl n'utilise pas COMSPEC pour cela car COMSPEC a un haut degré de variabilité entre les utilisateurs, ce qui amène à des soucis de portabilité. De plus, perl peut utiliser un shell qui ne convienne pas à un usage interactif, et le fait de fixer COMSPEC vers un tel shell peut interférer avec le fonctionnement correct d'autres programmes (qui regardent habituellement COMSPEC pour trouver un shell permettant l'utilisation interactive).
perl -V:d_mymalloc
vaut 'define'). Si elle a une valeur, cela provoque un dump de
statistiques d'utilisation de la mémoire après l'exécution. Si sa
valeur est un entier supérieur à un, les statistiques d'utilisation de
la mémoire sont aussi dumpées après la compilation.
Perl dispose aussi de variables d'environnement qui contrôlent comment Perl manipules les données spécifiques à un langage naturel particulier. Voir la page de manuel perllocale.
À part celles-ci, Perl n'utilise pas d'autres variables d'environnement, sauf pour les rendre disponibles au programme étant exécuté, et aux processus fils. Toutefois, les programmes exécutés en setuid feraient bien d'exécuter les lignes suivantes avant de faire quoi que ce soit d'autres, ne serait-ce que pour que les gens restent honnêtes :
$ENV{PATH} = '/bin:/usr/bin'; # or whatever you need $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions, consultez http://perl.enstimac.fr/.
Loic Tortay <loict@bougon.net> Roland Trique <roland.trique@uhb.fr>
Personne pour l'instant.
perlrun - Comment utiliser l'interpréteur Perl |