如何在scala sys.process调用上获得shell扩展
考虑一个简单的shell扩展尝试: 简单/直接方法:如何在scala sys.process调用上获得shell扩展,scala,process,expansion,Scala,Process,Expansion,考虑一个简单的shell扩展尝试: 简单/直接方法: scala> ("/bin/ls /tmp/*" run BasicIO(false, sb, None)).exitValue ls: /tmp/*: No such file or directory res18: Int = 1 scala> ("bash -c \"/bin/ls /tmp/*\"" run BasicIO(false, sb, None)).exitValue /tmp/*": -c: line 0:
scala> ("/bin/ls /tmp/*" run BasicIO(false, sb, None)).exitValue
ls: /tmp/*: No such file or directory
res18: Int = 1
scala> ("bash -c \"/bin/ls /tmp/*\"" run BasicIO(false, sb, None)).exitValue
/tmp/*": -c: line 0: unexpected EOF while looking for matching `"'
/tmp/*": -c: line 1: syntax error: unexpected end of file
res19: Int = 2
scala> ("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
<console>:1: error: ';' expected but ')' found.
("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
我已经尝试了ProcessIO、BasicIO、Process等多种组合,但不知道如何让shell扩展工作
bash-c:
scala> ("/bin/ls /tmp/*" run BasicIO(false, sb, None)).exitValue
ls: /tmp/*: No such file or directory
res18: Int = 1
scala> ("bash -c \"/bin/ls /tmp/*\"" run BasicIO(false, sb, None)).exitValue
/tmp/*": -c: line 0: unexpected EOF while looking for matching `"'
/tmp/*": -c: line 1: syntax error: unexpected end of file
res19: Int = 2
scala> ("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
<console>:1: error: ';' expected but ')' found.
("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
管道到bash-s:
scala> ("/bin/ls /tmp/*" run BasicIO(false, sb, None)).exitValue
ls: /tmp/*: No such file or directory
res18: Int = 1
scala> ("bash -c \"/bin/ls /tmp/*\"" run BasicIO(false, sb, None)).exitValue
/tmp/*": -c: line 0: unexpected EOF while looking for matching `"'
/tmp/*": -c: line 1: syntax error: unexpected end of file
res19: Int = 2
scala> ("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
<console>:1: error: ';' expected but ')' found.
("echo \"/bin/ls /tmp/*\" | bash -s") run BasicIO(false, sb, None)).exitValue
理解wrt scala进程类也会对Shell转义感兴趣:一个同时包含扩展和转义的示例是最佳的
更新我找到了这个JIRA-可能与此相关。我希望不是-这意味着这里描述的功能几乎没有希望
sys.process.\uu在它可以接受的内容方面限制太多,无法使用
另一次更新我发现了一封旧邮件,其中涉及尊敬的丹尼尔·索布拉尔,他提到:
因为引号没有分隔传递给bash的参数--
是Scala决定了争论的破裂方式,这很简单
在空格上拆分,没有任何报价工具。如果你试一下
相反,它将发挥以下作用:
Seq(“bash”、“-c”、“ls*.scala”)
对于运行shell命令的“开火并忘记”版本来说,情况看起来更加严峻。我渴望红宝石
%x{whatever shell string you want goes here}
e、 g
echo“打印%x{ls-lrtad/etc/*2>&1}”ruby
最令人满意的回报是:
-r--r--r-- 1 root wheel 69836 May 28 2013 /etc/php.ini.default-
5.2-previous~orig
lrwxr-xr-x 1 root wheel 30 Oct 22 2013 /etc/localtime -> /usr/share/zoneinfo/US/Pacific
-rw-r--r-- 1 root wheel 102 Nov 5 2013 /etc/hostconfig
-rw-r--r-- 1 root wheel 1286 Nov 5 2013 /etc/my.cnf
-rw-r--r-- 1 root wheel 4161 Dec 18 2013 /etc/sshd_config~previous
-rw-r--r-- 1 root wheel 199 Feb 7 2014 /etc/shells
-rw-r--r-- 1 root wheel 0 Sep 9 2014 /etc/xtab
-rw-r--r-- 1 root wheel 1316 Sep 9 2014 /etc/ttys
.. etc
但看起来Scala没有出现这种情况。我担心你误解了我的答案。Ruby也在做同样的事情,我不看他们的代码就知道这一点,因为Java(以及Scala)作为API提供的是Unix API的直接翻译 是shell进行了shell扩展,尽管任何其他软件都完全有可能模仿它们,但这将是一场失败的游戏。通常会提供通配符,但它们只是shell扩展的一小部分 我的答案有你需要的一切,但让我进一步说明:
import scala.sys.process._
implicit class RubyX(val sc: StringContext) extends AnyVal {
def x(args: Any*): ProcessBuilder = {
val strings = sc.parts.iterator
val expressions = args.iterator
var buf = new StringBuffer(strings.next)
while(strings.hasNext) {
buf append expressions.next
buf append strings.next
}
Process(Seq("bash", "-c", buf.toString))
}
}
那你就可以了
x"ls *.scala".!
我返回了一个ProcessBuilder,因此您可以选择适合您的最佳执行形式,例如
上面的代码>返回退出代码,并将所有其他内容回显到stdout。哦,我认为现在重要的一点是,我们只需要三个部分来完成流程(.)调用。考虑到整个命令行是三个部分中的一个,这很好。是的,我错误地收集到命令行的每一部分都需要是流程调用的不同成员。这里仍然缺少一些东西:scala>Process(Seq(“bash”、“-C”、“ls/tmp/*”)。!!bash:ls/tmp/*:没有此类文件或directory@javadba小写-c
.ah man。。但愿你早点注意到这一点。刚刚花了两个小时尝试将java.lang.Process代码(以及相关的流读取器/写入器)转换为scala。但这很好——而且简单得多。所以最后一切都好。。