如何通过java的ProcessBuilder将参数传递给pkill,通过ssh传递?

时间:2017-03-29 14:56:22

标签: java ssh processbuilder

我正在尝试使用ProcessBuilder通过java接口远程杀死进程。我的代码如下所示:

ProcessBuilder builder = new ProcessBuilder( 
  "ssh", 
  "user@host", 
  "pkill -f \"'instanceId XXXXXX'\"");
Process process = builder.start();

其中instanceId XXXXX与启动进程时的某些命令行参数匹配。

当我获得最后的命令字符串时,使用

builder.command()

它返回

ssh user@host pkill -f "'instanceId XXXXX'"

当在命令行上手动运行时。不幸的是,当由ProcessBuilder运行时,它无法识别目标进程。

在过去几周花了太多时间与争论ssh / ProcessBuilder的争论,有人可以解释它为什么这样做,也许可以指出一些不相关的文档完全神秘吗?

1 个答案:

答案 0 :(得分:1)

问题在于双引号。

在命令行上运行命令时,shell将解释双引号或单引号本身。因此,如果你运行

ssh user@host pkill -f 'instanceId XXXXX'
从命令行

(或双引号相同),它将删除这些引号。虽然本地shell将字符串instanceID XXXX视为单个参数,但远程 shell将命令视为一个整体,没有看到任何引号,因此看到" INSTANCEID"和" XXXXX"作为两个独立的实体。

因此,从命令行运行时,需要在引号上添加引号。本地shell将剥离外部引号,ssh将使用内部引号传递命令,这将导致远程shell将instanceID XXXX视为单个参数。

但是,当您从流程构建器运行时,您不能从本地shell运行。您自己构建了适当的参数,然后将它们字面上发送到ssh。因此,当您发送"'InstanceID XXXX'"时,远程shell将看到的是"'InstanceID XXXX'"。它只会删除一对,并且'InstanceID XXXX'不在远程计算机上的任何进程命令行中。不是那些引用......

因此,当您使用流程构建器时,不应该在直接在shell中运行时引用相同的引用方式。只需要一对。