gpt4 book ai didi

java - 我可以在不挂起主进程的情况下从 Java 以交互模式运行 bash 吗?

转载 作者:太空狗 更新时间:2023-10-29 11:18:03 30 4
gpt4 key购买 nike

我正在构建一个使用 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 来扩展别名,但这些都没有任何影响。

最佳答案

我从来没有真正弄清楚这其中的“原因”,但我发现了一些解决方法,它们至少让我可以通过使用的 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

关于java - 我可以在不挂起主进程的情况下从 Java 以交互模式运行 bash 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34937170/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com