我正在尝试使用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的争论,有人可以解释它为什么这样做,也许可以指出一些不相关的文档完全神秘吗?
答案 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中运行时引用相同的引用方式。只需要一对。