Question
J'essaye d'attribuer une constante en haut d'un script Perl comme ceci:
use constant {
# ...
CONSTNAME => qx{readlink -e __FILE__} || __FILE__,
# ...
};
__FILE__
n'est pas interpolé dans l'opérateur qx
, ce qui provoque son échec.Comment puis-je réaliser ce que je veux, c'est-à-dire interpoler le __FILE__
avant d'appeler readlink
du shell.
Veuillez noter: ce n'est pas une option pour stocker la commande dans une variable intermédiaire entre les deux.
La solution
Pour répondre directement à la question, vous pouvez utiliser l'idiome interpolate-arbitrary-expression-in-string décrit dans perlref :
print qx{echo @{[ __FILE__ ]}};
Quelques mises en garde soulevées dans les commentaires:
- Le
[]
fournit un contexte de liste.Cela n'a pas d'importance ici, mais cela vaut la peine d'être pris en compte en général. - Vous pouvez avoir des problèmes si
__FILE__
a des métacaractères shell.
Si votre objectif est de trouver le chemin de votre script perl avec tous les liens symboliques résolus, vous pouvez consulter le module FindBin
.FindBin
fait partie de la distribution principale de Perl depuis un certain temps (au moins depuis la version 5.004 selon http://search.cpan.org/~chips/perl5.004/ ).
Autres conseils
Une solution tout-Perl:
my $self = $0;
while( -l $self ){
$self = readlink $self;
}
use constant {
# ...
CONSTNAME => $self,
# ...
};
Utilisez readpipe
la fonction équivalente à qx//
.Interne à Perl qx//
se comporte principalement comme qq//
et transmet ensuite le résultat à readpipe
.Lorsque le comportement de citation de qx//
vous gêne, vous pouvez le contourner et appeler readpipe
directement.
use constant {
CONSTNAME => readpipe('readlink -e ' . quotemeta(__FILE__)) || __FILE__,
};
quotemeta
aidera à se prémunir contre d'éventuelles attaques de métacaractères shell dans le nom de fichier.