逐字执行一个bash命令字符串(包括扩展和转义)

Execute a bash command string verbatim (including expansion and escaping)

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

使用进程库进行测试:

import sys.process._

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

让我们尝试一个 转义 测试:这是 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)

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

那么 .. 我应该采用旧的 java 处理方式 - 即执行 "bash -c" 然后发送整个命令行吗?

注意:运行使用外部命令(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)