【问题标题】:Execute a bash command string verbatim (including expansion and escaping)逐字执行 bash 命令字符串(包括扩展和转义)
【发布时间】:2015-05-30 08:02:28
【问题描述】:

我正在寻找如何将字符串逐字提交给外部 bash。 Bash 应该处理通配符扩展和转义。

使用流程库进行测试:

import sys.process._

将所需的流程 DSL 隐式导入范围。

让我们尝试 escaping 测试:这是在 bash shell 上运行所需的结果:

$echo -ne 'abc\t\n' | tr '\t' 'T'
abcT
$

让我们在 sys.process 中试试:

scala> "echo -ne 'abc\t\n' | tr '\t' 'T'" !!
warning: there were 1 feature warning(s); re-run with -feature for details
res16: String =
"-ne 'abc ' | tr ' ' 'T'
"

失败 ..与命令行完全不同..

现在让我们尝试一个扩展测试(OS/X 风格):

scala> "open /shared/adm*" !!
warning: there were 1 feature warning(s); re-run with -feature for details
The file /shared/adm* does not exist.
java.lang.RuntimeException: Nonzero exit value: 1
    at scala.sys.package$.error(package.scala:27)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.slurp(ProcessBuilderImpl.scala:131)
    at scala.sys.process.ProcessBuilderImpl$AbstractBuilder.$bang$bang(ProcessBuilderImpl.scala:101)

失败..这里没有进行通配符扩展。

所以..我应该求助于旧的 java Process 方式 - 即执行“bash -c”然后发送整个命令行?

【问题讨论】:

  • 您要求 bash 实现的功能,例如管道和通配符,因此请通过 bash 运行它们!请参阅scala-lang.org/api/2.11.5/… 以获得一些启示。
  • @DavidWeber 该页面没有解决扩展或转义问题——而且我已经知道所描述的管道和通配符支持。

标签: bash scala process


【解决方案1】:

注意:运行外部命令(sedcatls 等)与运行在 bash 中的命令(例如 cd| 和通配符。使用process 包不允许您从字符串运行bash 命令。

这是我在 Scala (2.10) 中实现你想要的东西的尝试。第一种方法仅使用process 包提供的方法。第二种方法是间接调用bash 来运行整个命令。

import sys.process._

val f = (Seq("echo", "-n", "abc\t\n") #| "tr '\\t' 'T'").!!.trim
println(f)

val g = Seq("/bin/sh", "-c", "echo 'abc\t\n' | tr '\t' 'T'").!!.trim
println(g)

【讨论】:

  • 我希望避免使进程调用复杂化:上面的方法可以工作,但失去了“创建命令字符串并启动”的便利性
  • 我同意它可能不如直接从 bash 运行它那么短,但我觉得它比使用 Java Process 更短且更简洁。
猜你喜欢
  • 2020-09-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 2013-11-16
  • 2015-11-08
相关资源
最近更新 更多