我坐在这里,至少从一开始就解决了一个让我很沮丧的问题!
我正在编写一个简单而小型的java程序,该程序可以轻松地将任何命令传递到(linux)屏幕会话。
Shell command: bash -c "screen -p 0 -S sessionname -X eval 'stuff "some command" 15'"
当我在命令shell中输入这个时,一切都很好!但如果我让Java程序来做这件事,什么都不会发生!甚至没有消息、错误或提示!什么都没有!我让程序回显生成的屏幕命令,如果我得到输出并将其粘贴到shell中,它就可以工作了。
这是我的Java代码:
static public void screenCmd() throws IOException
{
String command = "bash -c "screen -p 0 -S screenname -X eval 'stuff \"cmd\"\015'"";
System.out.println("debug: '" + command + "'"); //output would work
//when copy and paste it to the shell
InputStreamReader isr = new InputStreamReader(
Runtime.getRuntime().exec(command).getInputStream()
);
//for debug output
BufferedReader br = new BufferedReader(isr);
String line = "";
while ((line = br.readLine()) != null)
System.out.println(line);
}
最有趣的是,所有其他shell命令都在工作。我试着用Java来执行tail,whomi,cp,ls。。。没有任何问题。为什么不屏蔽?
Java程序由启动屏幕会话的同一用户启动。
如果有人有什么小想法,请报告!我在这里开车疯了!
p.s.:屏幕会话还运行一个java程序!(这可能是问题的一部分吗?)
谢谢。
我建议您尝试更现代的ProcessBuilder
类。
阅读这些:
- 五个常见的java.lang.Process陷阱
- 当Runtime.exec()不会
- 从Runtime.exec()到ProcessBuilder
真正的问题是命令行的解析方式:Java的Runtime.exec没有遵循与Bash相同的引用规则。您应该使用API的数组版本:
String[] command = {"bash", "-c",
"screen -p 0 -S screenname -X eval 'stuff \"cmd\"\015'"};
Runtime.getRuntime().exec(command);
如果你直接执行屏幕而不经过bash:,你可以减少一些引用混乱
String[] command = {"screen", "-p", "0",
"-S", "10624.pts-2.koivu", "-X", "eval", "stuff "cmd"\015"};