我正在构建一个使用Java的CFML应用程序,允许用户在Linux上运行shell命令。输入的命令将使用bash
选项传递给-c
。为了使bash扩展别名,我使用-i
选项以交互模式运行。可以从CommandBox REPL测试以下行以复制行为:
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()
访问,但它也会暂停运行我的CFML引擎的主java进程并将我放到我的shell中。
[1]+ Stopped myBinary
[root@host]#
然后我必须运行fg
才能开始备份。我知道这与在交互模式下运行bash
有关,但我该如何避免这种行为?
我还尝试使用选项-O expand_aliases
或运行shopt -s expand_aliases
来扩展别名,但这些都没有任何影响。
答案 0 :(得分:1)
我从未真正弄清楚"为什么"这个,但我发现了一些工作,至少让我通过使用别名扩展的Runtime.exec()
运行用户输入的bash命令,所以我会在这里为其他人分享它们。如果有人有更好的答案,请添加它。
我发现最干净的方法是在运行命令之前将+m
选项设置为set +m;
来禁用作业控制(监控模式):
process = createObject( 'java', 'java.lang.Runtime' ).getRuntime().exec( [ 'bash','-i','-c', 'set +m; ll' ], javaCast( 'null', '' ), CWD );
唯一的缺点是与bash
一起使用,但不能与我的几个用户喜欢在Mac上使用的zsh
一起使用。
我最终做的是在命令中添加&& exit
以退出shell:
process = createObject( 'java', 'java.lang.Runtime' ).getRuntime().exec( [ 'bash','-i','-c', 'll && exit'], javaCast( 'null', '' ), CWD );
这样做并没有将整个Java进程置于后台模式,但到目前为止我发现了两个副作用:
git pull
)会在标准错误中输出文本bash: no job control in this shell
。