2016-01-22 39 views
3

我正在构建一个使用Java来允许用户在Linux上运行shell命令的CFML应用程序。输入的命令通过-c选项传递给bash。要使bash扩展别名,我使用-i选项以交互模式运行。以下行可以从CommandBox REPL进行测试,以重复的行为:我可以在没有挂起主进程的情况下以Java的交互模式运行bash吗?

CWD = createObject('java', 'java.io.File').init('/my/working/dir') 
process = createObject('java', 'java.lang.Runtime').getRuntime().exec(['bash','-i','-c','ll'], javaCast('null', ''), CWD) 

此执行和ll命令的输出可以经由process.getInputStream()被访问,但是它也中止主java程序,我的CFML发动机是跑进去,把我扔在我的外壳里。

[1]+ Stopped     myBinary 
[[email protected]]# 

然后我必须运行fg开始备份。我知道这与在交互模式下运行bash有关,但是如何避免此行为?

我也尝试通过使用选项-O expand_aliases或运行shopt -s expand_aliases来扩展别名,但这两者都没有任何影响。

+0

你可以试试['ProcessBuilder'](https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html)。 –

+0

是的,我意识到这一点,但卢西CF引擎有一些不错的实用程序围绕runtime.exec构建,它处理并发捕获错误和输出流等,这真是太好了。我想让它按原样运行,但请始终认为我只是在某处丢失了一些简单的选项。 –

+0

我发现一个黑客添加“&&退出”到最后。我会再提供几天,如果没有人能回答,我会将其作为解决方案发布。 –

回答

1

我从来没有真正弄清楚这个“为什么”,但我发现了一些解决方法,至少让我通过使用别名扩展的Runtime.exec()运行用户输入的bash命令,所以我会在这里分享它们为他人。如果有人有更好的答案,请添加它。

我发现的最彻底的方法是用set +m;运行命令之前设置+m选项来禁用作业控制(监控模式):

process = createObject('java', 'java.lang.Runtime').getRuntime().exec([ 'bash','-i','-c', 'set +m; ll' ], javaCast('null', ''), CWD); 

唯一的缺点是,与bash工作,但没” t与zsh工作,我的几个用户喜欢在他们的Mac上使用。

我最终什么事做了添加&& exit的命令退出,像这样的外壳:

process = createObject('java', 'java.lang.Runtime').getRuntime().exec([ 'bash','-i','-c', 'll && exit'], javaCast('null', ''), CWD); 

这跑,而无需把整个Java进程进入后台模式,但我发现两个侧面影响至今:

  1. “exit”一词被附加到标准错误。
  2. 某些命令如git pull输出标准错误文本bash: no job control in this shell
+0

非常好奇,“为什么”的答案是。显然你不能/不想使用SSH ......但为什么? –

+0

那么,我正在运行CFML(Java)应用程序运行的同一台机器上的进程。我不知道为什么我想使用SSH。 –

+0

我不怀疑你需要使用CFML。我只是想知道你的场景是什么,你需要允许用户通过cfml运行命令,而通常情况下只需要给用户SSH访问。 我完全理解你对cfml的这种想法我只是好奇它的用途,因为它可能对未来有用。 –

相关问题