【问题标题】:Can I run bash in interactive mode from Java without it suspending the main process?我可以在不暂停主进程的情况下从 Java 以交互模式运行 bash 吗?
【发布时间】:2016-04-28 11:46:15
【问题描述】:

我正在构建一个使用 Java 的 CFML 应用程序,以允许用户在 Linux 上运行 shell 命令。输入的命令通过-c 选项传递给bash。为了使 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 来扩展别名,但这些都没有任何影响。

【问题讨论】:

  • 你可以试试ProcessBuilder
  • 是的,我知道这一点,但是 Lucee CF 引擎围绕 runtime.exec 构建了一些不错的实用程序,可以同时处理捕获错误和输出流等,这非常好。我想让它按原样工作,但一直认为我只是在某个地方遗漏了一些简单的选项。
  • 我发现了一个在末尾添加“&& exit”的hack。我再等几天,如果没有人能回答,我会把它作为解决方案发布。

标签: java linux bash shell cfml


【解决方案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 一起使用,但不能与我的几个用户喜欢在他们的Mac 上使用的zsh 一起使用。

我最终做的是在命令中添加&& exit 以退出shell,如下所示:

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

【讨论】:

  • 非常好奇“为什么”的答案是什么。显然你不能/不想使用 SSH……但是为什么呢?
  • 好吧,我正在运行 CFML (Java) 应用程序的同一台机器上运行该进程。我不确定我为什么要为此使用 SSH。
  • 我不怀疑您需要使用 CFML。我只是想知道您的场景是什么,您需要允许用户通过 cfml 运行命令,而通常的做法是只为用户提供 SSH 访问权限。我完全理解您希望使用 cfml 进行此操作
  • 当然。这是用例。 CommandBox:(一个 CFML CLI、REPL 和包管理器)允许用户从交互式 shell(类似于 Gant)运行操作系统命令commandbox.ortusbooks.com/content/v/development/usage/execution/… 另外,如果你很好奇,这个实现的代码在这里:@ 987654322@
猜你喜欢
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多