简体   繁体   English

从Groovy运行外部流程

[英]Run external process from groovy

i have a bash script which i want to execute from groovy like 我有一个bash脚本,我想从groovy执行

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 该脚本从命令行成功运行,但是当我尝试从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. 看起来当我从groovy运行外部脚本时,它启动了没有父进程上下文的其他进程。 I mean no function definitions of parent process are exists. 我的意思是不存在父进程的函数定义。

Anyone have cue how to cope with such a situation? 有人提示如何应对这种情况吗?

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. 还要打开一个新的bash shell并确保定义了some_function

This seems a path problem. 这似乎是路径问题。 Can you put the full path to the script and try again? 您可以将完整路径放在脚本中,然后重试吗?

Definitely check out those quotes as indicated by @Reimeus. 一定要按@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. 另外,当您以交互方式运行bash时, some_function()可以在~/.bashrc~/.bashrc /etc/bash.bashrc或任何一个源文件中定义。 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. 如果是这种情况,请将some_function()移至另一个文件,并将其完整路径放入BASH_ENV变量中,以便bash在处理脚本时将其拾取。

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]

DISCLAIMER: there are limitations with this solution, and, the shell sub-script commands should be properly tested before deployment. 免责声明: 解决方案有局限性, 并且应该在部署之前正确测试shell子脚本命令。 However if multithreading were not required eg 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!) 例如 ,如果mycmd的结果取决于~/.bashrc设置的环境变量,我可以显示其结果:(尝试作为groovy-script / v1.8.1,是的,这是一个愚蠢的示例,可能有风险!)

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM