2012-08-07 2 views
2

i ont un script bash que je veux exécuter à partir groovy commeRun processus externe de groovy

some_shell_script.sh param1 "report_date=`some_function 0 \"%Y%m%d\"`" 

ce script fonctionne avec succès à partir de la ligne de commande, mais lorsque je tente de l'exécuter à partir Groovy

def command = "some_shell_script.sh param1 "report_date=`some_function 0 \"%Y%m%d_%H%M%S\"`"" 
def sout = new StringBuffer() 
def serr = new StringBuffer() 
//tried to use here different shells /bin/sh /bin/bash bash 
ProcessBuilder pb = new ProcessBuilder(['sh', '-c',command]) 
Process proc = pb.start() 
proc.consumeProcessOutput(sout, serr) 

def status = proc.waitFor() 

println 'sout: ' + sout 
println 'serr: ' + serr 

i ont l'erreur suivante

serr: sh: some_function: command not found 

en même temps

which some_function 

retours définition fonctionnelle comme

some_function() 
{ 
;some definition here 
} 

ressemble quand je lance script externe de Groovy il lancer le processus différent sans contexte de processus parent. Je veux dire aucune définition de fonction du processus parent existe.

Quelqu'un sait comment gérer une telle situation?

Répondre

1

Vérifiez clairement ces citations comme indiqué par @Reimeus. J'avais quelques doutes à propos de ça.

En outre, some_function() peut être défini dans ~/.bashrc, /etc/bash.bashrc ou dans un fichier provenant de l'un de ceux-ci lorsque vous exécutez bash interactivement. Cela ne se produit pas si vous exécutez un script. (ce qui est bon pour faire l'exécution de script on pouvait s'y attendre -. Vous ne pouvez pas avoir votre script dépendent de l'environnement de connexion de personnes)

Si tel est le cas, déplacer une_fonction() vers un autre fichier, et de mettre le chemin complet dans la BASH_ENV variable, de sorte que bash le récupère lors du traitement des scripts.

homme bash:

When bash is started non-interactively, to run a shell script, for 
    example, it looks for the variable BASH_ENV in the environment, expands 
    its value if it appears there, and uses the expanded value as the name 
    of a file to read and execute. Bash behaves as if the following com- 
    mand were executed: 
  if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 
but the value of the PATH variable is not used to search for the file 
    name. 
    [Manual page bash(1) line 158] 
+0

pas sûr que cela soit lié mais ** export -f some_function ** session précédente groovy résolu le problème – user1582639

+0

Cela fonctionnera pour votre environnement de connexion. Le 'export -f' force la définition de la fonction dans l'environnement du script, qui à son tour la transmet à l'instance bash créée par ProcessBuilder. * Attention *, si vous donnez le script groovy à d'autres, leur environnement peut ne pas avoir votre définition de 'some_function'. –

1

Cela semble un problème de chemin. Pouvez-vous mettre le chemin complet du script et réessayer?

+0

ressemble à cela défini dans les profils. Je ne connais pas le chemin, ce qui renvoie la définition de la fonction, mais pas le chemin – user1582639

2

Vous devez remplacer les guillemets dans votre définition de commande par des guillemets simples.

def command = 'some_shell_script.sh param1 "report_date=`some_function 0 "%Y%m%d_%H%M%S"`'

Ajouter:

println command 

pour assurer que vous exécutez la commande correcte.

Ouvrez également un nouveau shell bash et vérifiez que some_function est défini.

0

AVERTISSEMENT: il y a des limites avec cette solution, et, les commandes sous-script shell doit être correctement testé avant le déploiement. Cependant, si le multithreading n'était pas requis, , par ex. la fonction fournit immédiatement quelques résultats courts, il existe une alternative que j'ai implémenté dans here.

Par exemple, si le résultat de mycmd dépend d'une variable d'environnement définie dans ~/.bashrc je pouvais afficher son résultat: (essayé comme groovy-script/1.8.1, et oui, cela est un exemple stupide et peut être risqué!)

commands = '''source ~/.bashrc; cd ~/mytest; ./mycmd''' 
"bash".execute().with{ 
    out << commands 
    out << ';exit $?\n' 
    waitFor() 
    [ok:!exitValue(), out:in.text, err:err.text] 
}.with{ println ok?out:err } 
Questions connexes