2009-04-06 9 views
6

supposons que vous avez un script perl « de foobar.pl » qui imprime ce qui suit à stdoutexécuter la sortie d'un script comme une commande bash autonome

date -R 

et que vous voulez exécuter quoi que les sorties de script Perl en tant commande standhone bash (ne vous inquiétez pas des problèmes de sécurité car ceux-ci s'exécutent dans un environnement sécurisé).

Comment obtenez-vous que bash reconnaisse cela comme une commande autonome?

J'ai essayé d'utiliser xargs, mais cela semble vouloir passer arguments seulement à une commande prédéfinie.

Je veux que le script Perl soit capable de générer n'importe quelle commande arbitraire.

$command = 'date -R' 
system($command); ## in the perl script 

le dessus ne fonctionne pas parce que je veux qu'il fonctionne dans un environnement Cygwin existant ...

foobar.pl | xargs bash -i {} 

le précède ne fonctionne pas parce que bash semble être en cours d'exécution d'un nouveau processus et donc la l'initialisation et les paramètres de bash_profile ne sont pas instanciés.

Répondre

4

Bad:

`perl foo.pl` 
$(perl foo.pl) 

Pourquoi est-ce mauvais? En raison de tant de raisons; notamment:

  • Wordsplitting: Qu'est-ce que vous faites ici est de prendre la sortie du script perl, diviser en morceaux où il y a des espaces, des onglets ou des sauts de ligne, et en prenant ces morceaux comme arguments au premier morceau qui est la commande à exécuter. Dans des cas vraiment extrêmement simplistes comme $(echo 'date +%s') cela pourrait fonctionner; mais c'est juste une très mauvaise représentation de ce que vous faites VRAIMENT ici.
  • Vous ne pouvez pas faire de guillemets ou utiliser d'autres fonctionnalités du shell bash comme l'expansion des paramètres, les mots-clés bash, etc.

Bon, mais peu pratique:

perl foo.pl > mytmpfile; bash mytmpfile 

Création d'un fichier temporaire pour mettre la sortie de votre script perl dans et en cours d'exécution que bash fonctionne, mais il est peu pratique que vous devez créer (et propre up!) votre fichier temporaire et l'avoir dans un emplacement portable en écriture (et sécurisé!).

N'oubliez pas non plus d'utiliser . ou source pour exécuter le fichier temporaire, sauf si vous avez vraiment l'intention de tout exécuter dans le shell actif. En outre, lorsque vous utilisez . ou source, vous ne pourrez pas nettoyer votre fichier temporaire de manière fiable par la suite.

Probablement la meilleure solution:

perl foo.pl | bash 

Ceci est assez sûr tous azimuts (« sûr » dans le contexte de, moins sujettes aux bugs) en supposant que vos sorties de script perl syntaxe bash correcte, bien sûr .

Alternatives qui ne peu près la même chose:

bash < <(perl foo.pl) 
bash <(perl foo.pl) 
+0

bash <($ OUTPUT) est ce que je cherchais. Cela fait une énorme différence avec la tuyauterie puisque vous en avez toujours le contrôle - pour les entrées. – yclian

3

Essayez:

foobar.pl | bash 
+0

export FOO = 'foobar.pl '; $ FOO – ojblass

0

Je ne pense pas que ce soit exactement ce que vous cherchez, mais ce que j'ai :-)

perl foo.pl > /tmp/$$.script; bash /tmp/$$.script; rm /tmp/$$.script 

Bonne chance!

5
`foobar.pl` 
+0

+1 pour plus de simplicité. :) –

4

Compte tenu du fichier perl:

print "date"; 

la commande bash suivante fera.

> $(perl qq.pl) 
Mon Apr 6 11:02:07 WAST 2009 

Mais cela est exécuté dans un shell séparé. Si vous voulez vraiment l'invoquer dans le cadre de l'enveloppe actuelle , faites ceci:

$ perl qq.pl >/tmp/qq.$$ ; . /tmp/qq.$$ ; rm -f /tmp/qq.$$ 
Mon Apr 6 11:04:59 WAST 2009 
+0

Dans le cas $(), la commande "perl qq.pl" est exécutée dans un shell séparé, mais la commande retournée par elle, "date", est exécutée dans le shell actuel, qui est, je pense, ce que il voulait. –

+0

Vous ne devriez pas utiliser '.' ou' source' pour exécuter les commandes. Vous ne savez jamais ce que le script va faire à votre shell en cours d'exécution; ce qui signifie que vous ne pouvez pas compter sur le fait que vous aurez même la chance de faire votre nettoyage de fichier temporaire correctement. Mettre le nettoyage dans un piège sur EXIT pourrait aider avec cela. – lhunath

+0

@lhunath, n'avez-vous pas lu la question? Quoth le corbeau "ne vous inquiétez pas des problèmes de sécurité car cela fonctionne dans un environnement de confiance". J'ai pris cela pour signifier que la sortie du script Perl était contrôlée. Et l'utilisation de "." était spécifiquement pour répondre à l'exigence, il ne démarre pas un nouveau processus. – paxdiablo

0

Essayez avec open ($ fh, "- |", arg1 $, arg2 $)

Questions connexes