Вопрос

i have a bash script which i want to execute from groovy like

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

that script runs successfully from the command line, but when i try to execute it from 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 have the following error

serr: sh: some_function: command not found

at the same time

which some_function

returns functional definition like

some_function ()
{
;some definition here
}

looks like when i run external script from groovy it start different process without context of parent process. I mean no function definitions of parent process are exists.

Anyone have cue how to cope with such a situation?

Это было полезно?

Решение

Definitely check out those quotes as indicated by @Reimeus. I had some doubts about those.

In addition, some_function() may be defined in ~/.bashrc, /etc/bash.bashrc or in a file sourced by either of those when you run bash interactively. This does not happen if you run a script. (Which is good for making script run predictably - you can't have your script depend on people's login environment.)

If this is the case, move some_function() to another file, and put its full path in the BASH_ENV variable, so that bash picks it up when processing scripts.

man 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]

Другие советы

You should replace the double quotes in your command definition with single quotes.

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

Add:

println command 

to ensure that you are executing the correct command.

Also open a new bash shell and ensure that some_function is defined.

This seems a path problem. Can you put the full path to the script and try again?

DISCLAIMER: there are limitations with this solution, and, the shell sub-script commands should be properly tested before deployment. However if multithreading were not required e.g. the function provides immediately some short results, there is an alternative as I implemented in here.

For instance, if the result of mycmd depends on an environment variable set in ~/.bashrc I could display its result: (tried as a groovy-script/v1.8.1, and yes, this is a stupid example and it might be risky!)

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 }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top