我有一个bash脚本,我想从groovy执行
some_shell_script.sh param1 "report_date=`some_function 0 \"%Y%m%d\"`"
该脚本从命令行成功运行,但是当我尝试从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
我有以下错误
serr: sh: some_function: command not found
同时
which some_function
返回功能定义,如
some_function ()
{
;some definition here
}
看起来当我从groovy运行外部脚本时,它启动不同的进程而没有父进程的上下文。我的意思是不存在父进程的函数定义。
任何人都有提示如何应对这种情况?
答案 0 :(得分:2)
您应该使用单引号替换命令定义中的双引号。
def command = 'some_shell_script.sh param1 "report_date=`some_function 0 "%Y%m%d_%H%M%S"`'
添加:
println command
确保您正在执行正确的命令。
同时打开一个新的bash shell并确保定义some_function
。
答案 1 :(得分:1)
这似乎是一个路径问题。你能把完整的路径放到脚本上再试一次吗?
答案 2 :(得分:1)
绝对查看@Reimeus指示的引号。我对这些产生了一些疑问。
此外,some_function()
可以在~/.bashrc
,/etc/bash.bashrc
中定义,也可以在以交互方式运行bash时由其中任何一个来源的文件中定义。如果您运行脚本,则不会发生这种情况。
(这对于使脚本可预测地运行是有好处的 - 您不能让脚本依赖于人们的登录环境。)
如果是这种情况,请将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]
答案 3 :(得分:0)
免责声明: 此解决方案存在限制,和应在部署之前正确测试shell子脚本命令。但是,如果不需要多线程例如,函数会立即提供一些简短的结果,我可以在here中实现。
例如,如果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 }